Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

фунции ДЛЛ

23 views
Skip to first unread message

Sergey Gluhov

unread,
Jun 16, 2002, 1:39:38 AM6/16/02
to
Hello всем.

Как получить программным путем список всех экспортируемых ДЛЛ функицй ?

ЗЫ Очень надо....

Sergey

Dmitriy Prokopenko

unread,
Jun 17, 2002, 6:13:27 AM6/17/02
to
> Как получить программным путем список всех экспортируемых ДЛЛ функицй ?
Прочитать таблицу экспорта DLL. Ее формат описан в MSDN.


Sergey Gluhov

unread,
Jun 17, 2002, 9:12:10 AM6/17/02
to

>> Как получить программным путем список всех экспортируемых ДЛЛ
>> функицй ?
DP> Прочитать таблицу экспорта DLL. Ее формат описан в MSDN.
если бы у меня это дело было бы, не спрашивал бы.

Valery

unread,
Jun 18, 2002, 11:19:43 PM6/18/02
to
> Как получить программным путем список всех экспортируемых ДЛЛ функицй ?

Программным вроде никак. Пусть опровергнут меня специалисты по WinAPI.
Если ты просто хочешь проверить наличие функции в DLL, используй:

if GetProcAddress(hModule, 'FunctionName') = INVALID_HANDLE_VALUE then
функции нет;

Если все же ты хочешь получить _список экспортируемых функций_,
то тогда тебе надо открывать DLL-ку, анализировать ее в зависимости от
типа файла (PE, NE, LE) и выкусывать список функций. Если это
ОЧЕНЬ надо, могу опубликовать алгоритм...


--
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Anthony Brajnikoff

unread,
Jun 18, 2002, 11:52:08 PM6/18/02
to
17.06.2002 23:41:21
Sergey Gluhov <Sergey...@p33.f111.n5024.z2.fidonet.org> сообщил(а) в конференцию:

>Hello всем.
>
>Как получить программным путем список всех экспортируемых ДЛЛ функицй ?
tdump /?

Leonid Troyanovsky

unread,
Jun 18, 2002, 11:47:08 PM6/18/02
to
Приветствую, Sergey.

Mon Jun 17 2002 17:12, Sergey Gluhov wrote to Dmitriy Prokopenko:

SG> Как получить программным путем список всех экспортируемых ДЛЛ функицй ?


DP> Прочитать таблицу экспорта DLL. Ее формат описан в MSDN.

> если бы у меня это дело было бы, не спрашивал бы.

----------------------------------------------------------
От:Peter Below (TeamB) (10011...@compuXXserve.com)
Заголовок:Re: How to extract exported function names from .DLL
Группы новостей:borland.public.delphi.objectpascal
Число:2000/01/09

unit DLLTools;

interface

Uses Windows, Classes, Sysutils, imagehlp ;

type
TDLLExportCallback = function (const name: String; ordinal: Integer;
address: Pointer): Boolean of Object;
{ Note: address is a RVA here, not a usable virtual address! }
DLLToolsError = Class( Exception );

Procedure ListDLLExports( const filename: String; callback:
TDLLExportCallback );
Procedure DumpExportDirectory( Const ExportDirectory: TImageExportDirectory;
lines: TStrings; const Image: LoadedImage );
Function RVAToPchar( rva: DWORD; const Image: LoadedImage ): PChar;
Function RVAToPointer( rva: DWORD; const Image: LoadedImage ): Pointer;

implementation

resourcestring
eDLLNotFound =
'ListDLLExports: DLL %s does not exist!';

