Get type stored in binary field signature

165 Views Asked by At

Suppose you have a binary representation of a field signature in a .NET module, like 0604. The 6 (FIELD) represents the field calling convention and the 4 (ELEMENT_TYPE_I1) represents the I1 primitive type (see ECMA-335 for more on CIL). The signature can be from a debugger or assembly inspector, that is not important. What's more important, is it possible (using methods provided by .NET) to "parse" this signature and get the corresponding .NET type that the signature is representing?

Examples:

0601System.Void
0604System.SByte
060ESystem.String
061408020000System.Int32[,]

2

There are 2 best solutions below

0
On BEST ANSWER

There are some internal .NET methods that can do that:

public static unsafe Type GetTypeFromFieldSignature(byte[] signature, Type declaringType = null)
{
    declaringType = declaringType ?? typeof(object);
    Type sigtype = typeof(Type).Module.GetType("System.Signature");
    Type rtype = typeof(Type).Module.GetType("System.RuntimeType");
    var ctor = sigtype.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[]{typeof(void*), typeof(int), rtype}, null);
    fixed(byte* ptr = signature)
    {
        object sigobj = ctor.Invoke(new object[]{(IntPtr)ptr, signature.Length, declaringType});
        return (Type)sigtype.InvokeMember("FieldType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, sigobj, null);
    }
}

This loads any valid field signature and returns the appropriate type.

0
On

I don't know about any public API that can do this, but Cecil can parse this kind of signature internally, so you might be able to copy its code.

The relevant code is in SignatureReader.ReadTypeSignature().

Or maybe don't try to parse the assembly by yourself and use Cecil for that.