Extract DLL member names in Delphi
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.
What should be in “if libDirectory nil then”, ?
WordPress formatting sadly ruined this. I have reposted a few times so it should be visible now 🙂