2

エクスポートおよびインポートされたすべての関数を DLL にリストするアプリケーションを作成したいと考えています。

ImageDirectoryEntryToDatafunctionを使用して、エクスポートされた部分を実行しました。

 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;

エクスポート ディレクトリのこのコードは動作します。

インポートディレクトリテーブルを取得するために適切に変更する方法を知りたいです。

前もって感謝します 。

4

1 に答える 1