与反编译 native x86 二进制文件相比,为什么将 .NET IL 代码反编译为源代码如此容易? (Reflector 大多数时候都会生成相当好的源代码,而反编译 C++ 编译器的输出几乎是不可能的。)
是因为IL包含大量元数据吗?或者是因为 IL 是比 x86 指令更高的抽象?我做了一些研究,发现了以下两篇有用的文章,但它们都没有回答我的问题。
最佳答案
我认为您已经掌握了最重要的部分。
- 正如您所说,有更多元数据可用。我不知道 C 或 C++ 编译器发出的内容的详细信息,但我怀疑 IL 中包含更多的名称和类似信息。只需查看反编译器对特定堆栈帧中内容的了解,例如 - 就 x86 而言,您只知道堆栈如何使用;在 IL 中,您知道堆栈的内容代表什么(或者至少知道类型 - 而不是语义含义!)
- 正如您已经提到的,IL 是比 x86 更高级别的抽象。 x86 不知道什么是方法或函数调用、事件或属性等。IL 中仍然包含所有这些信息。
- 通常,C 和 C++ 编译器的优化程度比(例如)C# 编译器要高得多。这是因为 C# 编译器假定大部分优化仍可以稍后通过 JIT 执行。在某些方面,C# 编译器尝试进行大量优化是有意义的,因为有各种信息可供 JIT 使用,但 C# 编译器无法使用。优化后的代码更难反编译,因为它与原始源代码的自然表示相去甚远。
- IL 被设计为 JIT 编译; x86 被设计为本地执行(诚然是通过微代码)。 JIT 编译器所需的信息与反编译器所需的信息类似,因此反编译器可以更轻松地使用 IL。在某些方面,这实际上只是对第二点的重申。
关于.net - 为什么反编译 .NET IL 代码如此容易?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/671407/