当我打开像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);
}
}
答案 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符号可能包含实际源代码的路径(例如,您可能会在异常堆栈跟踪中看到这些路径),然后反编译工具会使用它直接显示它而不进行任何反编译。