You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CIL中解码call指令的元数据令牌?

解码CIL call指令中的元数据令牌

别担心,这部分内容确实需要深挖ECMA-335的细节才能搞明白,我给你一步步拆解清楚:

元数据令牌的通用结构

所有.NET元数据令牌都是4字节的数值,结构非常固定:

  • 最高1字节:表示令牌对应的元数据表类型(比如MethodDef、MethodRef这些)
  • 低3字节:表示该表中的行号(注意:行号从1开始计数,不是0)

call指令支持的三种令牌类型详解

根据ECMA-335的定义,call指令的操作数可以是methodref、methoddef或methodspec类型的令牌,对应的表标识和含义如下:

1. MethodDef令牌(标识:0x06)

  • 对应元数据中的MethodDef表,用来指向当前程序集内定义的方法
  • 示例:令牌0x06000003 → 最高字节0x06表示MethodDef表,低3字节0x000003表示表中第3行的方法

2. MethodRef令牌(标识:0x0A)

  • 对应元数据中的MethodRef表,用来指向其他程序集里的方法(或当前程序集里的父类方法)
  • 示例:令牌0x0A000007 → 最高字节0x0A表示MethodRef表,低3字节0x000007表示表中第7行的方法引用

3. MethodSpec令牌(标识:0x11)

  • 对应元数据中的MethodSpec表,用来指向泛型方法的实例化版本(比如List<int>.Add这种具体的泛型方法)
  • 示例:令牌0x11000002 → 最高字节0x11表示MethodSpec表,低3字节0x000002表示表中第2行的泛型方法实例

怎么在实际CIL中验证?

你可以用ildasm工具来直观查看:

  1. 打开目标程序集,双击要查看的方法进入CIL视图
  2. 右键点击窗口,选择「Show Bytes」,就能看到call指令的原始字节码
    • call指令的操作码是0x28,后面紧跟4字节的元数据令牌
    • 比如你看到字节序列0x28 0x0A 0x00 0x00 0x05,那0x0A000005就是对应的MethodRef令牌

ECMA-335里的参考章节

其实这些细节都在ECMA-335文档里:

  • Partition II 第24.2.1节:元数据令牌的通用结构定义
  • Partition II 第22章:所有元数据表的详细定义(包括MethodDef、MethodRef、MethodSpec)
  • Partition II 第23.2.1节:call指令的操作数规范

内容的提问来源于stack exchange,提问作者tairqammar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:17:30