Buy Me a Coffee

Buy Me a Coffee!

Saturday, January 14, 2017

Dissecting C# Executables: Part 10

Ok, now we get to some interesting parts.  The .text region contains the CLR header, the metadata, the IL code, and managed resources and exception handling.  This is where the actual code is put by the IL assembler.  We have run out of the general PECOFF file and entered managed code land, so we need a new reference to help us understand what is going on.  I am going to be using the wonderful Apress book:
.NET IL Assembler
by Serge LidinPublished by Apress, 2014ISBN: 9781430267607
for the structure.  The link above is for the Safari version, the Amazon version is at .NET IL Assembler if you are looking for a dead tree version.  For the IL Opcodes I am going to be relying on Wikipedia: List of CIL instructions.  Ok, let's get started by looking at the smallest of the three, which is not really very small.  From back in Part 7 we know that for the Command Line version of the file, the .text section starts at 0x200 and has a size of 0x400.  Below is the whole listing for the section:

D:\Source\HelloWorld\CommandLine>PrintBinaryFile.exe HelloWorld_CSC_2.0.exe00000200   90 23 00 00 00 00 00 00  48 00 00 00 02 00 05 00   ?#······H·······00000210   70 20 00 00 EC 02 00 00  01 00 00 00 01 00 00 06   p ··ì···········00000220   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000230   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000240   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000250   56 72 01 00 00 70 28 03  00 00 0A 28 04 00 00 0A   Vr···p(····(····00000260   28 05 00 00 0A 2A 1E 02  28 06 00 00 0A 2A 00 00   (····*··(····*··00000270   42 53 4A 42 01 00 01 00  00 00 00 00 0C 00 00 00   BSJB············00000280   76 32 2E 30 2E 35 30 37  32 37 00 00 00 00 05 00   v2.0.50727······00000290   6C 00 00 00 04 01 00 00  23 7E 00 00 70 01 00 00   l·······#~··p···000002A0   00 01 00 00 23 53 74 72  69 6E 67 73 00 00 00 00   ····#Strings····000002B0   70 02 00 00 1C 00 00 00  23 55 53 00 8C 02 00 00   p·······#US·?···000002C0   10 00 00 00 23 47 55 49  44 00 00 00 9C 02 00 00   ····#GUID···?···000002D0   50 00 00 00 23 42 6C 6F  62 00 00 00 00 00 00 00   P···#Blob·······000002E0   02 00 00 01 47 15 00 00  09 00 00 00 00 FA 01 33   ····G········ú·3000002F0   00 16 00 00 01 00 00 00  06 00 00 00 02 00 00 00   ················00000300   02 00 00 00 01 00 00 00  06 00 00 00 02 00 00 00   ················00000310   01 00 00 00 01 00 00 00  00 00 0A 00 01 00 00 00   ················00000320   00 00 06 00 44 00 3D 00  06 00 76 00 56 00 06 00   ····D·=···v·V···00000330   96 00 56 00 06 00 CC 00  3D 00 06 00 DE 00 3D 00   ?·V···I·=···_·=·00000340   06 00 EA 00 3D 00 00 00  00 00 01 00 00 00 00 00   ··ê·=···········00000350   01 00 01 00 00 00 10 00  21 00 29 00 05 00 01 00   ········!·)·····00000360   01 00 50 20 00 00 00 00  91 00 4B 00 0A 00 01 00   ··P ····?·K·····00000370   66 20 00 00 00 00 86 18  50 00 10 00 02 00 00 00   f ····?·P·······00000380   01 00 C7 00 11 00 50 00  14 00 19 00 50 00 10 00   ··Ç···P·····P···00000390   21 00 D4 00 19 00 29 00  F2 00 1E 00 21 00 D4 00   !·O···)·ò···!·O·000003A0   23 00 09 00 50 00 10 00  2E 00 0B 00 28 00 2E 00   #···P···.···(·.·000003B0   13 00 31 00 04 80 00 00  00 00 00 00 00 00 00 00   ··1··?··········000003C0   00 00 00 00 00 00 B4 00  00 00 02 00 00 00 00 00   ······'·········000003D0   00 00 00 00 00 00 01 00  34 00 00 00 00 00 00 00   ········4·······000003E0   00 3C 4D 6F 64 75 6C 65  3E 00 48 65 6C 6C 6F 57   ·<Module>·HelloW000003F0   6F 72 6C 64 5F 43 53 43  5F 32 2E 30 2E 65 78 65   orld_CSC_2.0.exe00000400   00 50 72 6F 67 72 61 6D  00 48 65 6C 6C 6F 57 6F   ·Program·HelloWo00000410   72 6C 64 00 6D 73 63 6F  72 6C 69 62 00 53 79 73   rld·mscorlib·Sys00000420   74 65 6D 00 4F 62 6A 65  63 74 00 4D 61 69 6E 00   tem·Object·Main·00000430   2E 63 74 6F 72 00 53 79  73 74 65 6D 2E 52 75 6E   .ctor·System.Run00000440   74 69 6D 65 2E 43 6F 6D  70 69 6C 65 72 53 65 72   time.CompilerSer00000450   76 69 63 65 73 00 43 6F  6D 70 69 6C 61 74 69 6F   vices·Compilatio00000460   6E 52 65 6C 61 78 61 74  69 6F 6E 73 41 74 74 72   nRelaxationsAttr00000470   69 62 75 74 65 00 52 75  6E 74 69 6D 65 43 6F 6D   ibute·RuntimeCom00000480   70 61 74 69 62 69 6C 69  74 79 41 74 74 72 69 62   patibilityAttrib00000490   75 74 65 00 48 65 6C 6C  6F 57 6F 72 6C 64 5F 43   ute·HelloWorld_C000004A0   53 43 5F 32 2E 30 00 61  72 67 73 00 43 6F 6E 73   SC_2.0·args·Cons000004B0   6F 6C 65 00 57 72 69 74  65 4C 69 6E 65 00 45 6E   ole·WriteLine·En000004C0   76 69 72 6F 6E 6D 65 6E  74 00 56 65 72 73 69 6F   vironment·Versio000004D0   6E 00 67 65 74 5F 56 65  72 73 69 6F 6E 00 00 00   n·get_Version···000004E0   00 17 48 00 65 00 6C 00  6C 00 6F 00 20 00 57 00   ··H·e·l·l·o· ·W·000004F0   6F 00 72 00 6C 00 64 00  00 00 00 00 DF 13 F8 01   o·r·l·d·····ß·o·00000500   D0 37 28 48 85 DA 41 FE  20 41 22 3B 00 08 B7 7A   D7(H?UA_ A";···z00000510   5C 56 19 34 E0 89 05 00  01 01 1D 0E 03 20 00 01   \V·4à?······· ··00000520   04 20 01 01 08 04 00 01  01 0E 04 00 00 12 19 04   · ··············00000530   00 01 01 1C 08 01 00 08  00 00 00 00 00 1E 01 00   ················00000540   01 00 54 02 16 57 72 61  70 4E 6F 6E 45 78 63 65   ··T··WrapNonExce00000550   70 74 69 6F 6E 54 68 72  6F 77 73 01 84 23 00 00   ptionThrows·?#··00000560   00 00 00 00 00 00 00 00  9E 23 00 00 00 20 00 00   ········?#··· ··00000570   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000580   00 00 00 00 90 23 00 00  00 00 00 00 00 00 00 00   ····?#··········00000590   00 00 5F 43 6F 72 45 78  65 4D 61 69 6E 00 6D 73   ··_CorExeMain·ms000005A0   63 6F 72 65 65 2E 64 6C  6C 00 00 00 00 00 FF 25   coree.dll·····ÿ%000005B0   00 20 40 00 00 00 00 00  00 00 00 00 00 00 00 00   · @·············000005C0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················000005D0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················000005E0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················000005F0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················
It looks a bit intimating, but even a cursory glance shows us a bunch of text that we can read.  It doesn't look like the disassembled code we saw earlier, but that is ok.  The IL is stored in a binary form which is why we will need the Opcodes to figure out what it actually says.  
The structure of the .text section is:

