Windows应用程序 调用约定 C++函数名修饰 二进制分析工具

2015-03-21 11:48:00
admin
原创 5506
摘要:Windows应用程序 调用约定 C++函数名修饰 二进制分析工具

一、Windows应用程序

1、Windows/SysWOW64用于支持32位应用程序,64位应用程序可以直接访问SysWOW64;

2、Windows/System32用于支持64位应用程序,32位应用程序访问System32会自动映射到SysWOW64;


二、调用约定

1、Calling Conventions,调用约定,跨语言编程需要关注调用约定;

2、Windows调用约定可以是__cdecl、__stdcall__fastcall,申明示例:int __cdecl myFunc()

3、Linux调用约定默认cdecl,申明示例:int __attribute__((cdecl)) myFunc()


VC默认是__cdecl,Windows API则是__stdcall,如果用VC开发DLL给其他语言使用,需要指定__stdcall。汇编函数给C调用,一定要小心堆栈的清除工作,如果是__cdecl方式调用,汇编函数不需要关心保存参数的堆栈清除,如果是__stdcall方式调用,汇编函数需要在函数退出前恢复堆栈。


1、__cdecl
        按从右至左的顺序压参数入栈,由调用者把参数弹出栈,返回值位于EAX,对于printf这样可变参数的函数必须用这种约定。编译器对这种调用约定的函数生成修饰名的时候,会在输出函数名前面加上一个下划线,格式为_function。
2、__stdcall 
        按从右至左的顺序压参数入栈,由被调用者把参数弹出栈,返回值位于EAX,通常用于Win32 API。编译器在输出函数名前面加上一个下划线,后面加上@参数的字节数量,格式为_function@num,int func(int a, double b)修饰名是_func@12。
3、__fastcall
       __fastcall主要特点就是快,因为它通过寄存器传递参数,实际上它用ECX和EDX传递前两个DWORD或更小的参数,剩下参数仍然自右向左压栈传递,由被调用者把参数弹出栈,返回值位于EAX。编译器在输出函数名前面加上一个@符号,后面加上@参数的字节数量,格式为@function@num。和__stdcall唯一差别是前面两个参数通过寄存器传递,注意通过寄存器传递的两个参数是从左向右,第1个进ECX,第2个进EDX,其他参数是从右向左入栈。


三、C++函数名修饰

1、Name Mangling,Decorated Names,函数名修饰;

2、编码格式:? + 函数名 + 调用约定 + 参数列表,问号标识函数开始;

3、调用约定编码:__cdecl=@@YA,__stdcall=@@YG, __fastcall=@@YI;

4、参数类型编码:

    X--void
    D--char
    E--unsigned char
    F--short
    H--int
    I--unsigned int
    J--long
    K--unsigned long
    M--float
    N--double

5、参数列表第一项是函数的返回值类型;
6、参数列表后面以@Z标识结束,函数无参数则以Z标识结束;

7、解析示例:?prn@@YAHD@Z函数申明是int __cdecl prn(char);

8、解析工具:dem.zip,或者Viusal Studio的undname.exe;


四、二进制分析工具

1、Viusal Studio的dumpbin.exe用于解析二进制文件;

2、binutils是一个二进制工具集合,包含objdump、nm、strings;


Windows查看可执行文件依赖的动态库:

1、dumpbin.exe  /DEPENDENTS exe-file

2、Dependencies:https://github.com/lucasg/Dependencies


objdump -d elf-file,查看反汇编;

objdump -S elf-file,查看源码和反汇编;

objdump -x elf-file,查看elf文件头部信息;

objdump -h elf-file,查看elf文件分段信息;

objdump -a elf-file,查看归档信息;


nm objfile,查看符号表信息,T代表定义的函数,U代表依赖的符号,用于解决链接错误;

strings file,查看二进制定义的字符串,查看修改的字符串是否生效,用于解决链接错误;

    发表评论
    评论通过审核之后才会显示。