【问题标题】:Programmatically disassemble CIL以编程方式反汇编 CIL
【发布时间】:2012-03-04 10:44:40
【问题描述】:

我可以将指令编译为字节码,甚至可以轻松执行它们,但我发现提取 CIL 的唯一函数是 GetILAsByteArray,顾名思义,它只返回字节而不是 CIL 指令。

那么如何在 .NET 上以编程方式反汇编 CIL?

请注意,我不希望结果为人类可读的形式。我想编写元程序来操作从其他程序生成的 CIL。

【问题讨论】:

  • 正如@JohnPalmer 在他的回答中建议的那样,Mono.Cecil 是一个不错的选择。 Here 是一个很好的博客,讨论 IL 重写可能会有所帮助。

标签: c# .net f# metaprogramming


【解决方案1】:

Mono Cecil 库 - http://www.mono-project.com/Cecil 应该可以满足您的需求,我知道它至少用于一个 .Net 分析器

【讨论】:

【解决方案2】:

您可以仅使用GetILAsByteArray 方法中的字节数组,但您需要自己编写字节解析(如果您不想依赖第 3 方库)。

数组的结构是有一个或两个字节标识指令,后跟指令的操作数(或者什么都没有,一些 4 字节的令牌或 8 字节的数字)。

要获取代码,您可以查看System.Reflection.Emit 中的OpCodes 结构(MSDN)。如果您枚举所有字段,您可以很容易地构建一个查找表来读取字节:

// Iterate over all byte codes to build lookup table
for fld in typeof<OpCodes>.GetFields() do
  let code = fld.GetValue(null) :?> OpCode
  printfn "%A (%d + %A)" code.Name code.Size code.OperandType

code.Value 属性为您提供代码的 byte 或 int16 值。 code.Size 属性告诉您这是 1 字节代码还是 2 字节代码,OperandType 属性指定代码后面的参数(字节数和含义是 explained on MSDN)。我不记得你究竟需要如何处理诸如引用 MethodInfo 的令牌之类的东西,但我想你能弄清楚这一点!

【讨论】:

    【解决方案3】:

    我对@9​​87654321@ 项目进行了一些 IL 操作。这是非常简单的 API。

    【讨论】:

      【解决方案4】:

      使用 Cecil 的一个有趣的替代方法是恢复 AbsIL 项目。 Cecil 写得很好,用得很好,但如果你用 F# 编写它,这可能不是你解决问题的方式。 AbsIL 是一个与 F# 同时启动的项目,允许 OCaml 和 F# 读写 IL,它已被 F# 项目取代,现在只是 F# 编译器的后端。然而,读写 IL 的代码仍然存在,理论上可以从 F# 编译器中分离出来,并自行制作成可用的库。将 AbsIL 代码与 F# 编译器的其余部分分开并不是一件容易的事,但如果您有一点空闲时间和一定的决心,应该是可能的。如果你真的很勇敢,你可能还想看看交叉编译到 OCaml。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-06
        • 2018-09-22
        • 2010-11-09
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多