Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different types have same signatures in CIL

Tags:

.net

cil

ildasm

I have one field defined in CIL like this:

.field public int32 modopt(void*) fld

I compile this to an assembly. Now I change it to:

.field public int32 modopt(int16) fld

Both how is it possible now, that ILDASM reports (when shown as hex) both those fields as this?

Field #1 (04000001)
-------------------------------------------------------
    Field Name: fld (04000001)
    Flags     : [Public]  (00000006)
    CallCnvntn: [FIELD]
    Field type:  CMOD_OPT 1b000001 I4
    Signature : 06 20 06 08 

This code looks for both fields exactly the same (actually I've created the second field to match the reported signature). The signature obviously matches the second field, but the signature of the first field should look like this: 06 20 0f 01 08! What am I missing here?

Edit:

C# cannot emit this type of field, throwing an exception about pointer and array types not supported for custom type modifiers, so this apparently solves the signature mismatch. But the question why ILDASM allows creating an invalid signature which it cannot decompile remains.

Edit #2:

It seems ILASM is actually creating correct IL, there is a difference in the hex dump I missed last time:

//the first assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
    TypeSpec : Ptr Void
    Signature: 0f 01 

//the second assembly
TypeSpec #1 (1b000001)
-------------------------------------------------------
    TypeSpec : I2
    Signature: 06 

So there is just a bug in ILDASM hex dump reporting wrong member signature (though I wonder where the 06 in the wrong signature came from).

like image 971
IS4 Avatar asked Jan 06 '15 20:01

IS4


1 Answers

Let's try to build the field signature manually based on the specification. To start, field signature is defined in §II.23.2.4. For our case with one custom modifier, it will be:

FIELD CustomMod Type

Since FIELD is defined as 0x06, we have:

06 CustomMod Type

Our custom modifier is modopt, so we get (based on §II.23.2.7):

06 CMOD_OPT TypeDefOrRefOrSpecEncoded Type

CMOD_OPT is 0x20 (§II.23.1.16):

06 20 TypeDefOrRefOrSpecEncoded Type

We want to reference TypeSpec 0x1b000001, which is encoded as 0b110 (10 for TypeSpec, 1 for 0x000001, §II.23.2.8). This is then "compressed" into the single byte 0x06 (§II.23.2):

06 20 06 Type

Finally, the type is int32, which is ELEMENT_TYPE_I4 = 0x08 (§II.23.2.12 and §II.23.1.16):

06 20 06 08

So we get exactly the same signature as the one shown in ILDasm.

like image 90
svick Avatar answered Oct 26 '22 16:10

svick