.net - 为什么反编译.NET IL代码这么容易?

与将本机x86二进制文件反编译相比,为什么将.NET IL代码反编译为源代码这么容易? (Reflector在大多数情况下会生成相当不错的源代码,而对C ++编译器的输出进行反编译几乎是不可能的。)

是因为IL包含大量元数据吗?还是因为IL比x86指令具有更高的抽象度?我进行了一些研究,发现以下两篇有用的文章,但都没有回答我的问题。


MSIL Decompiler Theory
C Decompiler - Quick primer

最佳答案

我认为您已经掌握了最重要的部分。


如您所说,还有更多可用的元数据。我不知道C或C ++编译器发出的内容的详细信息,但我怀疑IL中包含更多的名称和类似信息。例如,只要看一下反编译器对特定堆栈框架中所了解的内容,就x86而言,您只知道堆栈的使用方式。在IL中,您知道堆栈的内容代表什么(或者至少是类型-不是语义!)
再次,正如您已经提到的,IL是比x86更高级别的抽象。 x86不知道什么是方法或函数调用,事件或属性等。IL还在其中包含所有这些信息。
通常,C和C ++编译器的优化程度要比(例如)C#编译器高得多。这是因为C#编译器假定大多数优化仍可以在以后由JIT执行。在某些方面,C#编译器不要尝试进行很多优化是有道理的,因为JIT可以使用各种信息,而C#编译器则不可用。优化的代码更难反编译,因为它离自然地表示原始源代码还很远。
IL被设计为JIT编译的。 x86被设计为本地执行(必须通过微代码执行)。 JIT编译器所需的信息与反编译器所需的信息相似,因此反编译器使用IL的时间更短。在某些方面,这实际上只是第二点的重述。