https://www.cnblogs.com/starrysky77/p/8531413.html

对于 C 编译器的修饰规则

对于 __stdcall 调用约定,编译器和链接器会在输出函数名前加上一个下划线前缀,函数名后面加上一个“@”符号和其参数的字节数,例如 _functionname@number__cdecl 调用约定仅在输出函数名前加上一个下划线前缀,例如 _functionname

__fastcall 调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,例如 @functionname@number

对于 C++ 编译器的修饰规则

 C++ 的函数名修饰规则有些复杂,但是信息更充分,通过分析修饰名不仅能够知道函数的调用方式,返回值类型,参数个数甚至参数类型。不管 __cdecl__fastcall 还是 __stdcall 调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字,再后面是参数表的开始标识和按照参数类型代号拼出的参数表

对于 __stdcall 方式,参数表的开始标识是“@@YG”,对于 __cdecl 方式则是“@@YA”,对于 __fastcall 方式则是“@@YI”。参数表的拼写代号如下所示: 

X--void      
D--char      
E--unsigned char      
F--short      
H--int      
I--unsigned int      
J--long      
K--unsigned long(DWORD)   
M--float      
N--double      
_N--bool   
U--struct   

指针的方式有些特别,用 PA 表示指针,用 PB 表示 const 类型的指针。后面的代号表明指针类型,如果相同类型的指针连续出现,以“0”代替,一个“0”代表一次重复。

U 表示结构类型,通常后跟结构体的类型名,用“@@”表示结构类型名的结束。

函数的返回值不作特殊处理,它的描述方式和函数参数一样,紧跟着参数表的开始标志,也就是说,函数参数表的第一项实际上是表示函数的返回值类型。参数表后以“@Z”标识整个名字的结束,如果该函数无参数,则以“Z”标识结束。下面举两个例子,假如有以下函数声明:

int Function1 (char *var1,unsigned long); ?Function1@@YGHPADK@Z

void Function2(); ?Function2@@YGXXZ

成员函数

对于 C++ 的类成员函数(其调用方式是 thiscall),函数的名字修饰与非成员的 C++ 函数稍有不同,首先就是在函数名字和参数表之间插入以“@”字符引导的类名;其次是参数表的开始标识不同,公有(public)成员函数的标识是“@@QAE”,保护(protected)成员函数的标识是“@@IAE”,私有(private)成员函数的标识是“@@AAE”,如果函数声明使用了 const 关键字,则相应的标识应分别为“@@QBE”,“@@IBE”和“@@ABE”。如果参数类型是类实例的引用,则使用“AAV1”,对于 const 类型的引用,则使用“ABV1”。

class CTest 
{ 
private: 
    void Function(int); 
protected: 
    void CopyInfo(const CTest &src); 
public: 
    long DrawText(HDC hdc, long pos, const TCHAR* text, RGBQUAD color, BYTE bUnder, bool bSet); 
    long InsightClass(DWORD dwClass) const; 
};
?Function@CTest@@AAEXH@Z
?CopyInfo@CTest@@IAEXABV1@@Z
?DrawText@CTest@@QAEJPAUHDC__@@JPBDUtagRGBQUAD@@E_N@Z
?InsightClass@CTest@@QBEJK@Z

Tools

有两种方式可以检查你的程序中的函数的名字修饰:使用编译输出列表或使用 Dumpbin 工具。使用 /FAc/FAs/FAcs 命令行参数可以让编译器输出函数或变量名字列表。使用 dumpbin.exe /SYMBOLS 命令也可以获得 obj 文件或 lib 文件中的函数或变量名字列表。此外,还可以使用 undname.exe 将修饰名转换为未修饰形式。

undname.exe 在装 VS 的时候会装上,用 everything 找到就可以了(顺便放到 path 里)

对于 GCC 编译来说,可以使用 c++filt 解析被修饰过的名称