以编程方式反汇编CIL

Jon*_*rop 11 .net c# f# metaprogramming

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

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

请注意,我不希望结果以人类可读的形式出现.我想编写元程序来操纵从其他程序生成的CIL.

Joh*_*mer 9

Mono Cecil库 - http://www.mono-project.com/Cecil应该做你需要的,我知道它至少用于一个.Net profiler

  • `Cecil`确实在[ILSpy]中使用(https://github.com/icsharpcode/ILSpy). (4认同)

Tom*_*cek 8

你可以合理地使用GetILAsByteArray方法中的字节数组,但是你需要自己编写字节的解析(如果你不想依赖第三方库).

数组的结构是有一个或两个字节标识指令的操作数后面的指令(无论是什么,一些4字节标记或8字节数).

要获取代码,您可以查看OpCodes结构(MSDN)System.Reflection.Emit.如果枚举所有字段,则可以非常轻松地构建查找表以读取字节:

// 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
Run Code Online (Sandbox Code Playgroud)

code.Value属性为您提供代码的eithre byteint16值.该code.Size属性告诉您这是1或2字节代码,OperandType属性指定代码后面的参数(字节数和含义在MSDN解释).我不记得你究竟需要如何处理像引用的标记那样的东西MethodInfo,但我想你能够弄清楚这一点!


Rob*_*ert 5

使用Cecil的一个有趣的替代方案是恢复AbsIL项目.塞西尔写得很好,使用得很好,但如果你用F#编写它,可能不是你如何处理问题.Absil是一个与F#同时启动的项目,允许OCaml和F#读写IL,它已经被F#项目所取代,现在只是F#编译器的后端.然而,读取和写入IL的代码仍然存在,并且理论上可以与F#编译器分离,并且可以自己制作成可用的库.将Absil代码与F#编译器的其余部分分开并不是完全无足轻重的,但如果您有一些空闲时间和一定的决心,则应该可以实现.如果你真的很勇敢,你可能也想看看交叉编译到OCaml.