Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.13;
Скачать: CL | DM;

Вниз

Как получить список процедур из DLL?   Найти похожие ветки 

 
Viking   (2003-08-08 10:43) [0]

Господа! У меня возник такой вопрос.
Для динамического вызова DLL ипользуем примерно следующий код:
---------------------------------
{Пытаемся загрузить библиотеку}
LibHandle := LoadLibrary("MYDLL.DLL");
{Если все OK}
if LibHandle >= 32 then begin
{...то пытаемся получить адрес функции в библиотеке}
@MyProc := GetProcAddress(LibHandle,"MyProc");
{Если и здесь все OK}
if @MyProc <> nil then
( LibHandle) Господа! У меня возник такой вопрос.
Для динамического вызова DLL ипользуем примерно следующий код:
---------------------------------
{Пытаемся загрузить библиотеку}
LibHandle := LoadLibrary("MYDLL.DLL");
{Если все OK}
if LibHandle >= 32 then begin
{...то пытаемся получить адрес функции в библиотеке}
@MyProc := GetProcAddress(LibHandle,"MyProc");
{Если и здесь все OK}
if @MyProc <> nil then
{...то вызываем эту функцию и показываем результат}
end;
{И не забываем освободить память и выгрузить DLL}
FreeLibrary(LibHandle);
--------------------------------
Так вот, если имя процедуры неизвестно ("MyProc"), то как можно
во время исполнения программы получить список процедур из DLL?
Как, например, это делает программа TDUMP из поставки Delphi.

--------------------------------
Turbo Dump Version 5.0.16.6 Copyright (c) 1988, 1999 Inprise Corporation
Display of File MYDLL.DLL

EXPORT ord:0001="MyProc"
--------------------------------

Заранее спасибо!


 
AlexRush ©   (2003-08-08 10:51) [1]

Ну не так прямо просто. Это работа с PEформатом. Погодь немного - примерчик накатаю.


 
MBo ©   (2003-08-08 11:25) [2]

http://delphibase.endimus.com/?action=viewfunc&topic=filedll&id=10062


 
AlexRush ©   (2003-08-08 12:03) [3]

2MBo © (08.08.03 11:25) - ну и что я, зря старался ?? :)))


unit PE;

interface
USES windows;
type
PBYTE = ^byte;

PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
IMAGE_SECTION_HEADER_ARRAY = packed array of IMAGE_SECTION_HEADER;
PIMAGE_SECTION_HEADER_ARRAY = ^IMAGE_SECTION_HEADER_ARRAY;
PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;
//-------------------------------------------------
IMAGE_IMPORT_DESCRIPTOR = packed record
OriginalFirstThunk :DWORD;
TimeDateStump :DWORD;
ForwardChain :DWORD;
Name :DWORD;
FirstThunk :DWORD;
end;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
//-------------------------------------------------
IMAGE_IMPORT_BY_NAME = packed record
Hint :WORD;
Name :char;
end;
PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
//-------------------------------------------------
IMAGE_THUNK_DWORD = packed record
case integer of
0:(dwThunk :DWORD);
1:(w_Ord :WORD);
2:(pImportByName :PIMAGE_IMPORT_BY_NAME);
end;
PIMAGE_THUNK_DWORD = ^IMAGE_THUNK_DWORD;
//-------------------------------------------------
IMAGE_BASE_RELOCATION = packed record
VirtualAddress :DWORD;
SizeOfBlock :DWORD;
end;
PIMAGE_BASE_RELOCATION = ^IMAGE_BASE_RELOCATION;
//-------------------------------------------------
CONST
IMAGE_REL_BASED_ABSOLUTE = 0;
IMAGE_REL_BASED_HIGHLOW = 3;
IMAGE_REL_TYPE_MASK = WORD($F000);
IMAGE_REL_OFFSET_MASK = WORD($0FFF);

function ReadFile(hFile: THandle;
pBuffer:pointer;
nNumberOfBytesToRead: DWORD;
lpNumberOfBytesRead: PDWORD;
lpOverlapped: POverlapped): BOOL; stdcall; external "kernel32.dll" name "ReadFile";

function WriteFile(hFile: THandle;
pBuffer:pointer;
nNumberOfBytesToWrite: DWORD;
lpNumberOfBytesWritten: PDWORD;
lpOverlapped: POverlapped): BOOL; stdcall;external "kernel32.dll" name "WriteFile";


function mkptr(ptrBase:DWORD;addValue:DWORD):pointer;overload;assembler;
function mkptr(ptrBase:pointer;addValue:DWORD):pointer;overload;assembler;

implementation

function mkptr(ptrBase:DWORD;addValue:DWORD):pointer;overload;assembler;
asm
add ( ptrBase:pointer;addValue:DWORD)
2MBo © (08.08.03 11:25) - ну и что я, зря старался ?? :)))


unit PE;

interface
USES windows;
type
PBYTE = ^byte;

PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
IMAGE_SECTION_HEADER_ARRAY = packed array of IMAGE_SECTION_HEADER;
PIMAGE_SECTION_HEADER_ARRAY = ^IMAGE_SECTION_HEADER_ARRAY;
PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;
//-------------------------------------------------
IMAGE_IMPORT_DESCRIPTOR = packed record
OriginalFirstThunk :DWORD;
TimeDateStump :DWORD;
ForwardChain :DWORD;
Name :DWORD;
FirstThunk :DWORD;
end;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;
//-------------------------------------------------
IMAGE_IMPORT_BY_NAME = packed record
Hint :WORD;
Name :char;
end;
PIMAGE_IMPORT_BY_NAME = ^IMAGE_IMPORT_BY_NAME;
//-------------------------------------------------
IMAGE_THUNK_DWORD = packed record
case integer of
0:(dwThunk :DWORD);
1:(w_Ord :WORD);
2:(pImportByName :PIMAGE_IMPORT_BY_NAME);
end;
PIMAGE_THUNK_DWORD = ^IMAGE_THUNK_DWORD;
//-------------------------------------------------
IMAGE_BASE_RELOCATION = packed record
VirtualAddress :DWORD;
SizeOfBlock :DWORD;
end;
PIMAGE_BASE_RELOCATION = ^IMAGE_BASE_RELOCATION;
//-------------------------------------------------
CONST
IMAGE_REL_BASED_ABSOLUTE = 0;
IMAGE_REL_BASED_HIGHLOW = 3;
IMAGE_REL_TYPE_MASK = WORD($F000);
IMAGE_REL_OFFSET_MASK = WORD($0FFF);

function ReadFile(hFile: THandle;
pBuffer:pointer;
nNumberOfBytesToRead: DWORD;
lpNumberOfBytesRead: PDWORD;
lpOverlapped: POverlapped): BOOL; stdcall; external "kernel32.dll" name "ReadFile";

function WriteFile(hFile: THandle;
pBuffer:pointer;
nNumberOfBytesToWrite: DWORD;
lpNumberOfBytesWritten: PDWORD;
lpOverlapped: POverlapped): BOOL; stdcall;external "kernel32.dll" name "WriteFile";


function mkptr(ptrBase:DWORD;addValue:DWORD):pointer;overload;assembler;
function mkptr(ptrBase:pointer;addValue:DWORD):pointer;overload;assembler;

implementation

function mkptr(ptrBase:DWORD;addValue:DWORD):pointer;overload;assembler;
asm
add eax,edx
ret
end;


function mkptr(ptrBase:pointer;addValue:DWORD):pointer;overload;assembler;
asm
add eax,edx
ret
end;

end.


 
AlexRush ©   (2003-08-08 12:04) [4]

unit U_ModExportList;

interface

USES Windows,
PE;

TYPE _PROCSTRUCT = record
ProcName :string;
ProcRVA :DWORD;
ProcORD :DWORD;
end;

TfnProcCallback = function(const procStruct:_PROCSTRUCT):boolean;

function GetModuleExportList(const hModule:DWORD;fnCallback:TfnProcCallback):DWORD;

implementation

function GetModuleExportList(const hModule:DWORD;fnCallback:TfnProcCallback):DWORD;
var ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSections :PIMAGE_SECTION_HEADER;
ptrDataDir :PIMAGE_DATA_DIRECTORY;
ptrExport :PIMAGE_EXPORT_DIRECTORY;
pFunctions :PDWORD;
pNames :PDWORD;
pOrdinals :PWORD;
pStr :PChar;
i,j,L,fi :integer;
stProc:_PROCSTRUCT;
begin
result:=0;

if not assigned(fnCallback)
then exit;

ptrMZ:=pointer(hModule);
if IsBadReadPtr(ptrMZ,sizeof(PIMAGE_DOS_HEADER))
then exit;

if ptrMZ.e_magic<>IMAGE_DOS_SIGNATURE
then exit;

ptrPE:=mkptr(ptrMZ,ptrMZ._lfanew);
if IsBadReadPtr(ptrMZ,sizeof(IMAGE_NT_SIGNATURE))
then exit;

if ptrPE.Signature<>IMAGE_NT_SIGNATURE
then exit;

if ptrPE.OptionalHeader.DataDirectory[0].VirtualAddress=0
then exit;
ptrExport:=mkptr(ptrMZ,ptrPE.OptionalHeader.DataDirectory[0].VirtualAddress);
if IsBadReadPtr(ptrExport,sizeof(PIMAGE_EXPORT_DIRECTORY)+4)
then exit;

pFunctions:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfFunctions));

for i:=0 to ptrExport.NumberOfFunctions-1
do begin
stProc.ProcORD:=(ptrExport.Base+i);

pNames:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfNames));
pOrdinals:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfNameOrdinals));

// name search
for j:=0 to ptrExport.NumberOfNames-1
do begin
fi:=PWORD(mkptr(pOrdinals,j*sizeof(WORD)))^;

