Are you asking about the EXE running the current process or an EXE you've
loaded into a file or memory stream?
Anyhow, the data structures on disk are the same as those loaded into memory
on execution (see http://msdn.microsoft.com/msdnmag/issues/02/02/PE/ )
If you're wanting to access the data structures loaded into memory, then the
process hInstance is actually a pointer to the base of the file image once
it has been loaded into memory. ( Here's an example of how that can be
useful: http://angusj.com/delphitips/appendtoexe.php )
If you're asking about the structure of EXE files (ie the PE file format)
starting with the IMAGE_DOS_HEADER structure then there are numerous
resources on the net which go into the details. Eg:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndebug/html/msdn_peeringpe.asp
www.wotsit.org
It's been quite a few years since I've looked at this stuff so I'm afraid I
can't be more specific in answering your question.
The image starts with this structure:
TImageDosHeader = packed record
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 : 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 : array [0..9] of Word; // Reserved words
e_lfanew : DWord; // File address of new exe header
end;
That last field, e_lfanew is the address of the new header, so:
dosHeader := PImageDosHeader(lpFileBase);
PNTHeader := PImageNTHeaders(DWord(dosHeader) + dosHeader.e_lfanew);
where
TImageNTHeaders = packed record
Signature : DWord;
FileHeader : TImageFileHeader;
OptionalHeader : TImageOptionalHeader;
end;
PImageNTHeaders = ^TImageNTHeaders;
and
TImageFileHeader = packed record
Machine : Word;
NumberOfSections : Word;
TimeDateStamp : DWord;
PointerToSymbolTable : DWord;
NumberOfSymbols : DWord;
SizeOfOptionalHeader : Word;
Characteristics : Word;
end;
PImageFileHeader = ^TImageFileHeader;
and
TImageOptionalHeader = 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 : array[0..pred(ImageNumberofDirectoryEntries)] of
TImageDataDirectory;
end;
PImageOptionalHeader = ^TImageOptionalHeader;
IHTH
- Per
Angus and Per, Thank you. I was able t find the record layout in
Windows SDK help, but not the location of the record. I could
have guessed it, if I had had my wits about me. Thank you both.
Best regards, JohnH