如何从CLR / winmd方法签名中获取方法参数类型

时间:2019-06-18 21:23:26

标签: winmd

短版

如何转换方法签名数据:

  • 发件人20 03 01 12 55 11 61 09
  • (IOutputStream, CompressAlgorithm, UInt32)

  • 发件人20 01 01 12 55
  • (IOutputStream)

背景

我正在查看Windows元数据(.winmd-.tlb的后继)。

我可以得到:

    • 方法
      • 参数

但是我不知道如何获得方法参数的类型

例如Windows.Storage.Compression.Compressor constructor方法具有3个参数:

//Windows.Storage.Compression.Compressor (@02000019)
public class Compressor 
{
    public Compressor(
          IntPtr underlyingStream, 
          IntPtr algorithm,     
          Intptr blockSize); // (@060000A0)
}

注意:该参数不是实际上 IntPtr。那是为了加强我不知道如何找出实际类型的问题。

元数据

Windows.Storage.Compression.Compressor 类的标识符为@20000019

.ctor方法的标识符为@060000A0

IMetadataImport.GetMethodProps方法返回有关该方法的信息:

  • 方法名称: ".ctor"
  • 属性: 0x00001886 (mdHideBySig,mdReuseSlot,mdSpecialName,mdPublic,mdRTSpecialName)
  • 二进制签名20 03 01 12 55 11 61 09
  • 代码RVA 0 (对于.winmd文件,为0,因为没有代码)
  • 实施标志:0

您会注意到20 03 01 12 55 11 61 09签名。 (我认为)这是该方法的编码参数的 number type

给出方法ID,然后可以使用IMetadataImport.EnumParams枚举方法参数列表。

您还可以挖掘WinMD数据库本身:

方法(表0x06)

- **Rid:** @060000A0
- **RVA (iULONG):** 0
- **ImplFlags (iUSHORT):** 0x0003
- **Flags (iUSHORT):** 0x1886
- **Name (iSTRING):** ".ctor"
- **Signature (iBLOB):** 20 03 01 12 55 11 61 09
- **ParamList (iRid (0x08)):** @080000B6

Param(表0x08)

| Rid       | Flags (iUSHORT) | Sequence (iUSHORT) | Name (iSTRING)   |
|-----------|-----------------|--------------------|------------------|
| @080000B6 | 0x0001          | 1                  | underlyingStream |
| @080000B7 | 0x0001          | 2                  | algorithm        |
| @080000B8 | 0x0001          | 3                  | blockSize        |

但是最终没有人返回参数类型的类型类型引用

解码方法签名

我唯一能想到的是类型是用二进制方法签名编码的。查看两个构造函数的签名:

20 01 01 12 55          : IOutputStream 
20 03 01 12 55 11 61 09 : IOutputStream, CompressAlgorithm, UInt32

第一个.ctor具有1个参数,第二个.ctor具有3个参数:

20 01 01 12 55           (one parameter)
20 03 01 12 55 11 61 09  (three parameters)
    ^
    |
    number of parameters?

因此可能会将其余数字保留为类型:

20   01   01 12 55           : IOutputStream 
20   03   01 12 55 11 61 09  : IOutputStream, CompressAlgorithm, UInt32
      ^
      |
      |
      number of parameters

.winmd本身具有三种引用类型中的两种:

  • IOutputStream @010000015
  • CompressAlgorithm @010000018

解码二进制签名

某人必须已经弄清楚了方法二进制签名意味着的含义。

以前,我可以decode the binary signature [GuidAttribute]

  • 发件人01 00 1D 22 30 CA D9 86 FB 40 A2 6B D4 4E B7 CF 08 EA 00 00
  • {CA30221D-86D9-40FB-A26B-D44EB7CF08EA}

在任何地方都没有记录。这只是一个幸运的猜测。

但是我必须假设这都记录在某处; (仅在回答此问题时),在有人回答后,在此页面上。 (而不是在没有解释的情况下对它进行投票-无肠的w夫)

奖励聊天

  

14.7 Plnvoke的方法签名

     

DefineMethod 的调用包含一个名为pvSig的参数,该参数采用   方法的签名。此Blob指定方法的签名-用于   每个参数,以及返回类型(如果有)。该Blob的格式已定义   下面。本节总结了专用于PInvoke的签名的详细信息:

     
      
  • 所有数据类型都必须是托管数据类型,即使它们最终会在   PInvoke调度,作为非托管函数的参数
  •   
  • PInvoke提供简单(非结构)的默认自动封送处理   参数,以及struct参数中的简单字段。选择默认值   使用有关托管数据类型声明,目标平台和   方法级别的ansi / unicode / auto属性。 (如果需要,可以覆盖此默认封送处理-请参见 SetFieldMarshal
  •   
  • 在方法签名中,应将struct参数声明为承载布局信息的CLR类或值类型(我们在此将其称为“格式化类型”   上面的讨论)。
  •   

0 个答案:

没有答案