精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>Windows API函数>>显示DLL可导出的函数

主题:显示DLL可导出的函数
发信人: cn_prince(欢喜王子)
整理人: teleme(2001-06-27 14:52:11), 站内信件
// 为了测试,你需要在Form上放置一个TButton、TOpenDialog和TListView构件
  
  // 完整的DLLTools单元的代码在示例代码之后
  
  uses DLLTools; 
  
  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; 
  
  procedure TForm1.Button1Click(Sender: TObject); 
  begin 
    if opendialog.execute then 
    begin 
      listview.items.clear; 
      ListDLLExports( opendialog.filename, listexport ); 
    end; 
  end; 
  
  
  ***** 
  DLLTOOLS 单元
  ***** 
  
  
  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. 




----
prince 

[关闭][返回]