Friday, January 6, 2017

Dissecting C# Executables: Part 5

Welcome!  Ok, what's next?  In Part 4 we finished off the Optional Header Standard fields, so now we move on to the Windows-Specific fields that are needed by the Windows loader and linker.  There is a bunch of them (21) so let's see how many I can get done tonight.  Here is the full list from the Microsoft Portable Executable and Common ObjectFile Format Specification: Revision 10 that we have been using for these dissections:

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

No comments:

Post a Comment