Example 2: Decoding a private field signature of a reference type declared in another assembly
This example is just as easy as last night's example 1, except this deals with the TypeRef table - which holds classes declared in other assemblies [usually].
C# code:
private StringBuilder sb = null;
The field's information from ILDasm:
0x06 is calling convention for a field (IMAGE_CEE_CS_CALLCONV_FIELD)
0x12 is ELEMENT_TYPE_CLASS for a class token
0x0d like example 1 is a TypeDefOrRef [signature] token.
0x0d, is a compressed integer of 13 (0x0d)
NOTE: As in example 1, since 0x0d is under 128, the compressed value is the same as the uncompressed value and only takes 1 byte to represent it.
Determine the table the type is in:
If you AND the uncompressed value with 0x03 you can determine which of the least 2 bits are on or off, in this case it will be 01 = TypeRef.
Get the index of the record in the table:
Bit shift 13 to the right 2 bits and you get 3 (0x03) (which is the index in the TypeRef table for the System.Text.StringBuilder record)
Calling Conventions
Taken from CorCallingConvention on line 837 of CorHdr.h - found in Windows Sdk includes directory
| IMAGE_CEE_CS_CALLCONV_DEFAULT |
0x0 |
|
| IMAGE_CEE_CS_CALLCONV_VARARG |
0x5 |
|
| IMAGE_CEE_CS_CALLCONV_FIELD |
0x6 |
|
| IMAGE_CEE_CS_CALLCONV_LOCAL_SIG |
0x7 |
|
| IMAGE_CEE_CS_CALLCONV_PROPERTY |
0x8 |
|
| IMAGE_CEE_CS_CALLCONV_UNMGD |
0x9 |
|
| IMAGE_CEE_CS_CALLCONV_GENERICINST |
0xa |
generic method instantiation |
| IMAGE_CEE_CS_CALLCONV_NATIVEVARARG |
0xb |
used ONLY for 64bit vararg PInvoke calls |
| IMAGE_CEE_CS_CALLCONV_MAX |
0xc |
first invalid calling convention |
| IMAGE_CEE_CS_CALLCONV_MASK |
0x0f |
Calling convention is bottom 4 bits |
| IMAGE_CEE_CS_CALLCONV_HASTHIS |
0x20 |
Top bit indicates a 'this' parameter |
| IMAGE_CEE_CS_CALLCONV_EXPLICITTHIS |
0x40 |
This parameter is explicitly in the signature |
| IMAGE_CEE_CS_CALLCONV_GENERIC |
0x10 |
Generic method sig with explicit number of type arguments (precedes ordinary parameter count) |
Element Types
Taken from CorElementType on line 774 of CorHdr.h - found in the Windows Sdk includes directory
| ELEMENT_TYPE_END |
0x0 |
|
| ELEMENT_TYPE_VOID |
0x1 |
|
| ELEMENT_TYPE_BOOLEAN |
0x2 |
|
| ELEMENT_TYPE_CHAR |
0x3 |
|
| ELEMENT_TYPE_I1 |
0x4 |
|
| ELEMENT_TYPE_U1 |
0x5 |
|
| ELEMENT_TYPE_I2 |
0x6 |
|
| ELEMENT_TYPE_U2 |
0x7 |
|
| ELEMENT_TYPE_I4 |
0x8 |
|
| ELEMENT_TYPE_U4 |
0x9 |
|
| ELEMENT_TYPE_I8 |
0xa |
|
| ELEMENT_TYPE_U8 |
0xb |
|
| ELEMENT_TYPE_R4 |
0xc |
|
| ELEMENT_TYPE_R8 |
0xd |
|
| ELEMENT_TYPE_STRING |
0xe |
|
| ELEMENT_TYPE_PTR |
0xf |
PTR |
| ELEMENT_TYPE_BYREF |
0x10 |
BYREF |
| ELEMENT_TYPE_VALUETYPE |
0x11 |
VALUETYPE |
| ELEMENT_TYPE_CLASS |
0x12 |
CLASS |
| ELEMENT_TYPE_VAR |
0x13 |
a class type variable VAR |
| ELEMENT_TYPE_ARRAY |
0x14 |
MDARRAY ... ... |
| ELEMENT_TYPE_GENERICINST |
0x15 |
GENERICINST ... |
| ELEMENT_TYPE_TYPEDBYREF |
0x16 |
TYPEDREF (it takes no args) a typed referece to some other type |
| ELEMENT_TYPE_I |
0x18 |
native integer size |
| ELEMENT_TYPE_U |
0x19 |
native unsigned integer size |
| ELEMENT_TYPE_FNPTR |
0x1B |
FNPTR |
| ELEMENT_TYPE_OBJECT |
0x1C |
Shortcut for System.Object |
| ELEMENT_TYPE_SZARRAY |
0x1D |
Shortcut for single dimension zero lower bound array SZARRAY |
| ELEMENT_TYPE_MVAR |
0x1e |
a method type variable MVAR |
| ELEMENT_TYPE_CMOD_REQD |
0x1F |
required C modifier : E_T_CMOD_REQD |
| ELEMENT_TYPE_CMOD_OPT |
0x20 |
optional C modifier : E_T_CMOD_OPT |
| ELEMENT_TYPE_INTERNAL |
0x21 |
INTERNAL |
| ELEMENT_TYPE_MAX |
0x22 |
first invalid element type |
| ELEMENT_TYPE_MODIFIER |
0x40 |
|
| ELEMENT_TYPE_SENTINEL |
0x01 | ELEMENT_TYPE_MODIFIER |
sentinel for varargs |
| ELEMENT_TYPE_PINNED |
0x05 | ELEMENT_TYPE_MODIFIER |
|
| ELEMENT_TYPE_R4_HFA |
0x06 | ELEMENT_TYPE_MODIFIER |
used only internally for R4 HFA types |
| ELEMENT_TYPE_R8_HFA |
0x07 | ELEMENT_TYPE_MODIFIER |
used only internally for R8 HFA types |
Next notes will provide:
- Compression/Decompression Algorithm
- Decoding a field that is a generic type