反编译的C#是否从IL/MSIL反向工程?

Jos*_*ard 8 c#

当我打开像ILSpy或dotPeek这样的工具时,我可以选择查看反编译的C#或IL.

当您查看反编译的源时,反编译器是否将IL反向工程为反编译的C#等效文件?

如果是这样,那么反编译器如何推断出下面的IL这样的情况呢?(请注意,这是我想到的第一种语言结构的一个简单例子,它不能从IL中推断出来,而不是反编译器的实际输出):

IL_0000: nop                  // Do nothing (No operation)
IL_0001: ldstr "C"            // Push a string object for the literal string
IL_0006: stloc.0              // Pop a value from stack into local variable 0
IL_0007: ret    
Run Code Online (Sandbox Code Playgroud)

翻译成:

public class C {
    public void M() {
        string foo = nameof(C);
    }
}
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 6

是的,反编译工具必须从IL进行逆向工程.

这就是为什么需要为每个版本的C#/ VB更新工具,如果您希望它们反编译新引入的语言功能.否则,如果该工具没有更新,它将放弃尝试反编译它或者它将产生高度复杂的代码,疯子本可以用该语言的早期版本编写但很可能没有.

一些反编译工具也会尝试找到实际的源代码(通过PDB和源服务器),如果他们在这项工作中取得成功,那么你将看到实际的源代码,当然在这种情况下不会发生反编译工作.

  • ...新引入的语言特征......以一种不是完全spagetti的方式. (3认同)
  • @JosephWoodward - PDB文件没什么帮助.它们将允许例如局部变量名称有时被恢复,但它们在大多数情况下并不真正指导反编译过程. (2认同)

Evk*_*Evk 6

当然,这些工具将尝试从MSIL进行逆向工程,但谈到您的特定示例 - 无法将MSIL逆向工程

public class C {
    public void M() {
        string foo = nameof(C);
    }
}
Run Code Online (Sandbox Code Playgroud)

没有extenal指导,如符号(.pdb)文件.尝试在库中编译上面的语句,然后删除".pdb"文件并将.dll放入dotPeek.您将看到它将按预期反编译:

public void M()
{
    string foo = "C";
}
Run Code Online (Sandbox Code Playgroud)

现在把.pdb文件放回去,你会看到你的nameof(C)表情.

现在放回.pbd文件,但是改变你用来编译.dll的源代码的位置(例如,重命名项目文件夹,完全删除它,或者只是将带有.pdb的.dll移动到不同的机器上).再次在dotPeek中加载它,您将再次看到它string foo = "C";.这是因为.pdb符号可能包含实际源代码的路径(例如,您可能会在异常堆栈跟踪中看到这些路径),然后反编译工具使用它直接显示它而不进行任何反编译.