Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7588067
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T19:49:54+00:00 2026-05-30T19:49:54+00:00

I’m working on something which dynamically loads specially formulated DLL’s. I need to be

  • 0

I’m working on something which dynamically loads specially formulated DLL’s. I need to be able to check the DLL and make sure all the expected functions exist before I consider using this DLL. If it’s missing some certain functions, I should not try to load it. I know I could attempt to call one of the functions and see if there’s an exception, but I would see errors in debug mode.

How should I go about checking a DLL if a function exists? I’d like to check it before I load it (using LoadLibrary) but I guess it’s OK if I have to load it to perform this check too.

UPDATE

I’ve accepted David’s answer below, and thought I’d post my final code to show the whole process. I turned it into a function returning a Bool, whether it succeeded or not, cleaned the code a bit, and added another function at the bottom which uses this one to check each name one by one.

I decided to use this method instead of reading GetProcAddress because it will help me in the future with other things.

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';

function ExportedFunctionNames(const ImageName: string; NamesList: TStrings): Bool;
var
  i: Integer;
  FileHandle: THandle;
  ImageHandle: THandle;
  ImagePointer: Pointer;
  Header: PIMAGE_NT_HEADERS;
  ExportTable: PIMAGE_EXPORT_DIRECTORY;
  NamesPointer: Pointer;
  Names: PAnsiChar;
  NamesDataLeft: Integer;
begin
  Result:= False;
  NamesList.Clear;
  FileHandle:= CreateFile(PChar(ImageName), GENERIC_READ, FILE_SHARE_READ,
    nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if FileHandle = INVALID_HANDLE_VALUE then Exit;
  try
    ImageHandle:= CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
    if ImageHandle = 0 then Exit;
    try
      ImagePointer:= MapViewOfFile(ImageHandle, FILE_MAP_READ, 0, 0, 0);
      if not Assigned(ImagePointer) then Exit;
      try
        Header:= ImageNtHeader(ImagePointer);
        if not Assigned(Header) then Exit;
        if Header.Signature <> $00004550 then Exit; // "PE\0\0" as a DWORD.
        ExportTable:= ImageRvaToVa(Header, ImagePointer,
          Header.OptionalHeader.DataDirectory[0].VirtualAddress, nil);
        if not Assigned(ExportTable) then Exit;
        NamesPointer:= ImageRvaToVa(Header, ImagePointer,
          Cardinal(ExportTable.AddressOfNames), nil);
        if not Assigned(NamesPointer) then Exit;
        Names:= ImageRvaToVa(Header, ImagePointer, Cardinal(NamesPointer^), nil);
        if not Assigned(Names) then Exit;
        NamesDataLeft:= Header.OptionalHeader.DataDirectory[0].Size;
        for i:= 0 to ExportTable.NumberOfNames - 1 do begin
          NamesList.Add(Names);
          while (Names^ <> chr(0)) and (NamesDataLeft > 0) do begin
            Inc(Names);
            Dec(NamesDataLeft);
          end;
          Inc(Names);
        end;
        Result:= True;
      finally
        UnmapViewOfFile(ImagePointer);
      end;
    finally
      CloseHandle(ImageHandle);
    end;
  finally
    CloseHandle(FileHandle);
  end;
end;

function IsMyDLL(const Filename: String): Bool;
var
  H: THandle;
  L: TStringList;
  function InList(const Func: String): Bool;
  begin
    Result:= L.IndexOf(Func) >= 0;
  end;
begin
  Result:= False;
  L:= TStringList.Create;
  try
    if ExportedFunctionNames(Filename, L) then begin
      Result:=//Names of functions which need to exist
        InList('GetName') and
        InList('GetDescription') and
        InList('GetVersion') and
        InList('Start') and
        InList('Stop');
    end;
  finally
    L.Free;
  end;
end;
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T19:49:56+00:00Added an answer on May 30, 2026 at 7:49 pm

    If you are in control of the DLLs and you don’t want to load them in order to check capability, then you could use the version resource to indicate capability. This would require the host app to have knowledge of what was the minimum supported version for each optional DLL feature. You can read the version resource cheaply without loading the DLL.

    It is perfectly possible, and rather simple, to obtain the list of functions exported by a DLL with loading it into your process with LoadLibrary. The dbghelp.dll system library provides services to do that. However, I suspect that is overkill for your situation.

    If it is not a problem to load and unload the DLL then GetProcAddress is probably the preferred solution. If there is some reason why you need to avoid loading the DLL in order to check capability, use the version resource to infer capability. If you need to do this with legacy DLLs that do not have a meaningful version resource then use dbghelp.dll to find the exported functions.


    For the sake of completeness, here is some code to read all the exported symbols from a DLL, without loading it with LoadLibrary.

    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 ImageExportedFunctionNames(const ImageName: string; NamesList: TStrings);
    var
      i: Integer;
      FileHandle: THandle;
      ImageHandle: THandle;
      ImagePointer: Pointer;
      Header: PIMAGE_NT_HEADERS;
      ExportTable: PIMAGE_EXPORT_DIRECTORY;
      NamesPointer: Pointer;
      Names: PAnsiChar;
      NamesDataLeft: Integer;
    begin
      //NOTE: our policy in this procedure is to exit upon any failure and return an 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;
    
            NamesPointer := ImageRvaToVa(Header, ImagePointer, Cardinal(ExportTable.AddressOfNames), nil);
            if not Assigned(NamesPointer) then begin
              exit;
            end;
            Names := ImageRvaToVa(Header, ImagePointer, Cardinal(NamesPointer^), nil);
            if not Assigned(Names) then begin
              exit;
            end;
    
            NamesDataLeft := Header.OptionalHeader.DataDirectory[0].Size;
            for i := 0 to ExportTable.NumberOfNames-1 do begin
              NamesList.Add(Names);
              // Locate the next name
              while (Names^<>chr(0)) and (NamesDataLeft>0) do begin
                inc(Names);
                dec(NamesDataLeft);
              end;
              inc(Names);
            end;
          Finally
            UnmapViewOfFile(ImagePointer); // Ignore error as there is not much we could do.
          End;
        Finally
          CloseHandle(ImageHandle);
        End;
      Finally
        CloseHandle(FileHandle);
      End;
    end;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have a text area in my form which accepts all possible characters from
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I am trying to understand how to use SyndicationItem to display feed which is
I used javascript for loading a picture on my website depending on which small
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I need to clean up various Word 'smart' characters in user input, including but
I need a function that will clean a strings' special characters. I do NOT
I have thousands of HTML files to process using Groovy/Java and I need to
I'm working with an upstream system that sometimes sends me text destined for HTML/XML

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.