【问题标题】:How to get all the exported functions in a DLL?如何在 DLL 中获取所有导出的函数?
【发布时间】:2015-08-10 10:33:51
【问题描述】:

如何以编程方式从 DLL 中获取所有导出的函数?我正在尝试比较两个 DLL 的导出函数。

【问题讨论】:

  • @DavidHeffernan 当然以编程方式。
  • 如果您需要在控制台中执行此操作:tdump.exe YourDLL.DLL,然后在WinMerge 或任何其他文本比较工具中进行比较
  • 您可以查看 GExperts PE-Information Expert 中的代码,该代码显示所有标头以及 dll 的导入和导出。

标签: delphi delphi-xe7


【解决方案1】:

这是我使用的代码:

uses
  System.Classes, Winapi.Windows;

type
  PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
  PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;

function ImageNtHeader(Base: Pointer): PIMAGE_NT_HEADERS; stdcall; external 'dbghelp.dll';
function ImageRvaToVa(NtHeaders: Pointer; Base: Pointer; Rva: ULONG; LastRvaSection: Pointer): Pointer; stdcall; external 'dbghelp.dll';

procedure EnumerateImageExportedFunctionNames(const ImageName: string; NamesList: TStrings);
var
  i: Integer;
  FileHandle: THandle;
  ImageHandle: THandle;
  ImagePointer: Pointer;
  Header: PIMAGE_NT_HEADERS;
  ExportTable: PIMAGE_EXPORT_DIRECTORY;
  NamesPointer: Pointer;
  NamesPtr: PCardinal;
  NamePtr: PAnsiChar;
begin
  //NOTE: our policy in this procedure is to exit upon any failure and return and empty list

  NamesList.Clear;

  FileHandle := CreateFile(
    PChar(ImageName),
    GENERIC_READ,
    FILE_SHARE_READ,
    nil,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0
  );
  if FileHandle=INVALID_HANDLE_VALUE then begin
    exit;
  end;
  Try
    ImageHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
    if ImageHandle=0 then begin
      exit;
    end;
    Try
      ImagePointer := MapViewOfFile(ImageHandle, FILE_MAP_READ, 0, 0, 0);
      if not Assigned(ImagePointer) then begin
        exit;
      end;

      Try
        Header := ImageNtHeader(ImagePointer);
        if not Assigned(Header) then begin
          exit;
        end;
        if Header.Signature<>$00004550 then begin // "PE\0\0" as a DWORD.
          exit;
        end;

        ExportTable := ImageRvaToVa(Header, ImagePointer, Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
        if not Assigned(ExportTable) then begin
          exit;
        end;

        NamesPtr := ImageRvaToVa(Header, ImagePointer, Cardinal(ExportTable.AddressOfNames), nil);
        if not Assigned(NamesPtr) then begin
          exit;
        end;

        for i := 0 to ExportTable.NumberOfNames-1 do begin
          NamePtr := ImageRvaToVa(Header, ImagePointer, NamesPtr^, nil);
          if not Assigned(NamePtr) then begin
            exit;
          end;

          NamesList.Add(NamePtr);
          inc(NamesPtr);
        end;
      Finally
        UnmapViewOfFile(ImagePointer); // Ignore error as there is not much we could do.
      End;
    Finally
      CloseHandle(ImageHandle);
    End;
  Finally
    CloseHandle(FileHandle);
  End;
end;

【讨论】:

    【解决方案2】:

    我来这里是为了找到一种方法来列出包含在 ocx(基本上是一个 dll)中的所有函数。这里的所有信息都没有给我我想要的东西。但后来我从 nirsoft (https://www.nirsoft.net/utils/dll_export_viewer.html) 找到了免费的 dllexp.exe。

    直接下载链接:https://www.nirsoft.net/packages/progtools.zip,完美展示了一个dll/ocx的所有导出功能,非常人性化。

    【讨论】:

      猜你喜欢
      • 2019-06-02
      • 2010-09-28
      • 2011-01-02
      • 2015-07-21
      • 1970-01-01
      • 2010-10-25
      • 2016-01-07
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多