2.函数调用约定

逆向基础的第二篇,也是好久没更新这个系列,感觉理论比较枯燥,大家也不敢兴趣,但是好像写啥都没人看哈哈哈

栈帧

在理解函数调用以前要先明白c语言怎么进行栈平衡的操作。

比如说你有一个函数:

int add(int a,int b){
  return a+b;
 }

main函数去调用它时,寄存器和栈的关系就是栈帧,当然完全理解栈帧可以尝试在函数内再调用另一个函数。

这里大家自己调试就懂了。大概的过程就是call 函数时保存返回地址到栈,调整ebp,入栈就提升esp反之下降esp。

如果再调用函数继续用栈保存。想必大家都会,不细说了。

 

函数调用约定

现在进入正题,先从32位的调用约定来说起(64位反而比较简单),当然我们只关心intel架构下的基本几种就够了,入参都是从后往前

 

1.__stdcall

windows中最常见的调用方式,有windows编程经验的小伙伴应该见过WINAPI的宏定义,其实等价于这个。

特点:函数本身去平衡堆栈

 

2.__cdecl

linux默认的函数调用方式。

特点:谁调用谁去平衡堆栈

 

3__fastcall(划重点)

它是比较特殊的一个,故名思意就是快速调用。

特点:32位下先用ecx和edx传递两个参数,多出来的用栈

      64位下先用rdi,rsi,rdx,rcx,r8,r9 共6个寄存器传参,多出的用栈

 

这里要着重理解fastcall,因为后面不论你是学逆向还pwn都需要很熟悉这个。

在c++中很多类的调用都是利用fastcall的,学到虚函数和类这块的小伙伴应该明白,很多类的调用其实是指针加偏移的形式,所以ecx尤其重要。

很多外挂编写也都是基于exc加偏移来进行的。

而pwn的大佬们都懂,pop_pop_ret这种gadget都是因为64位调用传参的关系,这里就不多说了。

这篇文章说的也不太清楚,大家多试多练,看似简单的东西其实还蛮复杂的,到后面结合新知识会有更深的理解。

posted @ 2021-05-28 13:40  TJ_WaTer  阅读(110)  评论(0编辑  收藏  举报