我可以将指令编译成字节码,甚至可以很容易地执行它们,但我找到的唯一提取CIL的函数是GetILAsByteArray,顾名思义,它只返回字节,而不返回CIL指令。
那么如何在.NET上以编程方式反汇编CIL呢?
请注意,我不希望结果以人类可读的形式出现。我想编写元程序来操作从其他程序生成的CIL。
发布于 2012-02-13 07:43:04
你可以使用GetILAsByteArray方法中的字节数组,但是你需要自己编写字节解析(如果你不想依赖第三方库的话)。
数组的结构是有一个或两个字节来标识指令,后面跟着指令的操作数(它或者是nothing,或者是某个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.OperandTypecode.Value属性提供代码的byte或int16值。code.Size属性告诉您这是1个字节的代码还是2个字节的代码,OperandType属性指定代码后面的参数(字节数和含义为explained on MSDN)。我不记得你到底需要如何处理像引用MethodInfo的令牌这样的东西,但我猜你会弄明白的!
发布于 2012-02-13 07:18:13
Mono Cecil库- http://www.mono-project.com/Cecil应该可以满足您的需求,我知道至少有一个.Net分析器使用了它
发布于 2012-02-13 17:01:47
使用Cecil的一个有趣的替代方案是重新启动AbsIL项目。Cecil写得很好,使用得也很好,但如果你用F#写它,你可能不会用它来解决这个问题。AbsIL是一个与F#同时启动的项目,允许OCaml和F#读写IL,后来被F#项目接管,现在只是F#编译器的后端。然而,读写IL的代码仍然存在,理论上可以从F#编译器中分离出来,并以其自身的权限成为可用的库。将AbsIL代码与F#编译器的其余部分分开并不是轻而易举的事情,但如果您有一点空闲时间和一定的决心,应该是可以做到的。如果你觉得自己真的很勇敢,你可能还想看看把它交叉编译成OCaml。
https://stackoverflow.com/questions/9253622
复制相似问题