.net反编译器的局限性

时间:2013-04-10 21:50:25

标签: .net decompiler

所以我的雇主有这个旧的.NET / C#程序需要重写并且源代码丢失了。它是由前雇员开发的,但他们多年没有来过这里。也许这是他们的疏忽或者可能不是 - 在这一点上它并不重要。

无论如何,所以我想弄清楚它做了什么,这让我想到了.NET反编译器的局限性。

尝试反编译.NET就像尝试使缩小的js文件可读?使用缩小的js,您可以将代码缩进到一些预先确定的编码标准,并且您可以重命名变量以匹配为它们分配值的函数,但是您仍然会丢失大量信息。您将失去实际的变量名称以及开发人员所做的任何评论。

这是一个公平的比喻吗?

似乎这就是我的情况,或者开发人员真的没有留下任何评论,他确实根据他们的类型而不是他们的应用程序命名了一半的变量(这与匈牙利语系统一致我想)。

2 个答案:

答案 0 :(得分:2)

注意:我所说的大部分内容都是基于Java的,但据我所知,CLR的运行方式几乎相同。

基本上,它的工作方式是编译器将源代码转换为称为字节码的格式,然后由VM执行。通常,编译器不会优化它们生成的代码,因为它无论如何都会在运行时在运行时进行优化。因此,如果代码是由标准编译器编译而不是混淆的,则字节码的转换是非常直接和可预测的,这意味着您可以将其反编译为合理的源代码。

然而,你仍然会失去任何基本上是语法糖的东西。编译器只包含执行所需的东西。幸运的是,反射支持(以及调试,如果启用)意味着很多源级别信息将保留在字节码中,可能通过可选元数据。但是,即使使用反射也无法访问空格和注释等内容,因此无法恢复它们。

与缩小JS的类比并不准确但它仍然有用。在Javascript的情况下,源文件是VM的输入,因此没有可见的中间字节码阶段。缩小是优化器经过并重新格式化源代码的结果,但它仍然是源代码。另一方面,在这两种情况下,丢失的信息是由于不需要执行而不保留它的工具的结果。

如果文件被混淆了,那么所有这些都会从窗口中消失。混淆器故意弄乱编译器引入的模式,并将删除它们可以使用的所有可选元数据。您通常仍然可以对混淆的代码进行反编译,但它会很混乱,并且不会包含原始源的有用信息,例如格式化和变量名称。

答案 1 :(得分:1)

反射不需要局部变量名,因此它们会被抛弃。实际上,在字节码级别上没有实际的局部变量,只有堆栈位置。评论相同 - 不保留。

您可以使用MSIL反汇编程序(Ildasm.exe)查看可执行文件中实际存在的内容。名称strNN等由反编译器生成,试图帮助您恢复代码的逻辑。