【逆向】函数调用时栈空间的变化

  1. 初始栈空间
    在这里插入图片描述

  2. 传参,通过push指令先将参数压入堆栈(c语言:从右向左压入)

在这里插入图片描述

  1. call指令函数入口地址(跳转到函数,并将下一条语句地址push到堆栈中)

  2. push ebp(保存栈底指针,用于后面恢复栈底)
    在这里插入图片描述

  3. mov ebp, esp(提升栈底指针,准备给函数分配栈空间)
    在这里插入图片描述

  4. sub esp, xxx(提升栈顶指针,开辟专属该函数的栈空间,共该函数局部变量使用)
    在这里插入图片描述

  5. push 寄存器(保存进入该函数前的寄存器的值,保证函数调用完后可以恢复原始值)
    在这里插入图片描述

  6. 执行函数代码

  7. pop 寄存器

在这里插入图片描述

  1. mov esp, ebp(降低栈顶指针,释放专属该函数的栈空间)
    在这里插入图片描述

  2. pop ebp(降低栈底指针,恢复成原始值)

  3. retn(pop eip,此时栈顶指针指向的位置刚好保存着进入函数之前的下一条语句的地址)

  4. add esp, xxx(由于调用函数前push参数导致栈顶指针提升,因此调用完要释放掉参数栈空间)
    在这里插入图片描述

问题:

  • 为什么要进行堆栈平衡?

因为Windows操作系统应用层堆栈大小默认是1M,每次调用函数都会开辟一段堆栈空间,用完如果不平衡,调用几次函数就凉凉了

  • 函数的返回值放哪里了?

大部分情况返回值会放到eax中,但不是绝对的。

  • 传参只能通过push到堆栈的方式吗?

也可以通过寄存器传参。

函数调用约定:

  • __cdecl: C/C++里中默认调用方式

特点1:push参数,顺序从右往左。
特点2:外部平衡堆栈。(即在retn之后(函数外部)释放参数栈空间)

  • __stdcall:windows API函数的调用方式 用了WINAPI的宏进行代替

特点1:push参数,顺序从右往左。
特点2:内部平衡堆栈。(即在retn之前(函数内部)释放参数栈空间)

  • __fastcall:快速调用方式 这种方式选择将参数优先从寄存器传入

特点1:寄存器传参,edx,ecx (如果参数多于2个,则用push),顺序从右向左
特点2:内部平衡堆栈。(即在retn之前(函数内部)释放参数栈空间)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值