{+----------------------------------------------------------------------
| Procedure EnumExports
|
| Parameters :
| ExportDirectory: IMAGE_EXPORT_DIRECTORY record to enumerate
| image : LOADED_IMAGE record for the DLL the export directory belongs
| to.
| callback : callback function to hand the found exports to, must not be
Nil
| Description:
| The export directory of a PE image contains three RVAs that point at
tables
| which describe the exported functions. The first is an array of RVAs
that
| refer to the exported function names, these we translate to PChars to
| get the exported name. The second array is an array of Word that
contains
| the export ordinal for the matching entry in the names array. The
ordinal
| is biased, that is we have to add the ExportDirectory.Base value to it
to
| get the actual export ordinal. The biased ordinal serves as index for
the
| third array, which is an array of RVAs that give the position of the
| function code in the image. We don't translate these RVAs since the DLL
| is not relocated since we load it via MapAndLoad. The function array is
| usually much larger than the names array, since the ordinals for the
| exported functions do not have to be in sequence, there can be (and
| frequently are) gaps in the sequence, for which the matching entries in
the
| function RVA array are garbage.
| Error Conditions: none
| Created: 9.1.2000 by P. Below
+----------------------------------------------------------------------}
Procedure EnumExports( const ExportDirectory : TImageExportDirectory ;
const image : LoadedImage ;
callback : TDLLExportCallback ) ;
Type
TDWordArray = Array [0..$FFFFF] of DWORD;
Var
i: Cardinal;
pNameRVAs, pFunctionRVas: ^TDWordArray;
pOrdinals: ^TWordArray;
name: String;
address: Pointer;
ordinal: Word;
Begin { EnumExports }
pNameRVAs :=
RVAToPointer( DWORD(ExportDirectory.AddressOfNames), image );
pFunctionRVAs :=
RVAToPointer( DWORD(ExportDirectory.AddressOfFunctions), image );
pOrdinals :=
RVAToPointer( DWORD(ExportDirectory.AddressOfNameOrdinals), image );
For i:= 0 to Pred( ExportDirectory.NumberOfNames ) Do Begin
name := RVAToPChar( pNameRVAs^[i], image );
ordinal := pOrdinals^[i];
address := Pointer( pFunctionRVAs^[ ordinal ] );
If not callback( name, ordinal+ExportDirectory.Base, address ) Then
Exit;
End; { For }
End; { EnumExports }

{+----------------------------------------------------------------------
| Procedure ListDLLExports
|
| Parameters :
| filename : full pathname of DLL to examine
| callback : callback to hand the found exports to, must not be Nil
| Description:
| Loads the passed DLL using the LoadImage function, finds the exported
| names table and reads it. Each found entry is handed to the callback
| for further processing, until no more entries remain or the callback
| returns false. Note that the address passed to the callback for a
exported
| function is an RVA, so not identical to the address the function would
| have in a properly loaded and relocated DLL!
| Error Conditions:
| Exceptions are raised if
| - the passed DLL does not exist or could not be loaded
| - no callback was passed (only if assertions are on)
| - an API function failed
| Created: 9.1.2000 by P. Below
+----------------------------------------------------------------------}
Procedure ListDLLExports( const filename : String ; callback :
TDLLExportCallback ) ;
Var
imageinfo: LoadedImage;
pExportDirectory: PImageExportDirectory;
dirsize: Cardinal;
Begin { ListDLLExports }
Assert( Assigned( callback ));
If not FileExists( filename ) Then
raise DLLToolsError.CreateFmt( eDLLnotFound, [filename] );

If MapAndLoad( PChar( filename ), nil, @imageinfo, true, true ) Then
try
pExportDirectory :=
ImageDirectoryEntryToData(
imageinfo.MappedAddress, false,
IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize );

If pExportDirectory = Nil Then
RaiseLastWin32Error
Else
EnumExports( pExportDirectory^, imageinfo, callback );
finally
UnMapAndLoad( @imageinfo );
end
Else
RaiseLastWin32Error;
End; { ListDLLExports }

{+----------------------------------------------------------------------
| Procedure DumpExportDirectory
|
| Parameters :
| ExportDirectory: a IMAGE_EXPORT_DIRECTORY record
| lines : a TStrings descendend to put the info into, must not be Nil
| Description:
| Dumps the fields of the passed structure to the passed strings
descendent
| as strings.
| Error Conditions:
| will raise an exception if lines is Nil and assertions are enabled.
| Created: 9.1.2000 by P. Below
+----------------------------------------------------------------------}
Procedure DumpExportDirectory( Const ExportDirectory : TImageExportDirectory;
lines : TStrings; const Image: LoadedImage ) ;
Begin { DumpExportDirectory }
Assert( Assigned( lines ));

