MyException - 我的异常网
当前位置:我的异常网» VC/MFC » 【原创&交流】关于除了PE文件中函数修饰的做法

【原创&交流】关于除了PE文件中函数修饰的做法

www.myexceptions.net  网友分享于:2013-04-10  浏览:4次
【原创&交流】关于去除PE文件中函数修饰的做法
链接:关于去除PE文件中函数修饰的做法

    在之前的一篇文章《PE文件格式的一些研究》我简单谈了PE文件格式的基本机构。在文章的最后我提到由于C++的命名空间和虚函数的影响,编译器对C++库的导出函数进行了名称修饰。

今晚简单研究了一下如何把这个名称修饰去掉,还原函数的真实名称。对于VC编译器编译出来的DLL,微软提供了一个函数UnDecorateSymbolName(在Dbghelp.lib,使用时需要添加该库)来将修饰后的函数名称转换为函数签名(注意这里的函数签名不能简单认为是函数原本的名字,函数签名等于函数所在的命名空间加函数所在类再加函数名字)。UnDecorateSymbolName的原型如下(据Imagehlp.h):


DWORD
IMAGEAPI
WINAPI
UnDecorateSymbolName(
    __in PCSTR name,
    __out_ecount(maxStringLength) PSTR outputString,    
    __in DWORD maxStringLength,
    __in DWORD flags
);



     
Name —— 待转换的函数名
outputString —— 转换后函数签名的输出字符串
maxStringLength —— 输出字符串的缓冲区大小
flags —— 转换符号,0表示完全转换

VS 2008+ sp1对应的MSDN对这个函数的解释有差错,VS 2008+ sp1对应的MSDN上的UnDecorateSymbolName第一个参数是__in   PCTSTR DecoratedName,这意味着这个函数可以处理unicode字符串。实际上我在VS2005(带sp1)和VS2008(带sp1)上测试,UnDecorateSymbolName的第一个参数的类型应为PCSTR,就是说它只能处理多字节字符串。

 UnDecorateSymbolName基本用法如下:



int _tmain(int argc, _TCHAR* argv[])
{
TCHAR szUndecorateName[256];
memset(szUndecorateName,0,256);

if (2==argc)
{
::UnDecorateSymbolName(argv[1],szUndecorateName,256,0);
std::cout<<szUndecorateName<<std::endl;
}
return 0;
}



    
     测试了一下,basic_ostream的成员函数flush的修饰名为?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@XZ,函数签名为public: class std::basic_ostream<char,struct std::char_traits<char> > &
__thiscall std::basic_ostream<char,struct std::char_traits<char> >::flush(void),
真够复杂的。值得注意的是该函数只能还原VC编译的pe文件的函数修饰,因为不同编译器的函数修饰法则并不相同。

参考文献:

1.《程序员的自我修养——链接、装载与库》,俞甲子、石凡、潘爱民等


------解决方案--------------------
Up。。。
------解决方案--------------------
顶上去 支持一切分享

文章评论

软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有