Mega Code Archive

 
Categories / Delphi / Files
 

Get The list of function that an executable file imports

Title: Get The list of function that an executable file imports. Question: How to get the list of functions that an executable file imports as well as other information like the dlls from which the program imports these functions Answer: The following program shows how you can get the list of functions imported by the executable file. It consists of two units the first one is the 'structures' unit which is required by the program unit Here is the code Structures File --------------- unit structures; interface uses Windows,sysutils; const IMAGE_DOS_SIGNATURE = $5A4D; { MZ } IMAGE_OS2_SIGNATURE = $454E; { NE } IMAGE_OS2_SIGNATURE_LE = $454C; { LE } IMAGE_VXD_SIGNATURE = $454C; { LE } IMAGE_NT_SIGNATURE = $00004550; { PE00 } IMAGE_SIZEOF_SHORT_NAME = 8; IMAGE_SIZEOF_SECTION_HEADER = 40; IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16; IMAGE_RESOURCE_NAME_IS_STRING = $80000000; IMAGE_RESOURCE_DATA_IS_DIRECTORY = $80000000; IMAGE_OFFSET_STRIP_HIGH = $7FFFFFFF; DIRECTORY_ENTRY_EXPORT = 0; // Export Directory IMAGE_DIRECTORY_ENTRY_IMPORT = 1; // Import Directory IMAGE_DIRECTORY_ENTRY_RESOURCE = 2; // Resource Directory IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3; // Exception Directory IMAGE_DIRECTORY_ENTRY_SECURITY = 4; // Security Directory IMAGE_DIRECTORY_ENTRY_BASERELOC = 5; // Base Relocation Table IMAGE_DIRECTORY_ENTRY_DEBUG = 6; // Debug Directory IMAGE_DIRECTORY_ENTRY_COPYRIGHT = 7; // Description String IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8; // Machine Value (MIPS GP) IMAGE_DIRECTORY_ENTRY_TLS = 9; // TLS Directory IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10; // Load Configuration Directory IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11; // Bound Import Directory in headers IMAGE_DIRECTORY_ENTRY_IAT = 12; type plist_entry = ^LIST_ENTRY; LIST_ENTRY = record Flink:pLIST_ENTRY; Blink:pLIST_ENTRY; end; type 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; type FPO_DATA =packed record ulOffStart: DWORD; // offset 1st byte of function code cbProcSize:DWORD ; // # bytes in function cdwLocals:DWORD; // # bytes in locals/4 cdwParams:WORD ; // # bytes in params/4 cbProlog:WORD; // # bytes in prolog cbRegs:WORD; // # regs saved fHasSEH:WORD; // TRUE if SEH in func fUseBP:WORD; // TRUE if EBP has been allocated reserved:WORD; // reserved for future use cbFrame:WORD; // frame type end; PFPO_DATA=^FPO_DATA; type IMAGE_FUNCTION_ENTRY=packed record StartingAddress:dword; EndingAddress:dword; EndOfPrologue:dword; end; PIMAGE_FUNCTION_ENTRY=^IMAGE_FUNCTION_ENTRY; type PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER; IMAGE_DOS_HEADER = packed record { DOS .EXE header } e_magic : WORD; { Magic number } e_cblp : WORD; { Bytes on last page of file } e_cp : WORD; { Pages in file } e_crlc : WORD; { Relocations } e_cparhdr : WORD; { Size of header in paragraphs } e_minalloc : WORD; { Minimum extra paragraphs needed } e_maxalloc : WORD; { Maximum extra paragraphs needed } e_ss : WORD; { Initial (relative) SS value } e_sp : WORD; { Initial SP value } e_csum : WORD; { Checksum } e_ip : WORD; { Initial IP value } e_cs : WORD; { Initial (relative) CS value } e_lfarlc : WORD; { File address of relocation table } e_ovno : WORD; { Overlay number } e_res : packed array [0..3] of WORD; { Reserved words } e_oemid : WORD; { OEM identifier (for e_oeminfo) } e_oeminfo : WORD; { OEM information; e_oemid specific } e_res2 : packed array [0..9] of WORD; { Reserved words } e_lfanew : Longint; { File address of new exe header } end; PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER; IMAGE_FILE_HEADER = packed record Machine : WORD; NumberOfSections : WORD; TimeDateStamp : DWORD; PointerToSymbolTable : DWORD; NumberOfSymbols : DWORD; SizeOfOptionalHeader : WORD; Characteristics : WORD; end; PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY; IMAGE_DATA_DIRECTORY = packed record VirtualAddress : DWORD; Size : DWORD; end; PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_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_SECTION_HEADER = ^IMAGE_SECTION_HEADER; 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_NT_HEADERS = ^IMAGE_NT_HEADERS; IMAGE_NT_HEADERS = packed record Signature : DWORD; FileHeader : IMAGE_FILE_HEADER; OptionalHeader : IMAGE_OPTIONAL_HEADER; end; PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY; IMAGE_RESOURCE_DIRECTORY = packed record Characteristics : DWORD; TimeDateStamp : DWORD; MajorVersion : WORD; MinorVersion : WORD; NumberOfNamedEntries : WORD; NumberOfIdEntries : WORD; end; PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY; IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record Name: DWORD; // Or ID: Word (Union) OffsetToData: DWORD; end; PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY; IMAGE_RESOURCE_DATA_ENTRY = packed record OffsetToData : DWORD; Size : DWORD; CodePage : DWORD; Reserved : DWORD; end; PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U; IMAGE_RESOURCE_DIR_STRING_U = packed record Length : WORD; NameString : array [0..0] of WCHAR; end; type LOADED_IMAGE = record ModuleName:pchar; hFile:thandle; MappedAddress:pchar; FileHeader:PIMAGE_NT_HEADERS; 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; type IMAGE_LOAD_CONFIG_DIRECTORY = packed record Characteristics:DWORD; TimeDateStamp:DWORD; MajorVersion:WORD; MinorVersion:WORD; GlobalFlagsClear:DWORD; GlobalFlagsSet:DWORD; CriticalSectionDefaultTimeout:DWORD; DeCommitFreeBlockThreshold:DWORD; DeCommitTotalFreeThreshold:DWORD; LockPrefixTable:Pointer; MaximumAllocationSize:DWORD; VirtualMemoryThreshold:DWORD; ProcessHeapFlags:DWORD; ProcessAffinityMask:DWORD; Reserved: array[0..2] of DWORD; end; PIMAGE_LOAD_CONFIG_DIRECTORY=^IMAGE_LOAD_CONFIG_DIRECTORY; type IMAGE_IMPORT_BY_NAME = packed record Hint:WORD; Name:DWORD; end; PIMAGE_IMPORT_BY_NAME=^IMAGE_IMPORT_BY_NAME; type IMAGE_THUNK_DATA =packed record ForwarderString:PBYTE; Func:PDWORD; Ordinal:DWORD; AddressOfData:PIMAGE_IMPORT_BY_NAME; end; PIMAGE_THUNK_DATA=^IMAGE_THUNK_DATA; type IMAGE_IMPORT_DESCRIPTOR= packed record Characteristics:DWORD; TimeDateStamp:DWORD; ForwarderChain:DWORD; Name:DWORD; FirstThunk:DWORD; end; PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR; implementation end. -------- Code File --------- unit p1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,structures; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); private { Private declarations } public procedure ProcessFile; end; var Form1: TForm1; h1,hmap:integer; bptr:pointer; gptr:pbyte; ntsign:plongword; doshd:PIMAGE_DOS_HEADER; pehd:PIMAGE_FILE_HEADER; peoptn:PIMAGE_OPTIONAL_HEADER; sectionheads:array of PIMAGE_SECTION_HEADER; offsetmem:longword; idataphysicaladress:pbyte; idata:PIMAGE_IMPORT_DESCRIPTOR; modulename,functionname:pchar; dptr:plongword; ord:word; pexpdir:PIMAGE_EXPORT_DIRECTORY; pexpnames:pdword; expfname:pchar; implementation {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); begin processfile; end; procedure TForm1.ProcessFile; var i,j:integer; begin if opendialog1.Execute=false then exit else h1:=fileopen(opendialog1.FileName,fmShareDenyNone or fmOpenRead); hmap:=CreateFileMapping(h1,nil,PAGE_READONLY,0,0,nil); doshd:=PIMAGE_DOS_HEADER(mapviewoffile(hmap,FILE_MAP_READ,0,0,0)); bptr:=doshd; memo1.lines.add('DOS Header'); memo1.Lines.Add(' -e_magic='+inttostr(doshd.e_magic)); memo1.Lines.Add(' -e_cblp='+inttostr(doshd.e_cblp)); memo1.Lines.Add(' -e_cp='+inttostr(doshd.e_cp)); memo1.Lines.Add(' -e_crlc='+inttostr(doshd.e_crlc)); memo1.Lines.Add(' -e_cparhdr='+inttostr(doshd.e_cparhdr)); memo1.Lines.Add(' -e_minalloc='+inttostr(doshd.e_minalloc)); memo1.Lines.Add(' -e_maxalloc='+inttostr(doshd.e_maxalloc)); memo1.Lines.Add(' -e_ss='+inttostr(doshd.e_ss)); memo1.Lines.Add(' -e_sp='+inttostr(doshd.e_sp)); memo1.Lines.Add(' -e_csum='+inttostr(doshd.e_csum)); memo1.Lines.Add(' -e_ip='+inttostr(doshd.e_ip)); memo1.Lines.Add(' -e_cs='+inttostr(doshd.e_cs)); memo1.Lines.Add(' -e_lfarlc='+inttostr(doshd.e_lfarlc)); memo1.Lines.Add(' -e_ovno='+inttostr(doshd.e_ovno)); memo1.Lines.Add(' -e_oemid='+inttostr(doshd.e_oemid)); memo1.Lines.Add(' -e_oeminfo='+inttostr(doshd.e_oeminfo)); memo1.Lines.Add(' -e_lfanew='+inttostr(doshd.e_lfanew)); gptr:=bptr; inc(gptr,doshd.e_lfanew); ntsign:=plongword(gptr); if (ntsign^=IMAGE_NT_SIGNATURE) then begin memo1.Lines.Add('NT Signature='+inttostr(ntsign^)); memo1.Lines.Add('Windows Executable'); memo1.lines.add('------------------------------------------'); gptr:=bptr; inc(gptr,doshd.e_lfanew+4); pehd:=PIMAGE_FILE_HEADER(gptr); memo1.lines.add('PE Header'); memo1.Lines.Add(' -Machine='+inttostr(pehd.Machine)); memo1.Lines.Add(' -Number of Sections='+inttostr(pehd.NumberOfSections)); memo1.Lines.Add(' -TimeDateStamp='+IntToStr(pehd.TimeDateStamp)); memo1.Lines.Add(' -PointerToSymbolTable='+IntToStr(pehd.PointerToSymbolTable)); memo1.Lines.Add(' -Number of Symbols='+IntToStr(pehd.NumberOfSymbols)); memo1.Lines.Add(' -SizeOfOptionalHeader='+IntToStr(pehd.SizeOfOptionalHeader)); memo1.Lines.Add(' -Characteristics='+IntToStr(pehd.Characteristics)); memo1.lines.add('------------------------------------------'); gptr:=pbyte(pehd); inc(gptr,sizeof(IMAGE_FILE_HEADER)); peoptn:=PIMAGE_OPTIONAL_HEADER(gptr); memo1.lines.add('PE Optional Header'); memo1.Lines.Add(' -Magic='+inttostr(peoptn.Magic)); memo1.Lines.Add(' -MajorLinkerVersion='+inttostr(peoptn.MajorLinkerVersion)); memo1.Lines.Add(' -MinorLinkerVersion='+inttostr(peoptn.MinorLinkerVersion)); memo1.Lines.Add(' -SizeOfCode='+inttostr(peoptn.SizeOfCode)); memo1.Lines.Add(' -SizeOfInitializedData='+inttostr(peoptn.SizeOfInitializedData)); memo1.Lines.Add(' -SizeOfUninitializedData='+inttostr(peoptn.SizeOfUninitializedData)); memo1.Lines.Add(' -AddressOfEntryPoint='+inttostr(peoptn.AddressOfEntryPoint)); memo1.Lines.Add(' -BaseOfCode='+inttostr(peoptn.BaseOfCode)); memo1.Lines.Add(' -BaseOfData='+inttostr(peoptn.BaseOfData)); memo1.Lines.Add(' -ImageBase='+inttostr(peoptn.ImageBase)); memo1.Lines.Add(' -SectionAlignment='+inttostr(peoptn.SectionAlignment)); memo1.Lines.Add(' -FileAlignment='+inttostr(peoptn.FileAlignment)); memo1.Lines.Add(' -MajorOperatingSystemVersion='+inttostr(peoptn.MajorOperatingSystemVersion)); memo1.Lines.Add(' -MinorOperatingSystemVersion='+inttostr(peoptn.MinorOperatingSystemVersion)); memo1.Lines.Add(' -MajorImageVersion='+inttostr(peoptn.MajorImageVersion)); memo1.Lines.Add(' -MinorImageVersion='+inttostr(peoptn.MinorImageVersion)); memo1.Lines.Add(' -MajorSubsystemVersion='+inttostr(peoptn.MajorSubsystemVersion)); memo1.Lines.Add(' -MinorSubsystemVersion ='+inttostr(peoptn.MinorSubsystemVersion )); memo1.Lines.Add(' -Reserved1 ='+inttostr(peoptn.Reserved1)); memo1.Lines.Add(' -SizeOfImage ='+inttostr(peoptn.SizeOfImage)); memo1.Lines.Add(' -SizeOfHeaders ='+inttostr(peoptn.SizeOfHeaders)); memo1.Lines.Add(' -CheckSum ='+inttostr(peoptn.CheckSum)); memo1.Lines.Add(' -SubSystem ='+inttostr(peoptn.Subsystem)); memo1.Lines.Add(' -DllCharacteristics ='+inttostr(peoptn.DllCharacteristics)); memo1.Lines.Add(' -SizeOfStackReserve ='+inttostr(peoptn.SizeOfStackReserve)); memo1.Lines.Add(' -SizeOfStackCommit ='+inttostr(peoptn.SizeOfStackCommit)); memo1.Lines.Add(' -SizeOfHeapReserve ='+inttostr(peoptn.SizeOfHeapReserve)); memo1.Lines.Add(' -SizeOfHeapCommit ='+inttostr(peoptn.SizeOfHeapCommit)); memo1.Lines.Add(' -LoaderFlags ='+inttostr(peoptn.LoaderFlags)); memo1.Lines.Add(' -NumberOfRvaAndSizes ='+inttostr(peoptn.NumberOfRvaAndSizes)); memo1.lines.add('------------------------------------------'); setlength(sectionheads,pehd.NumberOfSections); for i:=0 to pehd.NumberOfSections -1 do begin gptr:=pbyte(peoptn); inc(gptr,sizeof(IMAGE_OPTIONAL_HEADER)+i*sizeof(IMAGE_SECTION_HEADER)); sectionheads[i]:=PIMAGE_SECTION_HEADER(gptr); end; if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size=0 then begin memo1.lines.add('No Export Table Present'); memo1.lines.add('------------------------------------------'); end else begin memo1.lines.add('Export Table Present'); for i:=pehd.NumberOfSections-1 downto 0 do begin if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress=sectionheads[i].VirtualAddress then begin offsetmem:=sectionheads[i].PointerToRawData-sectionheads[i].VirtualAddress; break; end; end; gptr:=bptr; inc(gptr,offsetmem+peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); pexpdir:=PIMAGE_EXPORT_DIRECTORY(gptr); pexpnames:=pdword(longint(bptr)+integer(PIMAGE_EXPORT_DIRECTORY(gptr).pAddressOfNames)); for i:=0 to pexpdir.NumberOfNames-1 do begin expfname:=pchar(integer(bptr)+integer(pexpnames^)); memo1.lines.add(' -'+expfname); inc(pexpnames); end; memo1.lines.add('------------------------------------------'); end; if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=0 then memo1.lines.add('No Import Table Present') else begin memo1.lines.add('Import Table Present'); for i:=pehd.NumberOfSections-1 downto 0 do begin if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=sectionheads[i].VirtualAddress then begin offsetmem:=sectionheads[i].PointerToRawData-sectionheads[i].VirtualAddress; break; end; end; gptr:=bptr; inc(gptr,offsetmem+peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); idataphysicaladress:=gptr; i:=0; j:=0; while true do begin gptr:=idataphysicaladress; inc(gptr,i*sizeof(IMAGE_IMPORT_DESCRIPTOR)); idata :=PIMAGE_IMPORT_DESCRIPTOR(gptr); if idata.Name = 0 then break; gptr:=bptr; inc(gptr,offsetmem+idata.Name); modulename:=pchar(gptr); memo1.Lines.Add('Module Name:'+ modulename); while true do begin if (idata.FirstThunk + j*4)= 0 then break; gptr:=bptr; inc(gptr,offsetmem+idata.FirstThunk +j*4); dptr:=plongword(gptr); gptr:=bptr; inc(gptr,offsetmem+dptr^); if isbadcodeptr(gptr) then break; ord:=pword(gptr)^; inc(gptr,2); functionname:=pchar(gptr); if isbadcodeptr(functionname) then break; if functionname=nil then break; memo1.Lines.Add(' -Ord:'+inttohex(ord,3)+' Function Name:'+ functionname); inc(j); end; inc(i); end; end; end; UnmapViewOfFile(bptr); closehandle(hmap); fileclose(h1); end; end.