参考:pwn小白入门02---汇编函数调用过程_苏璃只想划水的博客-CSDN博客_汇编 过程调用
测试程序
#include<stdio.h> int sum(int x,int y){ int a=x+y; return a; } int main(){ sum(1,2); return 0; }
讯享网
编译
讯享网gcc -m32 pwn03.c -o pwn03
gdb分析
gdb pwn03
反汇编主函数
讯享网pwndbg> disass main Dump of assembler code for function main: 0x000011d1 <+0>: endbr32 0x000011d5 <+4>: push ebp 0x000011d6 <+5>: mov ebp,esp 0x000011d8 <+7>: call 0x11f5 <__x86.get_pc_thunk.ax> 0x000011dd <+12>: add eax,0x2dff 0x000011e2 <+17>: push 0x2 0x000011e4 <+19>: push 0x1 0x000011e6 <+21>: call 0x11ad <sum> 0x000011eb <+26>: add esp,0x8 0x000011ee <+29>: mov eax,0x0 0x000011f3 <+34>: leave 0x000011f4 <+35>: ret End of assembler dump.
在主函数处下断点,运行
pwndbg> b main Breakpoint 1 at 0xd1 pwndbg> r Starting program: /home/lingqi/Desktop/pwn/pwn03
当前状态
eip寄存器中存放的地址是cpu将要执行的指令的地址。
1.先将ebp中存储的数值0x0入栈

2.将esp指向的地址赋给ebp
此时栈底指针ebp和栈顶指针esp指向同一个位置,即当前栈帧为空。

3. 将sum(1,2)的参数2入栈
在调用函数之前,需要先把函数的各项参数压入栈中。根据栈先入后出的特性,我们要使2先入栈,1再入栈,使得参数1先出栈,2后出栈。

4.将sum(1,2)的参数1入栈

5.调用函数sum()
call指令是将call sum指令的下一条指令的地址(即指令add esp,8的地址0xeb)入栈,即为sum()函数的返回地址。然后将sum函数的第一条指令的地址放入eip寄存器中。

6.将ebp指向的地址入栈,即main函数时的ebp值入栈


7.将esp指向的地址放入ebp

8.将返回地址下存放的参数1(即0x1)放入edx

9. 将返回地址下存放的参数2(即0x2)放入eax

10.两数相加,将结果存入eax

11.将eax中的结果放入栈中ebp上方的局部变量1位置。

12.接下来离开sum函数,需要执行leave,ret指令。
leave 等价于
mov esp,ebp
pop ebp
执行leave函数:即将ebp的值赋给esp,这时esp,ebp都指向0xffffd608的位置。然后将先前存入栈中的ebp的值(0xffffd618)弹出放入当前ebp寄存器中,这时esp指向0xffffd60c(即为调用sum时放入栈中的main函数中call sum指令的下一条指令的地址(即指令add esp,8的地址0xeb))。

ret 等价于
pop
jump
然后执行ret指令,将先前存入栈中的eip的值放入当前eip寄存器中。

13.将栈顶指针esp的值加8,即把栈顶往栈底压,相当于把先前放入栈中的参数1,2移除。

可以发现,此时的栈结构与调用sum函数前没有区别。

14.清零eax,主函数返回。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/68013.html