函数栈帧

函数的每一次调用,都会为该函数开辟空间,用于本次函数的调用中变量的保存,现场保护。这块栈空间被称之为 函数栈帧
这里写图片描述
对这样一段代码进行调试发现,不仅仅有main函数,main函数被_tmainCRTStartup函数调用,而_tmainCRTStartup函数被mainCRTStartup函数调用

在函数栈帧中有两个至关重要的寄存器

  • ebp:存放指向当前函数的栈底的地址

  • esp:维护栈底,存放指向函数栈顶的地址,每当一次push操作完成,esp的地址更新为当前栈顶

对这段代码对应的汇编代码分析:

这里写图片描述
执行call指令时按F11,执行jmp指令,进行地址的跳转
这里写图片描述
可以发现通过jmp指令的跳转,刚好来到了Add函数内部
Add函数的栈帧与main函数整体思路相同
这里写图片描述
剩下就是函数的返回部分,则根据之前压栈的顺序出栈

ret指令会使得出栈一次,并将出栈的内容当作地址,将程序跳转到该地址处

根据上面分析的压栈顺序画出整个压栈过程,如下:
这里写图片描述

诡码分析

理解了上面整个函数栈帧的过程便可以理解以下代码

#include <stdio.h>

void fun()
{
    int tmp = 10;
    int *p = (int *)(*(&tmp+1));
    *(p-1) = 20;
}

int main()
{
    int a = 0;
    fun();
    printf("a = %d\n", a);
    return 0;
}

这里写图片描述
通过函数栈帧分析就会发现一段诡异的代码就变得不再诡异。
这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值