4

How can I get all the exported functions from a DLL, programmatically? I am trying to compare two DLL's for exported functions.

user5180416
  • 41
  • 1
  • 4
  • @DavidHeffernan Programmatically of course. – user5180416 Aug 10 '15 at 10:36
  • if you need to do this in console: `tdump.exe YourDLL.DLL` and then compare in `WinMerge` or in any other text comparising tool – Zam Aug 10 '15 at 11:07
  • 2
    You could have a look at the code in GExperts PE-Information Expert which shows all headers and also imports and exports of a dll. – dummzeuch Aug 10 '15 at 14:59

2 Answers2

7

This is the code that I use:

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;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

I came here to find a way to list all functions contained within an ocx (which is basically a dll). All infos here didn't give me what I was looking for. But then I found the free dllexp.exe from nirsoft (https://www.nirsoft.net/utils/dll_export_viewer.html).

Direct download link: https://www.nirsoft.net/packages/progtools.zip which perfectly shows all exported functions of a dll/ocx and is very user-friendly.

dummzeuch
  • 10,975
  • 4
  • 51
  • 158
John Ranger
  • 541
  • 5
  • 18