关于栈结构的一些总结

前几天在分析一款软件的时候,发现在分析栈的时候晕圈了,索性今天就总结一波吧:

先看一个demo:

void f1(int a, int b, int c)
{
    int d = a + b + c;


}

int f(int a,int b)
{
    int c = a + b;
    f1(1,2,3);
    return  c;
}

int main()
{

    f(2,3);


    return 0;
}

主函数:

这里写图片描述

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这是上面在主函数里面调用函数f之前的情况;
此时上一个ebp还没变;

进入f函数

这里写图片描述
这里写图片描述
这里写图片描述
保存上一个ebp(主函数的ebp);
设立一个新的ebp
这里写图片描述
设立新的esp;
这里写图片描述
safecookie前;
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
safecookie之后;(这里由于原来的demo的图片丢了,这里重新截图的,有随机基址的!只要了解其逻辑即可!)实际上是对局部变量赋值!(注意其方向)

这里写图片描述
调用函数前;

f1函数

这里写图片描述
调用函数时候;
保存上一个ebp;
这里写图片描述
这里写图片描述
设立一个新的ebp,设立新的esp;

这里写图片描述
这里写图片描述
这里写图片描述
上面2幅图,看栈的变化
看栈的变化
这是safecookie
这里写图片描述
这里写图片描述
这里写图片描述
仔细观察这3个图
最后一张图pop ebp恢复了上一个栈帧
即此时ebp里面装的是上一个栈帧的ebp
这里写图片描述
这里写图片描述
执行完retn指令之后
retn 就等于esp + 4,jmp 上一层函数的的下一条指令
其实就是retn = pop eip
retn N操作:先eip=esp,然后esp=esp+4+N
这里写图片描述
这里写图片描述
这里写图片描述
retn 调用 之前
这里写图片描述
retn 调用 之后

总结

能使得esp发生变化的指令:

  • push ——->esp=esp-4
  • pop ———>esp=esp+4
  • call指令(等效于以下指令):
    将call的下一条指令的地址压栈
    jmp 函数地址;
  • ret指令(等效于ret = pop eip):
  • retn 就等于esp + 4,jmp 上一层函数的的下一条指令
    其实就是retn = pop eip
    retn N操作:先eip=esp,然后esp=esp+4+N
    1.将当前栈顶中值(一般为返回地址)出栈,”放入”eip中;
    2.返回至上一层函数(其实放入eip中就已经注定这样结局)

  • sub esp, 0xXX

  • add esp,0xXX

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值