lines.add( 'Dump of IMAGE_EXPORT_DIRECTORY' );
lines.add( format('Characteristics: %d',
[ExportDirectory.Characteristics]));
lines.add( format('TimeDateStamp: %d',
[ExportDirectory.TimeDateStamp]));
lines.add( format('Version: %d.%d',
[ExportDirectory.MajorVersion,
ExportDirectory.MinorVersion]));
lines.add( format('Name (RVA): %x',
[ExportDirectory.Name]));
lines.add( format('Name (translated): %s',
[RVAToPchar( ExportDirectory.name, Image )]));
lines.add( format('Base: %d',
[ExportDirectory.Base]));
lines.add( format('NumberOfFunctions: %d',
[ExportDirectory.NumberOfFunctions]));
lines.add( format('NumberOfNames: %d',
[ExportDirectory.NumberOfNames]));
lines.add( format('AddressOfFunctions (RVA): %p',
[Pointer(ExportDirectory.AddressOfFunctions)]));
lines.add( format('AddressOfNames (RVA): %p',
[Pointer(ExportDirectory.AddressOfNames)]));
lines.add( format('AddressOfNameOrdinals (RVA): %p',
[Pointer(ExportDirectory.AddressOfNameOrdinals)]));
End; { DumpExportDirectory }

{+----------------------------------------------------------------------
| Function RVAToPointer
|
| Parameters :
| rva : a relative virtual address to translate
| Image : LOADED_IMAGE structure for the image the RVA relates to
| Returns : translated address
| Description:
| Uses the ImageRVAToVA function to translate the RVA to a virtual
| address.
| Error Conditions:
| Will raise an exception if the translation failed
| Created: 9.1.2000 by P. Below
+----------------------------------------------------------------------}
Function RVAToPointer( rva : DWORD ; const Image : LoadedImage ) : Pointer;
var
pDummy: PImageSectionHeader;
Begin { RVAToPchar }
pDummy := nil;
Result :=
ImageRvaToVa( Image.FileHeader, Image.MappedAddress, rva,
pDummy );
If Result = Nil Then
RaiseLastWin32Error;
End; { RVAToPointer }

{+----------------------------------------------------------------------
| Function RVAToPchar
|
| Parameters :
| rva : a relative virtual address to translate
| Image : LOADED_IMAGE structure for the image the RVA relates to
| Returns : translated address
| Description:
| Uses the RVAToPointer function to translate the RVA to a virtual
| address. Note that we do not check that the address does indeed point
| to a zero-terminated string!
| Error Conditions:
| Will raise an exception if the translation failed
| Created: 9.1.2000 by P. Below
+----------------------------------------------------------------------}
Function RVAToPchar( rva : DWORD ; const Image : LoadedImage ) : PChar ;
Begin { RVAToPchar }
Result := RVAToPointer( rva, image );
End; { RVAToPchar }

end {DLLTools}.

The ListDLLExports function is used like this:

Drop a TListview and a button on a new form, name the listview 'Listview',
set its viewstyle to vsReport, add three columns to it. Drop a TOpenDialog on
the form, name it 'OpenDialog', set its Filter property to show DLLs, its
InitialDir to your Windows\system directory. Add a OnClick handler for the
button, modify unit as follows, compile and run, click on button, select a
DLL.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;

type
TDLLExportCallback = function (const name: String; ordinal: Integer;
address: Pointer): Boolean of Object;
TForm1 = class(TForm)
ListView: TListView;
Button1: TButton;
OpenDialog: TOpenDialog;
procedure Button1Click(Sender: TObject);
private
function ListExport(const name: String; ordinal: Integer;
address: Pointer): Boolean;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses DLLTools;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
If opendialog.execute then begin
listview.items.clear;
ListDLLExports( opendialog.filename, listexport );
end;
end;

function tform1.ListExport( const name: String; ordinal: Integer; address:
Pointer ): Boolean;
var
listentry: TLIstItem;
begin
Result := true;
listentry:= listview.Items.Add;
listentry.Caption := Format('%p',[address] );
listentry.Subitems.Add( format('%d',[ordinal] ));
listentry.Subitems.Add( name );
end;

