我想制作一个应用程序,列出 DLL 中所有导出和导入的函数。
我已经通过使用ImageDirectoryEntryToData
功能完成了导出部分:
type
TDLLExportCallback = function (const name: String; ordinal: Integer;
address: Pointer): Boolean of Object;
Function ListDLLExports( const filename : String ; callback : TDLLExportCallback ;Var ErrMsg : String) : Boolean;
Var
imageinfo: LoadedImage;
pExportDirectory: PImageExportDirectory;
dirsize: Cardinal;
Begin { ListDLLExports }
Result :=False ;
Assert( Assigned( callback )); // assert(expression) --> raise an exception if expr is eval to false;
If not FileExists( filename ) Then
Begin
ErrMsg := Format(eDLLnotFound, [filename]);
Result := False;
Exit;
End;
If MapAndLoad( PChar( filename ), nil, @imageinfo, true, true ) Then
try
pExportDirectory := ImageDirectoryEntryToData(imageinfo.MappedAddress, False,
IMAGE_DIRECTORY_ENTRY_EXPORT, dirsize );
If pExportDirectory = Nil Then
begin
ErrMsg := SysErrorMessage(GetLastError);
Result := False;
Exit;
end
Else
EnumExports( pExportDirectory^, imageinfo, callback );
finally
UnMapAndLoad( @imageinfo );
end
Else
Begin
ErrMsg := SysErrorMessage(GetLastError);
Result := False;
Exit;
//RaiseLastWin32Error;
End;
End; { ListDLLExports }
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;
base : Pointer;
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 }
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( rva : DWORD ; const Image : LoadedImage ) : PChar ;
Begin { RVAToPchar }
Result := RVAToPointer( rva, image );
End; { RVAToPchar }
最后我使用了以下回调函数:
Function TFrmDLLViewer.MyImportCallBack(const Name : String ; Ord1 : Integer ; Addr1 : Pointer) : Boolean;
Begin
Result := False;
Form1.Memo1.Lines.Add(Name + ' ' + IntToStr(Ord1) + '=' +a ) ;
Result := True;
end;
此导出目录代码有效。
我想知道如何适当地修改它以获取导入目录表。
提前致谢 。