Section
Description
Import Address Table
The size of this section is defined by the IAT value from the Data Directories section.  It contains the entry point for the CLR.
CLR Header
Header
Strong Name Signature Hash (optional)
The signature for a strongly named assembly is stored here.  It is a hash of the prime module encrypted with the assembly publisher's private key.
IL Code and Managed Structure Exception Handling Table (Optional)
This contains the method table which contains pointers to exceptions handling methods.
Debug Directory (Optional)
Contains the path to the PDB file if applicable.
Metadata
A table which contains the Managed Metadata, a set of named streams representing the different types of metadata.
Managed Resources (Optional)
A table containing managed resources.
Unmanaged Export Stubs (Optional)
Export stubs for managed methods that are exposed as unmanaged exports.  Contains references to the v-table slots allocated for the methods.
VTFixup Table (Optional)
Defines the entries and slots in the v-table as number and width of slots in each entry.
CLR Startup Stub
A stub for the runtime startup.

Ok, the first part is the Import Address Table which contains the entry point to the CLR.  How big is it?  We have to look back in the Data Directories in Part 6 and find the IAT value (so now we know what IAT stands for!).  In all three images, we have the same value: 0x0000000800002000 which is actually not written correctly given what we now know.  The actual line looks like this:
00000150   00 00 00 00 00 00 00 00  00 20 00 00 08 00 00 00   ········· ······


