gpt4 book ai didi

c# - 在 .Net 中恢复本地名称

转载 作者:行者123 更新时间:2023-11-30 12:28:30 24 4
gpt4 key购买 nike

所以问题是:为什么反编译器不恢复局部变量的名称?我认为反编译器会删除有关本地名称的所有信息并简单地使用 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;
}

原始代码 - 就在这里! (我知道,我禁止编译器优化我的代码,但我不在乎)

问题是:为什么所有使用的反编译器(反射器、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

最佳答案

您的观察/假设不正确。该元数据不是 exe 的一部分。 ILSpy 和 ildasm 只能显示原始变量名,因为这些程序读取可用的 pdb 文件。

编译后你会得到两个文件:一个exe文件和一个pdb文件。 pdb 文件包含元数据(如变量名、行号)。如果您使用能够读取随附的 pdb 文件的工具打开 exe,您将获得与原始源文件更匹配的反编译结果。

要验证您的 self ,您可以将 pdb 文件重命名为不同的扩展名,然后在 ildasm 或 ilpsy 中打开 exe。
ildasm 结果是:

// Code size       56 (0x38)
.maxstack 2
.locals init (int32 V_0,
int32 V_1,
int32 V_2,
int32 V_3,
valuetype [mscorlib]System.ConsoleKeyInfo V_4)

存在 pdb 文件时:

 // Code size       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)

你可以看出区别。从 pdb 文件中读取本地名称。

要验证您的 EXE 是否可以找到 pdb,您可以使用 DUMPBIN 命令:

dumpbin /pdbPATH:VERBOSE ConsoleApplication1.exe

这将呈现如下输出:

Dump of file ConsoleApplication1.exe

File Type: EXECUTABLE IMAGE
PDB file 'C:...\ConsoleApplication1.pdb' checked. (File not found)
PDB file found at 'c:...\obj\x86\Debug\ConsoleApplication1.pdb'

John Robbin (Wintellect) PDB Files: What Every Developer Must Know

关于c# - 在 .Net 中恢复本地名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21511880/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com