Link to home
Start Free TrialLog in
Avatar of wuzhou
wuzhou

asked on

functions in DLL

is there any way to know the list of functions in a DLL (and it's parameter)?
Avatar of VSF
VSF
Flag of Brazil image

GETTING FUNCTIONS OF DLL
How to get the list of functions exported by a Dll module.
Answer:


To get the list of functions exported by a Dll module you need to use the following functions.

MapAndLoad function in 'imagehlp.pas'.
ImageRvaToVa function in 'imagehlp.pas'.

You also need to define the following structures.
To find details about what the members of these structures mean visit the web page 'http://www.csn.ul.ie/~caolan/publink/winresdump/winresdump/doc/msdn_peeringpe.html'

const
IMAGE_SIZEOF_SHORT_NAME            = 8;
IMAGE_NUMBEROF_DIRECTORY_ENTRIES   = 16;

  IMAGE_DATA_DIRECTORY = packed record
    VirtualAddress  : DWORD;
    Size            : DWORD;
  PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;

IMAGE_SECTION_HEADER = packed record
    Name     : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
    PhysicalAddress : DWORD; // or VirtualSize (union);
    VirtualAddress  : DWORD;
    SizeOfRawData   : DWORD;
    PointerToRawData : DWORD;
    PointerToRelocations : DWORD;
    PointerToLinenumbers : DWORD;
    NumberOfRelocations : WORD;
    NumberOfLinenumbers : WORD;
    Characteristics : DWORD;
  end;
  PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;

  IMAGE_OPTIONAL_HEADER = packed record
   { Standard fields. }
    Magic           : WORD;
    MajorLinkerVersion : Byte;
    MinorLinkerVersion : Byte;
    SizeOfCode      : DWORD;
    SizeOfInitializedData : DWORD;
    SizeOfUninitializedData : DWORD;
    AddressOfEntryPoint : DWORD;
    BaseOfCode      : DWORD;
    BaseOfData      : DWORD;
   { NT additional fields. }
    ImageBase       : DWORD;
    SectionAlignment : DWORD;
    FileAlignment   : DWORD;
    MajorOperatingSystemVersion : WORD;
    MinorOperatingSystemVersion : WORD;
    MajorImageVersion : WORD;
    MinorImageVersion : WORD;
    MajorSubsystemVersion : WORD;
    MinorSubsystemVersion : WORD;
    Reserved1       : DWORD;
    SizeOfImage     : DWORD;
    SizeOfHeaders   : DWORD;
    CheckSum        : DWORD;
    Subsystem       : WORD;
    DllCharacteristics : WORD;
    SizeOfStackReserve : DWORD;
    SizeOfStackCommit : DWORD;
    SizeOfHeapReserve : DWORD;
    SizeOfHeapCommit : DWORD;
    LoaderFlags     : DWORD;
    NumberOfRvaAndSizes : DWORD;
    DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1]                                            of IMAGE_DATA_DIRECTORY;
  end;
  PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;

IMAGE_FILE_HEADER = packed record
    Machine              : WORD;
    NumberOfSections     : WORD;
    TimeDateStamp        : DWORD;
    PointerToSymbolTable : DWORD;
    NumberOfSymbols      : DWORD;
    SizeOfOptionalHeader : WORD;
    Characteristics      : WORD;
  end;
  PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;

IMAGE_NT_HEADERS = packed record
  Signature       : DWORD;
  FileHeader      : IMAGE_FILE_HEADER;
  OptionalHeader  : IMAGE_OPTIONAL_HEADER;
end;
PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;

type LOADED_IMAGE = record
  ModuleName:pchar;//name of module
  hFile:thandle;//handle of file
  MappedAddress:pchar;// the base address of mapped file
  FileHeader:PIMAGE_NT_HEADERS;//The Header of the file.
  LastRvaSection:PIMAGE_SECTION_HEADER;
  NumberOfSections:integer;
  Sections:PIMAGE_SECTION_HEADER ;
  Characteristics:integer;
  fSystemImage:boolean;
  fDOSImage:boolean;
  Links:LIST_ENTRY;
  SizeOfImage:integer;
end;
PLOADED_IMAGE= ^LOADED_IMAGE;

here is the code

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Menus,structures,imagehlp;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Open1: TMenuItem;
    OpenDialog1: TOpenDialog;
    ListBox2: TListBox;
    procedure Open1Click(Sender: TObject);
  private
  public
   procedure DLLFuncstoList(fname:string;alistbox:tlistbox);
  end;

var
  Form1: TForm1;
implementation

{$R *.DFM}