which gives us a VirtualAddress (though the book notes that this is actually an RVA) of 0x00002000 and a Size of 0x00000008.  For now, the size is all we need.  That means that this line:
00000200   90 23 00 00 00 00 00 00  48 00 00 00 02 00 05 00   ?#······H·······


gives us the Import Address Table value of 0x0000000000002390.
The next part of the .text section is the CLR Header.  It's structure is:
Offset
Size
Field
Description
0
4
CB
Size of the header in bytes.
4
2
MajorRuntimeVersion
Major version of the minimum version of the runtime required to run the program.
6
2
MinorRuntimeVersion
Minor version of the minimum version of the runtime required to run the program.
8
8
MetaData
RVA and size of the metadata.
16
4
Flags
Binary flags describing the type of image stored in the program and information about it.  The flag field decoding table is below.
20
4
EntryPointToken/EntryPointRVA
Metadata identifier (token) of the entry point for the image file; can be 0 for DLL images.  May contain the RVA of the embedded native entry point method.
24
8
Resources
RVA and size of managed resources.
32
8
StrongNameSignature
RVA and size of the hash data for this PE file, used by the loader for binding and versioning.
40
8
CodeManagerTable
RVA and size of the Code Manager Table.  Currently reserved and must be set to 0.
48
8
VTableFixups
RVA and size in bytes of an array of virtual table (v-table) fixups. Currently, only VC++ linker and the IL assembler can product this array.
56
8
ExportAddressTableJumps
Obsolete and must be set to 0 for CLR versions 2.0+.
64
8
ManagedNativeHeader
Reserved for Precompiled images; set to 0.

and the data for it is:
00000200   90 23 00 00 00 00 00 00  48 00 00 00 02 00 05 00   ?#······H·······00000210   70 20 00 00 EC 02 00 00  01 00 00 00 01 00 00 06   p ··ì···········00000220   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000230   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················00000240   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ················
It is also variable in length, so we need more information again?  In the above table, the size looks pretty solid, but the header size allows for future versions to override or extend this header.  This time, the first half-word is the Cb which contains the size of the header in bytes.  In this case the Cb contains the value 0x00000048 or 72, which matches the table above perfectly.  
Next is the MajorRuntimeVersion and MinorRuntimeVersion which are both two bytes and contain 0x0002 and 0x0005 respectively.  Following that, we have the word MetaData which is made up of the half-word MetaData RVA and MetaData Size which are 0x00002070 and 0x000002EC respectively.   Next is the Flags half-word which contains 0x00000001 which decodes to COMIMAGE_FLAGS_ILONLY.  This means that the image file contains IL only, except for the tiny bit in the CLR startup and MSDOS header.  Next we have the EntryPointToken/EntryPointRVA half which is 0x06000001.  Next is the Resources table entry which is a word and contains the Resources RVA and Resources Size of the managed resources table which is 0x00 and 0x00 respectively.  Next is the StrongNameSignature field which contains the StrongNameSignature RVA and StrongNameSignature Size half-words which are also 0x00 and 0x00.  Next is the CodeManagerTable word entry which contains the CodeManagerTable RVA and CodeManagerTable Size half-word values which are both 0x00.  Next is the VTableFixups word, broken into the VTableFixups RVA and VTableFixups Size half-word values which are also 0x00.  The ExportAddressTableJumps word is next and is obsolete and set to 0x00.  And lastly, the ManagedNativeHeader value is a word and set to 0x00.
That wraps up the CLR Header, and our visit for today.  We will pick up with the next section tomorrow.  I believe it will be the IL Code and Managed Structure Exception Handling Table, but we will have to track it down and see.  Happy Coding, and keep digging in!