以编程方式反汇编 CIL
我可以将指令编译为字节码,甚至可以轻松执行它们,但我发现提取 CIL 的唯一函数是 GetILAsByteArray,顾名思义,它只返回字节而不是 CIL 指令。
那么如何以编程方式反汇编 .NET 上的 CIL?
请注意,我不希望结果采用人类可读的形式。我想编写元程序来操作其他程序生成的 CIL。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只需使用 GetILasByteArray 方法中的字节数组即可获得相当多的结果,但您需要自己编写字节解析(如果您不想依赖第 3 方库)。
数组的结构是,有一个或两个字节标识指令,后跟指令的操作数(要么什么也没有,要么是某个 4 字节令牌,要么是 8 字节数字)。
要获取代码,您可以查看
OpCodes
结构 (MSDN)来自System.Reflection.Emit
。如果枚举所有字段,则可以非常轻松地构建一个用于读取字节的查找表:code.Value
属性为您提供byte
或int16
代码的值。code.Size
属性告诉您这是 1 字节还是 2 字节代码,OperandType
属性指定代码后面跟随的参数(字节数和含义是 MSDN 上有解释)。我不记得您到底需要如何处理引用 ieMethodInfo
的令牌之类的东西,但我想您将能够弄清楚!You can get reasonably far just using the byte array from
GetILAsByteArray
method, but you'll need to write parsing of the bytes yourself (if you don't want to rely on 3rd party library).The structure of the array is that there is one or two bytes identifying the instruction followed by operands for the instruction (which is either nothing, some 4 byte token or a 8 byte number).
To get the codes, you can look at the
OpCodes
structure (MSDN) fromSystem.Reflection.Emit
. If you enumerate over all the fields, you can quite easily build a lookup table for reading of the bytes:The
code.Value
property gives you eithrebyte
orint16
value of the code. Thecode.Size
property tells you whether this is 1 or 2 byte code andOperandType
property specifies what arguments follow the code (the number of bytes and the meaning is explained on MSDN). I don't remember how exactly you need to process things like tokens that refer to i.e.MethodInfo
, but I guess you'll be able to figure that out!Mono Cecil 库 - http://www.mono-project.com/Cecil 应该做什么你需要,我知道它至少在一个 .Net 分析器中使用
The Mono Cecil library - http://www.mono-project.com/Cecil should do what you need, I know that it is used in at least one .Net profiler
使用 Cecil 的一个有趣的替代方案是复活 AbsIL 项目。 Cecil 写得很好并且使用得很好,但如果您用 F# 编写它,这可能不是您解决问题的方式。 AbsIL 是一个与 F# 同时启动的项目,允许 OCaml 和 F# 读写 IL,后来被 F# 项目接管,现在只是 F# 编译器的后端。然而,读取和写入 IL 的代码仍然存在,理论上可以与 F# 编译器分离,并以其本身的权限制作成可用的库。将 AbsIL 代码与 F# 编译器的其余部分分离并非完全微不足道,但如果您有一点空闲时间和一定的决心,应该是可能的。如果您真的很勇敢,您可能还想看看将其交叉编译为 OCaml。
One interesting alternative to using Cecil would be to resurrect the AbsIL project. Cecil well written and well used, but it probably isn't how you'd approach the problem if you were writing it in F#. AbsIL was a project started at the same time as F# to allow OCaml and F# to read and write IL, it's since been over taken as by the F# project and is now just the back end for the F# compiler. However the code to both read and write IL is still there and could in theory be separated from the F# compiler and made into usable library in it's own right. Separating the AbsIL code from the rest of the F# compiler is not completely trivial, but should be possible if you have a bit of spare time and a certain amount of determination. If you're feeling really brave you might also want to look at cross compiling it to OCaml.
我对 Mono Cecil 项目进行了一些 IL 操作。这是非常简单的 API。
I did some IL manipulation with Mono Cecil project. It's quite easy API.