马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 匿名 于 2016-12-12 20:33 编辑
参考C++反汇编与逆向分析技术揭秘,这本书讲的非常好,推荐大家去看看
VC++环境下的调用约定有三种,_cdecl,_stdcall,_fastcall.这三种调用约定解释如下:
_cdecl:C/C++默认调用方式,调用方平衡栈,不定参数的函数可以使用。
_stdcall:被调用方平衡栈,不定参数的函数无法使用。
_fastcall:寄存器方式传参,被调用方平衡栈,不定参数函数无法使用。
所谓的调用方与被调用方理解:
例如:
push 1
push 2
push 3
call xxxxx
add esp,0xC
调用方负责平衡栈意思是当函数结束的时候,也就是call后面直接add esp,push个数*4
被调用方负责平衡栈意思是当函数结束的时候,进行ret 操作,也就是会有ret 4、ret 8之类的。
_cdecl调用方式在函数内没有任何平衡参数操作,而在退出函数后对esp执行加8操作
Show_cdecl(10, 11);
00BF1547 push 0Bh
00BF1549 push 0Ah
00BF154B call Show_cdecl (0BF11D6h)
00BF1550 add esp,8 //这里平衡参数
_stdcall调用方式在函数内进行ret push参数*4进行堆栈平衡,与_cdecl调用方式相反
Show_stdcall(7, 8);
00BF153E push 8
00BF1540 push 7
00BF1542 call Show_stdcall (0BF106Eh)
00BF14ED pop edi
00BF14EE pop esi
00BF14EF pop ebx
00BF14F0 add esp,0C0h
00BF14F6 cmp ebp,esp
00BF14F8 call __RTC_CheckEsp (0BF1145h)
00BF14FD mov esp,ebp
00BF14FF pop ebp
00BF1500 ret 8 //这里进行平衡参数
_fastcall:寄存器方式传参,被调用方平衡栈,不定参数函数无法使用
好处是:传递效率高,因为是使用寄存器所以函数结束不用清空栈
坏处是:就只能用两个寄存器ecx,edx大于2就只能乖乖的用栈传递参数
Show_fastcall(22, 33);
00BF1553 mov edx,21h
00BF1558 mov ecx,16h
00BF155D call Show_fastcall (0BF1154h)
return 0;
00BF1562 xor eax,eax
例如这个例子:
_fastcall而寄存器比较少,它只使用了ecx,edx保存第一个和第二个参数,其余的放在堆栈操作
Show_fastcall(22, 33,44);
012D1553 push 2Ch //大于2个参数只能用栈
012D1555 mov edx,21h
012D155A mov ecx,16h
012D155F call Show_fastcall (012D11EAh)
012D1499 mov esp,ebp
012D149B pop ebp
012D149C ret 4 |