end.

Peter Below (TeamB) 10011...@compuserve.com)
-------------------------------------------------------------

С уважением, LVT

Valery

unread,
Jun 19, 2002, 2:37:15 AM6/19/02
to
> SG> Как получить программным путем список всех экспортируемых ДЛЛ функицй
?
> От:Peter Below (TeamB) (10011...@compuXXserve.com)
> Заголовок:Re: How to extract exported function names from .DLL

skip skip skip skip skip

> Peter Below (TeamB) 10011...@compuserve.com)
> -------------------------------------------------------------
>
> С уважением, LVT
>


Все хорошо, но попробуйте так загрузить не PE, а NE или LE файл.
Ну любой файл из каталога C:\WINDOWS\SYSTEM
Или скажем тот же C:\WINDOWS\SYSTEM32\avicap.dll

Энта штука рассчитана только на PE-файлы !
Осторожнее!

Sergey Gluhov

unread,
Jun 20, 2002, 3:48:25 AM6/20/02
to
Hello Valery.

V> From: "Valery" <val...@png.ws.lukoil.com>

V> Программным вроде никак. Пусть опровергнут меня специалисты по WinAPI.
V> Если ты просто хочешь проверить наличие функции в DLL, используй:

V> if GetProcAddress(hModule, 'FunctionName') = INVALID_HANDLE_VALUE then
V> функции нет;

что-то не пашет.........
Sergey

Andrew Ryazanov

unread,
Jun 20, 2002, 7:31:36 AM6/20/02
to
"Sergey Gluhov" <Sergey...@p33.f111.n5024.z2.fidonet.org>
сообщил/сообщила в новостях следующее:
news:10245...@p33.f111.n5024.z2.ftn...

> V> if GetProcAddress(hModule, 'FunctionName') = INVALID_HANDLE_VALUE then
> V> функции нет;
> что-то не пашет.........
Естетсвенно,в хелп то лень заглянуть и выяснить что надо писать так
If GetProcAddress(...)=NIL then ...

Stas Malinovski

unread,
Jun 21, 2002, 12:49:46 AM6/21/02
to
Hi Sergey!

V>> Пpогpаммным вpоде никак. Пyсть опpовеpгнyт меня специалисты по
V>> WinAPI. Если ты пpосто хочешь пpовеpить наличие фyнкции в DLL,
V>> использyй:

V>> if GetProcAddress(hModule, 'FunctionName') = INVALID_HANDLE_VALUE

V>> then фyнкции нет;

SG> что-то не пашет.........

Конечно не пашет. Hадо
if GetProcAddress(hModule, 'FunctionName') = nil then...

Bye Sergey!

Igor Nikolaev

unread,
Jun 21, 2002, 12:02:28 PM6/21/02
to
//Hi Sergey, //

on *17.06.02* *17:12:10* you wrote in the area *RU.DELPHI*
a message to *Dmitriy Prokopenko*

>>> Как получить программным путем список всех экспортируемых ДЛЛ функицй ?
DP>> Прочитать таблицу экспорта DLL. Ее формат описан в MSDN.

SG> если бы у меня это дело было бы, не спрашивал бы.
Возьми любой Pe-Editor посмотри Import и Export.
PE-Editor есть также в DeDe

Best regards,
Igor U. Nikolaev
Managing Director - FST Software
ad...@fstsoft.com
http://www.fstsoft.com

Dmitriy Prokopenko

unread,
Jun 24, 2002, 6:31:23 AM6/24/02
to
> Все хорошо, но попробуйте так загрузить не PE, а NE или LE файл.
> Ну любой файл из каталога C:\WINDOWS\SYSTEM
> Или скажем тот же C:\WINDOWS\SYSTEM32\avicap.dll
> Энта штука рассчитана только на PE-файлы !
> Осторожнее!
NE и LE файлы к Win32-приложениям не подключаются. Или мы говорим о Win16?
Тогда это нужно специально оговаривать.


0 new messages