procedure TForm1.DLLFuncstoList(fname:string;alistbox:tlistbox);
var
  fih:LOADED_IMAGE;
  pexpdir:PIMAGE_EXPORT_DIRECTORY;
  pexpnames:pdword;//pointer to list of exported fucntions
  pt1:PImageSectionHeader;
  i:integer;
  exportedfuncname:pchar;//exported function name
begin
   alistbox.items.clear;
   pt1:=nil;
   MapAndLoad(pchar(fname),pchar('#0'),@fih,true,true);//load the  
                                                 file into memory.
   pExpDir:=PIMAGE_EXPORT_DIRECTORY(fih.FileHeader.OptionalHeader.
                                    DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
   pExpDir:=PIMAGE_EXPORT_DIRECTORY(ImageRvaToVa
         (fih.FileHeader,fih.MappedAddress,DWORD(pExpDir),pt1));
   pExpNames:= pExpDir.pAddressOfNames;
   pExpNames:=PDWORD(ImageRvaToVa
       (fih.FileHeader,fih.MappedAddress,dword(pExpNames),pt1));
   pt1:=nil;
   for i:=0 to pexpdir.NumberOfNames-1 do
    begin
     exportedfuncname:=pchar(ImageRvaToVa  
       (fih.FileHeader,fih.MappedAddress,dword(pExpNames^),pt1));
     alistbox.items.add(exportedfuncname);
     inc(pexpnames);
    end;
   UnMapAndLoad(@fih);//Un load the mapped file  from memory.
end;

procedure TForm1.Open1Click(Sender: TObject);
var
begin
if opendialog1.execute = true then
  begin
   DLLFuncstoList(opendialog1.filename,listbox1);
  end;
end;


end.
 


Comments to this article
Write a new comment
 
Avoid General protection faults
    Florin Oltean (Sep 13 2000 8:53AM)

You shold better do something like :
if not MapAndLoad(pchar(fname),pchar('#0'),@fih,true,true) then Exit;

because if the call fails you will get a pretty nice GPF.
Respond

 
missing structure
    Florin Oltean (Sep 13 2000 8:32AM)

Your code is not running because you forgot to publish this structure :

IMAGE_EXPORT_DIRECTORY = packed record
  Characteristics : DWORD;
  TimeDateStamp   : DWORD;
  MajorVersion    : WORD;
  MinorVersion    : WORD;
  Name : DWORD;            
  Base : DWORD;
  NumberOfFunctions     : DWORD;
  NumberOfNames         : DWORD;
  pAddressOfFunctions   : PDWORD;
  pAddressOfNames       : PDWORD;
  pAddressOfNameOrdinals: PWORD;
end;
PIMAGE_EXPORT_DIRECTORY = ^IMAGE_EXPORT_DIRECTORY;
Respond

 
suggestions
    Andreas Schmidt (Aug 24 2000 3:20AM)

please separate the opendialog from the main procedure.

Put the core of Open1Click in a own procedure:

procedure DLLFuncsToListbox(filename:TFilename; lb:TListBox);
begin
...
end;


procedure TForm1.Open1Click(Sender: TObject);
begin
  if opendialog1.execute = true then
  begin
     listbox1.items.clear;
     DLLFuncsToListbox(opendialog1.filename, listbox1);
  end;
end;
ASKER CERTIFIED SOLUTION
Avatar of new_x
new_x

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of simonet
>And As far as I know it is impossible
to get the function parameters type.


That is correct. It's been asked a million times and the answer is always the same: impossible.
Avatar of Madshi
Madshi

Getting the parameters automatically is impossible. A very good disassembler program might be able to analyze the binary code of the DLL and find out how long the parameters are altogether (e.g. 20 bytes), but you won't get the name/meaning/whatever of the parameters. Sorry...

Regards, Madshi.
try Maquisistem DLL Viewer.
u can download it at http://www.springfieldtech.com/dlldload/Dll_Viewer/DLL%20Viewer104.htm
The Jedi Code Library contains JclPeImage unit which can read all info a PE file (EXE or DLL) contains.
Get it from http://delphi-jedi.org. There is also the PeViewer sample program.
Resource Explorer also gives you tons of information on the DLL:

- imported libraries and functions
- exported functions
- dependency analyzer (up to infinite levels of dependency)
- all resources

you can download REX for free from:

Athena's Place: http://www.bhnet.com.br/~simonet/resexp.htm
Good morning, wuzhou,

This question is still open today and may just have been overlooked.  If you have been helped here, you may choose the comment which served you as the accepted answer to then grade and close so that others seeking help on this may find it in the PAQ database.

If more information is required, please post details here.

Thank you,
Asta