关于去除PE文件中函数修饰的做法
2010-11-23 23:43
579 查看
在之前的一篇文章《PE文件格式的一些研究
》我简单谈了PE文件格式的基本机构。在文章的最后我提到由于C++的命名空间和虚函数的影响,编译器对C++库的导出函数进行了名称修饰。
今晚简单研究了一下如何把这个名称修饰去掉,还原函数的真实名称。对于VC编译器编译出来的DLL,微软提供了一个函数UnDecorateSymbolName(在Dbghelp.lib,使用时需要添加该库)来将修饰后的函数名称转换为函数签名(注意这里的函数签名不能简单认为是函数原本的名字,函数签名等于函数所在的命名空间加函数所在类再加函数名字)。UnDecorateSymbolName的原型如下(据Imagehlp.h):
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基本用法如下:
测试了一下,basic_ostream的成员函数flush的修饰名为?flush@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEA***12@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. 《程序员的自我修养--链接、装载与库》,俞甲子、石凡、潘爱民等
》我简单谈了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@@QAEA***12@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. 《程序员的自我修养--链接、装载与库》,俞甲子、石凡、潘爱民等
相关文章推荐
- 关于去除PE文件中函数修饰的做法
- 关于VC中生成的PE(exe, dll, sys...)文件中对函数名称的修饰
- 关于ini文件读取的函数
- 关于获取文件路径,查找文件是否存在,创建文件的一些函数
- 关于宏定义汇编函数的的做法
- 获得PE文件的导入模块和导入函数
- 关于在WIN32调用一些Zw系列的文件操作函数
- 关于finfo_file函数获取文件mime值验证出错的问题
- 关于HM打印配置文件中参数的函数
- 关于PE可执行文件的修改(引用http://www.xfocus.net/articles/200109/266.html)
- c语言关于文件操作的常用函数(新手入门看)
- 使用汇编取得PE文件导入的DLL名称和函数名称
- 关于PHP程序使用file_get_content()函数进行抓取PHP程序与smarty结合编译过程中产生的静态文件,抓取不了?连接超时?(地址映射)
- 关于acm C++一些常用函数和头文件
- os, os.path模块中关于文件/目录常用的函数使用方法
- C语言中关于文件操作的常用函数
- 关于PE可执行文件的修改
- python基础:os模块中关于文件/目录常用的函数使用方法
- 关于在Eclipse中使用函数名查找此函数所在的js文件
- windows PE Image 文件分析(4)--- 导入函数的绑定