在反转二进制文件和解析内存时,我经常遇到诸如"@YAXPAX@"之类的用于引用过程的字符串。

我相信这些字符串是符号引用。

#1 楼

我相信这种奇怪的东西是由于名称改写而出现的,也被称为名称修饰。名称修饰是编译器用来将语义相关信息从编译器传递到链接器的机制。

这是Wikipedia如何描述Visual C ++系列编译器的名称修饰的方法:


Visual C ++名称修饰是Microsoft Visual C ++中使用的修饰(修饰)方案系列编译器。它提供了一种编码名称和有关函数,结构,类或其他数据类型的附加信息的方法,以便将更多语义信息从Microsoft Visual C ++编译器传递到其链接器。 Visual Studio和Windows SDK(包括命令行编译器)附带了程序undname,可以调用该程序undname以获得以整齐的名称编码的C样式函数原型。以下信息大部分是反向工程的。没有使用的实际算法的官方文档。


评论


谢谢。这很有帮助。我会投票,但我缺乏声誉。

– rekav0k
13年7月1日在15:42

#2 楼

(稍微偏离主题)

c ++ filt是一个非常有用的实用程序,用于在Unix上进行分解。我不确定它在Visual Studio中是否也可用,但这是您可以编译的简单实现。比较输出(g ++,不是VC):

 $ nm a.out
 0000000100001040 S _NXArgc
 0000000100001048 S _NXArgv
 0000000100000d40 T __ZN6complxC1Edd
 0000000100000d10 T __ZN6complxC2Edd
 0000000100000d70 T __ZNK6complxplERKS_
 0000000100001058 S ___progname
 0000000100000000 T __mh_execute_header
 0000000100001050 S _environ
                  U _exit
 0000000100000e20 T _main
 0000000100001000 s _pvars
                  U dyld_stub_binder
 0000000100000cd0 T start


与c ++ filt:

 $ nm a.out |c++filt
 0000000100001040 S _NXArgc
 0000000100001048 S _NXArgv
 0000000100000d40 T complx::complx(double, double)
 0000000100000d10 T complx::complx(double, double)
 0000000100000d70 T complx::operator+(complx const&) const
 0000000100001058 S ___progname
 0000000100000000 T __mh_execute_header
 0000000100001050 S _environ
                  U _exit
 0000000100000e20 T _main
 0000000100001000 short _pvars
                  U dyld_stub_binder
 0000000100000cd0 T start


#3 楼

只是一个小提示,以防您不知道:您可以通过Options-> Demangled names对IDA内部的名称进行解密...

我相信默认值是对注释中的名称进行解密,但是您可以还将其更改为函数名称本身。带走一些杂物!

#4 楼

对于vc ++名称分解,您可以使用

vc ++ filt

它是dbghelp上的一个小型包装器。UnDecorateSymbolname()函数将经过修饰的字符串并打印出已分解的名称返回给控制台,请参见下面的代码段

??3@YAXPAX@Z
void __cdecl operator delete(void *)
?AFXSetTopLevelFrame@@YAXPAVCFrameWnd@@@Z
void __cdecl AFXSetTopLevelFrame(class CFrameWnd *)


代码段

int _tmain(int argc, _TCHAR* argv[])
{
    char buff[0x100];
    UnDecorateSymbolName("??3@YAXPAX@Z",buff,0xf0,UNDNAME_COMPLETE);
    printf("%s\n",buff);
    return 0;
}


输出

>
void __cdecl operator delete(void *)


评论


Visual Studio附带了“ undname.exe”,不需要任何其他工具。

–伊戈尔·斯科钦斯基♦
13年7月11日,1:13

#5 楼

有一个宝石般的宝石可以解开C ++名称。尽管您拥有的是MSVC,但它还不支持GCC。

您可以很快将其放入名称为unmangler gui的红宝石鞋应用中。

require 'unmangler'

puts Unmangler.unmangle "??3@YAXPAX@Z"
puts Unmangler.unmangle "?AFXSetTopLevelFrame@@YAXPAVCFrameWnd@@@Z"

# output:
# void __cdecl operator delete(void *)
# void __cdecl AFXSetTopLevelFrame(class CFrameWnd *)