内存和 IDA 会话中类似于“@YAXPAX@”的工件

逆向工程 拆卸 艾达
2021-07-02 03:37:59

在反转二进制文件和解析内存时,我经常遇到"@YAXPAX@"用于引用过程的字符串这种约定有名称吗?

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

4个回答

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

维基百科是这样描述Visual C++ 系列编译器的 Name Mangling 的

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

(有点跑题了)

c++filt 是一个非常有用的工具,用于在 Unix 上进行 de-mangling。我不知道它是可用在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

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

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

您可以使用 vc++ 名称去重

vc++过滤器

它是 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 *)