.NET IL Assembler
Published 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 ········· ······
00000200 90 23 00 00 00 00 00 00 48 00 00 00 02 00 05 00 ?#······H·······
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!