Offset (PE32/
PE32+) |
Size (PE32/
PE32+) |
Field
|
Description
|
28/24
|
4/8
|
ImageBase
|
The
preferred address of the first byte of image when loaded into memory; must be
a multiple of 64 K. The default for DLLs is 0x10000000. The default for
Windows CE EXEs is 0x00010000. The default for Windows NT, Windows 2000,
Windows XP, Windows 95, Windows 98, and Windows Me is
0x00400000.
|
32/32
|
4
|
SectionAlignment
|
The
alignment (in bytes) of sections when they are loaded into memory. It must be
greater than or equal to FileAlignment. The default is the page size for the
architecture.
|
36/36
|
4
|
FileAlignment
|
The
alignment factor (in bytes) that is used to align the raw data of sections in
the image file. The value should be a power of 2 between 512 and 64 K,
inclusive. The default is 512. If the SectionAlignment is less than the
architecture’s page size, then FileAlignment must match SectionAlignment.
|
40/40
|
2
|
MajorOperatingSystemVersion
|
The
major version number of the required operating system.
|
42/42
|
2
|
MinorOperatingSystemVersion
|
The
minor version number of the required operating system.
|
44/44
|
2
|
MajorImageVersion
|
The
major version number of the image.
|
46/46
|
2
|
MinorImageVersion
|
The
minor version number of the image.
|
48/48
|
2
|
MajorSubsystemVersion
|
The
major version number of the subsystem.
|
50/50
|
2
|
MinorSubsystemVersion
|
The
minor version number of the subsystem.
|
52/52
|
4
|
Win32VersionValue
|
Reserved,
must be zero.
|
56/56
|
4
|
SizeOfImage
|
The
size (in bytes) of the image, including all headers, as the image is loaded
in memory. It must be a multiple of SectionAlignment.
|
60/60
|
4
|
SizeOfHeaders
|
The
combined size of an MS‑DOS stub, PE header, and section headers rounded up to
a multiple of FileAlignment.
|
64/64
|
4
|
CheckSum
|
The
image file checksum. The algorithm for computing the checksum is incorporated
into IMAGHELP.DLL. The following are checked for validation at load time: all
drivers, any DLL loaded at boot time, and any DLL that is loaded into a
critical Windows process.
|
68/68
|
2
|
Subsystem
|
The
subsystem that is required to run this image. For more information, see
“Windows Subsystem” later in this specification.
|
70/70
|
2
|
DllCharacteristics
|
For
more information, see “DLL Characteristics” later in this specification.
|
72/72
|
4/8
|
SizeOfStackReserve
|
The
size of the stack to reserve. Only SizeOfStackCommit is committed; the rest
is made available one page at a time until the reserve size is reached.
|
76/80
|
4/8
|
SizeOfStackCommit
|
The
size of the stack to commit.
|
80/88
|
4/8
|
SizeOfHeapReserve
|
The
size of the local heap space to reserve. Only SizeOfHeapCommit is committed;
the rest is made available one page at a time until the reserve size is
reached.
|
84/96
|
4/8
|
SizeOfHeapCommit
|
The
size of the local heap space to commit.
|
88/104
|
4
|
LoaderFlags
|
Reserved,
must be zero.
|
92/108
|
4
|
NumberOfRvaAndSizes
|
The
number of data-directory entries in the remainder of the optional header.
Each describes a location and size.
|
Since all three images come with the same data, I am just going to pick up the next 4 rows for us to look at (remember that we have already used the first 4 bytes in the last post):
000000B0 00 40 00 00 00 00 40 00 00 20 00 00 00 02 00 00 ·@····@·· ······
000000C0 04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ················
000000D0 00 80 00 00 00 02 00 00 00 00 00 00 03 00 40 85 ·?············@?
000000E0 00 00 10 00 00 10 00 00 00 00 10 00 00 10 00 00 ················
000000F0 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 ················
The first word is the ImageBase which is the expected (reading it as little-endian) 0x00400000 which means that this is a Windows image. Next, we have the SectionAlignment word which is 0x00002000. We finish off the row with the FileAlignment word which is also 0x00000200. Moving down, we get the MajorOperatingSystemVersion which is a half-word with a value of 0x0004 and the MinorOperatingSystemVersion half-word of 0x0000, meaning that these images are all targeting Windows 4.0 or better. Next, the MajorImageVersion and MinorImageVersions which are both half-word values of 0x0000. Next the MajorSubsystemVersion half-word of 0x0004 and the MinorSubsystemVersion of 0x0000. This is followed by the Win32VersionValue which is a reserved word and must be 0x00000000. That finished off the second row.
Moving on, we have the SizeOfImage word as 0x00008000 which seems strange since all three files are different sizes, but they are all the same program so it really makes sense. The SizeOfHeaders word is 0x00000200. The CheckSum word is blank, or 0x00000000 which is fine because only drivers, boot time DLLs, or critical system DLLs are checked when loaded. The last two half-words are the SubSystem as 0x0003 and the DllCharacteristics as 0x8540. When we look the SubSystem up in the document we find that all three files are command line:
IMAGE_SUBSYSTEM_WINDOWS_CUI
|
3
|
The
Windows character subsystem
|
and the DllCharacteristics flag lets us know that the image can be relocated, is NX compatible, does not use structured exeptions and is terminal server aware:
IMAGE_DLLCHARACTERISTICS_
DYNAMIC_BASE
|
0x0040
|
DLL
can be relocated at load time.
|
IMAGE_DLLCHARACTERISTICS_
NX_COMPAT
|
0x0100
|
Image
is NX compatible.
|
IMAGE_DLLCHARACTERISTICS_
NO_SEH
|
0x0400
|
Does
not use structured exception (SE) handling. No SE handler may be called in
this image.
|
IMAGE_DLLCHARACTERISTICS_
TERMINAL_SERVER_AWARE
|
0x8000
|
Terminal
Server aware.
|
It will be interesting to re-visit this section with an image that handles .NET exceptions and see if this value changes.
Moving on down, we have the last six words of the section. So, the SizeOfStackReserve value is 0x00100000, the SizeOfStackCommit value is 0x00001000, the SizeOfHeapCommit value is 0x00100000, the SizeOfHeapCommit value is 0x00001000, the LoaderFlags which is reserved and must be 0x00000000 and the NumberOfRvaAndSizes which is 0x00000010.
That ends the Windows-Specific field section. I tried using highlighting this time to help make sense of the parts being used. Did that help? Did it make it hard to read? Let me know, and I can make adjustments to the process. I actually started doing it to keep track of where I was in the binary block, but I can always clear the highlights out when I am done.
Next, we will start looking at the Optional Header Data Directories which will give us the addresses of the sections later in the list. We know that we have 16 of the data directories defined because of the value we found in NumberOfRvaAndSizes. See you next time!
Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8
Part 9
Part 1
Part 2
Part 3
Part 4
Part 5
Part 6
Part 7
Part 8
Part 9