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

时间:2017-04-12 08:38:55

标签: 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    

转换为:

public class C {
    public void M() {
        string foo = nameof(C);
    }
}

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:6)

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

public class C {
    public void M() {
        string foo = nameof(C);
    }
}

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

public void M()
{
    string foo = "C";
}

现在放回.pdb文件,你会看到你的nameof(C)表达式。

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