Home > Delphi, Object Pascal > Extract DLL member names in Delphi

Extract DLL member names in Delphi

February 16, 2018 Leave a comment Go to comments

Long before dot net and Java I was doing a huge coding system for a large Norwegian company. They wanted a custom scripting engine and they wanted a way to embed bytecodes in dll files. Easy like apple pie (I sure know how to pick’em huh?).

The solution turned out to be simple enough, but this post is not about that, but rather about a unit I wrote as part of the solution. In order to recognize one dll from another, you obviously need the ability to examine a dll file. I mean, you could just load the dll and try to map the functions you need, but that will throw an exception if it’s the wrong dll.

So after a bit of googling around and spending a few hours on MDN, I sat down and wrote a unit for this. It allows you to load a dll and extract all the method names the library exposes. If nothing else it makes it easier to recognize your dll files.

Well enjoy!

unit dllexamine;

interface

uses
  WinAPI.Windows,
  WinAPI.ImageHlp,
  System.Sysutils,
  System.Classes;

  {
    Reference material for WinAPI functions
    =======================================

    MapAndLoad::
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms680353(v=vs.85).aspx

    UnMapAndLoad:
    https://social.msdn.microsoft.com/search/en-US/windows?query=UnMapAndLoad&refinement=183

    ImageDirectoryEntryToData:
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms680148(v=vs.85).aspx

    ImageRvaToVa:
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms680218(v=vs.85).aspx
  }

  Type

  THexDllExamine = class abstract
  public
    class function Examine(const Filename: AnsiString;
      out Members: TStringlist): boolean; static;
  end;

  implementation

  class function THexDllExamine.Examine(const Filename: AnsiString;
    out Members: TStringlist): boolean;
  type
    TDWordArray = array [0..$FFFFF] of DWORD;
  var
    libinfo:      LoadedImage;
    libDirectory: PImageExportDirectory;
    SizeOfList: Cardinal;
    pDummy: PImageSectionHeader;
    i: Cardinal;
    NameRVAs: ^TDWordArray;
    Name: string;
  begin
    result := false;
    members := nil;

    if MapAndLoad( PAnsiChar(FileName), nil, @libinfo, true, true) then
    begin
      try
        // Get the directory
        libDirectory := ImageDirectoryEntryToData(libinfo.MappedAddress,
          false, IMAGE_DIRECTORY_ENTRY_EXPORT, SizeOfList);

        // Anything to work with?
        if libDirectory  nil then
        begin

          // Get ptr to first node for the image directory
          NameRVAs := ImageRvaToVa( libinfo.FileHeader,
            libinfo.MappedAddress,
            DWORD(libDirectory^.AddressOfNames),
            pDummy
          );

          // Traverse until end
          Members := TStringList.Create;
          try
            for i := 0 to libDirectory^.NumberOfNames - 1 do
            begin
              Name := PChar(ImageRvaToVa(libinfo.FileHeader,
                libinfo.MappedAddress, NameRVAs^[i], pDummy));
              Name := Name.Trim();
              if Name.Length > 0 then
                Members.Add(Name);
            end;
          except
            on e: exception do
            begin
              FreeAndNil(Members);
              exit;
            end;
          end;

          // We never get here if an exception kicks in
          result := members  nil;

        end;
      finally
        // Yoga complete, now breathe ..
        UnMapAndLoad(@libinfo);
      end;
    end;
  end;

end.
  1. February 16, 2018 at 6:38 pm

    What should be in “if libDirectory nil then”, ?

    • March 16, 2018 at 6:35 pm

      WordPress formatting sadly ruined this. I have reposted a few times so it should be visible now 🙂

  1. No trackbacks yet.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: