Текущий архив: 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.49 MB
Время: 0.008 c