Friday, January 13, 2017

Dissecting C# Executables: Part 9

Let's get back to section two of the Section Table as defined in Microsoft Portable Executable and Common ObjectFile Format Specification: Revision 10:


Offset
Size
Field
Description
  0
8
Name
An 8-byte, null-padded UTF-8 encoded string. If the string is exactly 8 characters long, there is no terminating null. For longer names, this field contains a slash (/) that is followed by an ASCII representation of a   decimal number that is an offset into the string table. Executable images do not use a string table and do not support section names longer than 8 characters. Long names in object files are truncated if they are emitted to an executable file.
  8
4
VirtualSize
The total size of the section when loaded into memory. If this value is greater than SizeOfRawData, the section is zero-padded. This field is valid only for executable images and should be set to zero for object files.
12
4
VirtualAddress
For executable images, the address of the first byte of the section relative to the image base when the section is loaded into memory. For object files, this field is the address of the first byte before relocation is applied; for simplicity, compilers should set this to zero. Otherwise, it is an arbitrary value that is subtracted from offsets during relocation.
16
4
SizeOfRawData
The size of the section (for object files) or the size of the initialized data on disk (for image files). For executable images, this must be a multiple of FileAlignment from the optional header. If this is less than VirtualSize, the remainder of the section is zero-filled. Because the SizeOfRawData field is rounded but the VirtualSize field is not, it is possible for SizeOfRawData to be greater than VirtualSize as well. When a section contains only uninitialized data, this field should be zero.
20
4
PointerToRawData
The file pointer to the first page of the section within the COFF file. For executable images, this must be a multiple of FileAlignment from the optional header. For object files, the value should be aligned on a 4‑byte boundary for best performance. When a section contains only uninitialized data, this field should be zero.
24
4
PointerToRelocations
The file pointer to the beginning of relocation entries for the section. This is set to zero for executable images or if there are no relocations.
28
4
PointerToLinenumbers
The file pointer to the beginning of line-number entries for the section. This is set to zero if there are no COFF line numbers. This value should be zero for an image because COFF debugging information is deprecated.
32
2
NumberOfRelocations
The number of relocation entries for the section. This is set to zero for executable images.
34
2
NumberOfLinenumbers
The number of line-number entries for the section. This value should be zero for an image because COFF debugging information is deprecated.
36
4
Characteristics
The flags that describe the characteristics of the section. For more information, see section 4.1, “Section Flags.”


In the last post we dissected the .rsrc section header.  We will pick up where we left off on the Command Line image:

D:\Source\HelloWorld\CommandLine>PrintBinaryFile.exe HelloWorld_CSC_2.0.exe
000001C0   00 00 00 00 40 00 00 40  2E 72 65 6C 6F 63 00 00   ····@··@.reloc··
000001D0   0C 00 00 00 00 60 00 00  00 02 00 00 00 0A 00 00   ·····`··········
000001E0   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 42   ············@··B

Starting with the Name which is stored in a word using UTF-8 encoding we see that value stored is .reloc .  Next is the VirtualSize which is a half-word containing 0x0000000C or 13 bytes.  Next is the VirtualAddress half-word containing 0x00006000 and the half-word for SizeOfRawData containing 0x00000200.  The PointerToRawData half-word contains 0x00000A00 and the PointerToRelocations half-word contains 0x00.  The PointerToLinenumbers is just taking up space as a half-word of 0x00 and the NumberOfRelocations and NumberOfLinenumbers are equally bland two bytes each as 0x00.  The last element is Characteristics which is a half word containing a new value for us as 0x42000040 which translates to IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ.

As before, there are only a couple of differences in the Xamarin:

D:\Source\HelloWorld\CommandLine>PrintBinaryFile.exe HelloWorld_Xamarin_2.0.exe
000001C0   00 00 00 00 40 00 00 40  2E 72 65 6C 6F 63 00 00   ····@··@.reloc··
000001D0   0C 00 00 00 00 60 00 00  00 02 00 00 00 0C 00 00   ·····`··········
000001E0   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 42   ············@··B

and the Visual Studio:

D:\Source\HelloWorld\CommandLine>PrintBinaryFile.exe HelloWorld_VS_2.0.exe
000001C0   00 00 00 00 40 00 00 40  2E 72 65 6C 6F 63 00 00   ····@··@.reloc··
000001D0   0C 00 00 00 00 60 00 00  00 02 00 00 00 12 00 00   ·····`··········
000001E0   00 00 00 00 00 00 00 00  00 00 00 00 40 00 00 42   ············@··B

data and that from the Command line.  This time they are only the PointerToRawData.  Well, that is it for the section headers.  The next line in all three files is a snappy looking blank:

000001F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················

Not what I was expecting!  But that is because I was mistaken earlier. :-(  I was looking at the wrong value to determine how many sections we have.  I was using NumberOfRvaAndSizes which is silly since there is actually a NumberOfSections that we found back in Part 3.  To make it even sillier, I originally transcribed the number from the binary file incorrectly stating that there were 30 sections when really there are only 3.  What is really cool is that we are about to get to actual data that is described by the headers we have been pulling.  Way back in Part 7 we decoded the PointerToRawData of the .text section as 0x200, and that is the next line in our file.  So the above blank line was padding to get us in alignment.

See you next time!  Keep coding!


No comments:

Post a Comment