Windows调用约定 C++函数名修饰 二进制文件分析

2015-01-21 11:48:00
admin
原创 6153
摘要:Windows调用约定 C++函数名修饰 二进制文件分析

一、调用约定

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;


三、二进制文件分析

Windows应用程序细节:

1、Windows/System32存放64位应用程序依赖库;

2、Windows/SysWOW64存放32位应用程序依赖库;

3、32位应用程序访问System32会自动映射到SysWOW64

4、msvcrt.dll是操作系统使用的vc运行时库;

5、msvcr.dll是应用程序使用的vc运行时库;

6、msvcp.dll是应用程序使用的vc++运行时库;


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

1、分析依赖库,dumpbin.exe /DEPENDENTS GM.exe
2、分析依赖函数,dumpbin.exe /IMPORTS:msvcr120.dll GM.exe

3、Dependencies工具下载,https://github.com/lucasg/Dependencies

4、分析依赖库,Dependencies.exe -depth 1 -chain GM.exe

5、解析依赖库位置,Dependencies.exe -depth 1 -modules GM.exe


Windows查找进程加载库和文件

1、Procexp.exe,Private Bytes虚拟内存,Working Set物理内存,包括使用的共享内存;

2、Procexp.exe,可以查找进程的加载库,可以查找加载库的进程,可以查找加载文件的进程;

3、Listdlls.exe,可以查找进程的加载库,可以查找加载库的进程;

4、文件引用查找,资源监视器的CPU页面搜索资源名称,handle.exe搜索资源名称;


进程和文件操作监控:

1、SysinternalsSuite的Procmon.exe可以对进程和文件操作监控;

2、过滤器,Process Name-进程文件名,Path-进程操作的文件路径;

3、Jump to Object可以跳转到进程操作的文件目录;


Linux二进制文件分析:

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

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

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

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

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

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

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

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

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