TypeSpec元数据表中的恶意条目

Bar*_*nes 5 .net clr metadata

我有一个.NET库,我试图更多地了解.NET的内部工作原理.所以我将通过ECMA-335规范并使用CFF Explorer VII.

我的问题是,在TypeSpec表中,Signature是Blob堆的索引,应该是TypeSpec签名,如第23.2.14节所述.这意味着它可以是PTR,FNPTR,ARRAY,SZARRAY,GENERICINSTANCE(ELEMENT_TYPE_为简洁起见而删除).

但是,我在这个TypeSpec表中有两个条目,它们似乎没有被元数据中的任何其他表引用,并且类型为VAR 0x13和MVAR 0x1e.

该程序集在VS2010中针对.NET 4进行编译.

ECMA-335会让我相信这是一个错误,但它是使用MS C#编译器编译的.

有谁知道它们是什么,它们是什么意思?

更新:

经过大量的乱码后,这段代码在TypeSpec表中创建了这两个条目.

public class AllOutputTypesClass<T> {
    public void GenericMethod<N>(N anItem) {
        string s = anItem.ToString();
    }

    public string GenericMethod<N>(T anItem, N secondItem) {
        return anItem.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*ley 2

如果您使用 ILDasm,您可以获得方法的详细分类,转到“查看”->“元信息”-> 选择“更多十六进制”。然后转到查看 -> 元信息 -> 显示!

这是第二种方法的细分:

    Method #2 (06000002) 
-------------------------------------------------------
    MethodName: GenericMethod (06000002)
    Flags     : [Public] [HideBySig] [ReuseSlot]  (00000086)
    RVA       : 0x0000206c
    ImplFlags : [IL] [Managed]  (00000000)
    CallCnvntn: [DEFAULT]
    hasThis 
    generic 
    Type Arity:1 
    ReturnType: String
    2 Arguments
        Argument #1:  Var!0
        Argument #2:  MVar!!0
    Signature : 30 01 02 0e 13 00 1e 00 
    1 Generic Parameters
        (0) GenericParamToken : (2a000003) Name : N flags: 00000000 Owner: 06000002
    2 Parameters
        (1) ParamToken : (08000002) Name : anItem flags: [none] (00000000)
        (2) ParamToken : (08000003) Name : secondItem flags: [none] (00000000)
Run Code Online (Sandbox Code Playgroud)

如果进一步向下滚动,您还会看到 TypeSpec 表条目。

类型规格 #1 (1b000001)

TypeSpec : MVar!!0
Signature: 1e 00 
Run Code Online (Sandbox Code Playgroud)

类型规格 #2 (1b000002)

TypeSpec : Var!0
Signature: 13 00 
Run Code Online (Sandbox Code Playgroud)

ILdasm 上面显示的是 VAR (13 00) 是在类级别传递的通用 !T(类型定义中的通用参数),而 MVAR (1e 00) 是在方法级别传递的通用 !!N(类型定义中的通用参数)方法定义)。

然而...您已经知道了很多,Orion 已经为您提供了答案 - TypeSpec 表中的条目正在 IL 中使用。一个条目用于一种方法,另一个条目用于另一种方法。当您查看这些方法时,您可以在 ILdasm 中看到这一点:

    .method /*06000001*/ public hidebysig instance void 
        'GenericMethod'<'N'>(!!'N' 'anItem') cil managed
// SIG: 30 01 01 01 1E 00
{
  // Method begins at RVA 0x2050
  // Code size       16 (0x10)
  .maxstack  1
  .locals /*11000001*/ init ([0] string 's')
  IL_0000:  /* 00   |                  */ nop
  IL_0001:  /* 0F   | 01               */ ldarga.s   'anItem'
  IL_0003:  /* FE16 | (1B)000001       */ constrained. !!'N'/*1B000001*/
  IL_0009:  /* 6F   | (0A)000011       */ callvirt   instance string ['mscorlib'/*23000001*/]'System'.'Object'/*01000001*/::'ToString'() /* 0A000011 */
  IL_000e:  /* 0A   |                  */ stloc.0
  IL_000f:  /* 2A   |                  */ ret
} // end of method 'AllOutputTypesClass`1'::'GenericMethod'
Run Code Online (Sandbox Code Playgroud)

.method /*06000002*/ public hidebysig instance string 
        'GenericMethod'<'N'>(!'T' 'anItem',
                             !!'N' 'secondItem') cil managed
// SIG: 30 01 02 0E 13 00 1E 00
{
  // Method begins at RVA 0x206c
  // Code size       19 (0x13)
  .maxstack  1
  .locals /*11000001*/ init ([0] string 'CS$1$0000')
  IL_0000:  /* 00   |                  */ nop
  IL_0001:  /* 0F   | 01               */ ldarga.s   'anItem'
  IL_0003:  /* FE16 | (1B)000002       */ constrained. !'T'/*1B000002*/
  IL_0009:  /* 6F   | (0A)000011       */ callvirt   instance string ['mscorlib'/*23000001*/]'System'.'Object'/*01000001*/::'ToString'() /* 0A000011 */
  IL_000e:  /* 0A   |                  */ stloc.0
  IL_000f:  /* 2B   | 00               */ br.s       IL_0011
  IL_0011:  /* 06   |                  */ ldloc.0
  IL_0012:  /* 2A   |                  */ ret
} // end of method 'AllOutputTypesClass`1'::'GenericMethod'
Run Code Online (Sandbox Code Playgroud)

0x1b 表是 TypeSpec,因此上述方法中的以下几行显示了您想知道的 2 行的用法:

  IL_0003:  /* FE16 | (1B)000001       */ constrained. !!'N'/*1B000001*/
Run Code Online (Sandbox Code Playgroud)

IL_0003:  /* FE16 | (1B)000002       */ constrained. !'T'/*1B000002*/
Run Code Online (Sandbox Code Playgroud)