if ((pOrdinals^=(i+ptrExport.Base))
and (pOrdinals^>0))
then begin
pNames:=mkptr(pNames,j*4);
pStr:=mkptr(ptrMZ,pNames^);
L:=lstrlen(pStr);
if L>0
then begin
SetLength(stProc.ProcName,L+2);
lstrcpy(@stProc.ProcName[1],pStr);
end
else stProc.ProcName:="";
break;
end
else inc(pOrdinals);

stProc.ProcRVA:=pFunctions^;
end;
//--------------
if not fnCallback(stProc)
then exit;
( pFunctions) unit U_ModExportList;

interface

USES Windows,
PE;

TYPE _PROCSTRUCT = record
ProcName :string;
ProcRVA :DWORD;
ProcORD :DWORD;
end;

TfnProcCallback = function(const procStruct:_PROCSTRUCT):boolean;

function GetModuleExportList(const hModule:DWORD;fnCallback:TfnProcCallback):DWORD;

implementation

function GetModuleExportList(const hModule:DWORD;fnCallback:TfnProcCallback):DWORD;
var ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSections :PIMAGE_SECTION_HEADER;
ptrDataDir :PIMAGE_DATA_DIRECTORY;
ptrExport :PIMAGE_EXPORT_DIRECTORY;
pFunctions :PDWORD;
pNames :PDWORD;
pOrdinals :PWORD;
pStr :PChar;
i,j,L,fi :integer;
stProc:_PROCSTRUCT;
begin
result:=0;

if not assigned(fnCallback)
then exit;

ptrMZ:=pointer(hModule);
if IsBadReadPtr(ptrMZ,sizeof(PIMAGE_DOS_HEADER))
then exit;

if ptrMZ.e_magic<>IMAGE_DOS_SIGNATURE
then exit;

ptrPE:=mkptr(ptrMZ,ptrMZ._lfanew);
if IsBadReadPtr(ptrMZ,sizeof(IMAGE_NT_SIGNATURE))
then exit;

if ptrPE.Signature<>IMAGE_NT_SIGNATURE
then exit;

if ptrPE.OptionalHeader.DataDirectory[0].VirtualAddress=0
then exit;
ptrExport:=mkptr(ptrMZ,ptrPE.OptionalHeader.DataDirectory[0].VirtualAddress);
if IsBadReadPtr(ptrExport,sizeof(PIMAGE_EXPORT_DIRECTORY)+4)
then exit;

pFunctions:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfFunctions));

for i:=0 to ptrExport.NumberOfFunctions-1
do begin
stProc.ProcORD:=(ptrExport.Base+i);

pNames:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfNames));
pOrdinals:=mkptr(ptrMZ,DWORD(ptrExport.AddressOfNameOrdinals));

// name search
for j:=0 to ptrExport.NumberOfNames-1
do begin
fi:=PWORD(mkptr(pOrdinals,j*sizeof(WORD)))^;

if ((pOrdinals^=(i+ptrExport.Base))
and (pOrdinals^>0))
then begin
pNames:=mkptr(pNames,j*4);
pStr:=mkptr(ptrMZ,pNames^);
L:=lstrlen(pStr);
if L>0
then begin
SetLength(stProc.ProcName,L+2);
lstrcpy(@stProc.ProcName[1],pStr);
end
else stProc.ProcName:="";
break;
end
else inc(pOrdinals);

stProc.ProcRVA:=pFunctions^;
end;
//--------------
if not fnCallback(stProc)
then exit;
inc(pFunctions);
end;
end;

end.


 
AlexRush ©   (2003-08-08 12:06) [5]

Пример использования:

unit U_frmProcRTL;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,PE,U_ModExportList, StdCtrls;

type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
( const procStruct:_PROCSTRUCT)
Пример использования:

unit U_frmProcRTL;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,PE,U_ModExportList, StdCtrls;

type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

function fnCallBack(const procStruct:_PROCSTRUCT):boolean;
begin
Form1.Memo1.Lines.Add(IntToStr(procStruct.ProcRVA)+" "+procStruct.ProcName);
result:=true;
end;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.BeginUpdate;
GetModuleExportList(GetModuleHandle("kernel32.dll"#0),fnCallBack);
Memo1.Lines.EndUpdate;
end;

end.


 
Игорь Шевченко ©   (2003-08-08 12:33) [6]

Это все конечно хорошо, но как по списку определить, какую процедуру надо вызывать ? :))))))))


 
AlexRush ©   (2003-08-08 12:39) [7]

2Игорь Шевченко © (08.08.03 12:33) Random() :)))))



Страницы: 1 вся ветка

Текущий архив: 2003.10.13;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.015 c
14-40621
Ihor Osov'yak
2003-09-24 21:38
2003.10.13
Умей говорить с подчиненными !


1-40386
OlegM
2003-10-01 09:59
2003.10.13
Можно ли заблокировать колесико мыши?


14-40589
Khloo!
2003-09-25 15:09
2003.10.13
VBA - Visual Basic for Applicationl


14-40605
Mystic
2003-09-25 18:51
2003.10.13
Статьи Каспарова


1-40349
Guzz
2003-09-30 19:04
2003.10.13
Сочетания клавиш