Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get all the exported functions in a DLL?

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

like image 261
user5180416 Avatar asked Mar 16 '23 03:03

user5180416


1 Answers

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;
like image 102
David Heffernan Avatar answered Mar 24 '23 16:03

David Heffernan