【发布时间】:2014-02-26 00:36:36
【问题描述】:
所以问题是:为什么反编译器不恢复局部变量的名称?我认为反编译器会删除有关本地名称的所有信息,并简单地使用 ldarg_0 等。这就是为什么这段代码:
private static int Foo()
{
int locA = Console.ReadKey().KeyChar;
int b = Console.ReadKey().KeyChar;
int c = Console.ReadKey().KeyChar;
return locA*b * c;
}
被反编译成这个:
private static int Foo() // from .Net reflector 8.2
{
int keyChar = Console.ReadKey().KeyChar;
int num2 = Console.ReadKey().KeyChar;
int num3 = Console.ReadKey().KeyChar;
return ((keyChar * num2) * num3);
}
直到今天,我发现了一个反编译器 ILSpy,它就这样反编译它:
// ConsoleApplication101.Program
private static int Foo()
{
int locA = (int)Console.ReadKey().KeyChar;
int b = (int)Console.ReadKey().KeyChar;
int c = (int)Console.ReadKey().KeyChar;
return locA * b * c;
}
原来的代码 - 在这里! (我知道,我禁止编译器优化我的代码,但我不在乎)
问题是:为什么所有使用的反编译器(reflector、dotPeek 等)在编译器在 exe 中提供时都没有显示这些非常重要的信息!
.method private hidebysig static int32 Foo() cil managed
{
// Размер кода: 56 (0x38)
.maxstack 2
.locals init ([0] int32 locA,
[1] int32 b,
[2] int32 c,
[3] int32 CS$1$0000,
[4] valuetype [mscorlib]System.ConsoleKeyInfo CS$0$0001)
IL_0000: nop
IL_0001: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0006: stloc.s CS$0$0001
IL_0008: ldloca.s CS$0$0001
IL_000a: call instance char [mscorlib]System.ConsoleKeyInfo::get_KeyChar()
IL_000f: stloc.0
IL_0010: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0015: stloc.s CS$0$0001
IL_0017: ldloca.s CS$0$0001
IL_0019: call instance char [mscorlib]System.ConsoleKeyInfo::get_KeyChar()
IL_001e: stloc.1
IL_001f: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0024: stloc.s CS$0$0001
IL_0026: ldloca.s CS$0$0001
IL_0028: call instance char [mscorlib]System.ConsoleKeyInfo::get_KeyChar()
IL_002d: stloc.2
IL_002e: ldloc.0
IL_002f: ldloc.1
IL_0030: mul
IL_0031: ldloc.2
IL_0032: mul
IL_0033: stloc.3
IL_0034: br.s IL_0036
IL_0036: ldloc.3
IL_0037: ret
} // end of method Program::Foo
【问题讨论】:
-
也许其中一个使用了 .PDB 文件而一个没有?
-
因为反编译器使用官方api访问元数据,IMetaDataImport和朋友。哪个不提供此信息。就像反射没有一样。 Ildasm 不同,可能是在 api 可用之前编写的。维护起来一定很痛苦。
标签: c# .net reflection reverse-engineering disassembly