函数调用栈

博客网址:www.shicoder.top
微信:18223081347
欢迎加群聊天 :452380935

这个分栏我们开始学习PWN,当然PWN也是自己的兴趣爱好,所以可能博客更新较慢,不好意思啦

前置知识

每个函数都有自己的栈帧,栈底用 ebp,栈顶用 esp,还有一个 eip,表示即将执行的指令的地址,下面是栈的图示,是从高地址向低地址增长

函数调用栈

函数的栈帧包括

  • 函数的返回地址和参数
  • 本地变量
  • 调用前后上下文

因此比如一个 main函数执行时候, ebp指向其栈帧底部,然后在函数运行时候随时 pushpop,导致其 esp不断变化,当要调用子函数 func时候,会先 push子函数所需要的参数,然后进入 func之后,首先 push ebp,因为此时的 ebpmain函数的,为了在 func函数结束后,找到 main函数的 ebp,所以先保留,然后 mov ebp,esp,这时候 ebp就会被赋予新的值,这个值就是 func函数栈帧的底部,然后就是一些 func函数自己的操作,当要使用传进来的参数时候,就去当时在 main调用 funcpush的参数去取,当执行 func函数之后,需要返回到 main,此时分两种情况

  • func中没有使用过局部变量,则进入 func之后, ebpesp始终是一样的,所以直接 pop ebp,此时 ebp中就存放了 call调用前, mainebp
  • func中使用过局部变量,则进入 func之后,首先会 sub esp,一些空间来给 func使用,然后结束时候,使用 leave => mov esp,ebp、pop ebp,先将 esp值变为 ebp的值,此时两个一样,然后 pop ebp之后, ebp中就存放了 call调用前, mainebp

简单的就是如下代码

main:
    ...

    push arg2
    push arg1
    call func
    ...

; func函数内没有局部变量
func:
    push ebp
    mov ebp,esp
    将main的栈中的参数放到寄存器中
    一顿操作
    pop ebp
    retn

; func函数内有局部变量
func:
    push ebp
    mov ebp,esp
    sub esp,0x10(就是一段长度,存放局部变量)
    将main的栈中的参数放到寄存器中
    一顿操作
    leave
    retn

注意:

  • call => 等价 push 返回地址,然后eip跳转到sum开头的地方
  • leave => 等价 mov esp, ebp 然后 pop ebp
  • retn => 等价 pop eip

小试牛刀

以下面的c语言代码进行讲解

#include

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

int main(){
    sum(3,4);
    return 0;
}

push    ebp
mov     ebp, esp
push    4
push    3
call    sum
add     esp, 8
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
pop     ebp
retn

下面一段视频就是其过程,可以看下

后面还有两段有局部变量的,大家也可以自己推导下。

#include

int sum(int a,int b)
{
    int c;
    c = a + b;
    return c;
}

int main(){
    int ret;
    ret = sum(3,4);
    return 0;
}
push    ebp
mov     ebp, esp
sub     esp, 10h
push    4
push    3
call    sum
add     esp, 8
mov     [ebp-4], eax
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
sub     esp, 10h
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
mov     [ebp-4], eax
mov     eax, [ebp-4]
leave
retn
#include

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

int main(){
    int ret;
    ret = sum(3,4);
    return 0;
}
push    ebp
mov     ebp, esp
sub     esp, 10h
push    4
push    3
call    sum
add     esp, 8
mov     [ebp-4], eax
mov     eax, 0
leave
retn

push    ebp
mov     ebp, esp
mov     edx, [ebp+8]
mov     eax, [ebp+0Ch]
add     eax, edx
pop     ebp
retn

Original: https://www.cnblogs.com/shilinkun/p/16272423.html
Author: 小坤学习园
Title: 函数调用栈

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/607255/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • [CentOS7]redis设置开机启动,设置密码

    简介 上篇文章介绍了如何安装redis,但每次重启服务器之后redis不会自启,这里将介绍如何进行自启设置,以及如何设置redis的密码,进行密码验证登陆。 上篇文章: Cento…

    Linux 2023年5月28日
    0104
  • 在海思芯片上使用GDB远程调试

    使用海思平台上(编译工具链:arm-himix200-linux)交叉编译 GDB 工具(使用版本8.2,之前用过10.2的版本,在编译 gdbserver 遇到编译出错的问题,因…

    Linux 2023年6月7日
    0142
  • go将青龙面板里面的脚本文件都下载到本地

    纯粹练手用的,大家轻喷青龙面板的脚本文件可以下载到本地,这样的话自己可以研究一下对应的脚本文件,能学到更多的知识,原理其实很简单,F12一下就知道了,青龙面板使用Request H…

    Linux 2023年6月7日
    0129
  • apache tomcat 目录session应用信息漏洞

    Tomcat 是一款开源的 Web 应用服务器软件。Tomcat 属于轻量级应用服务器,在中小型系统和并发访问用户不多的场合下被普遍使用,是开发和调试 JSP 程序的首选。 漏洞描…

    Linux 2023年6月7日
    0128
  • SpringBoot的文件上传&下载

    前言:不多BB直接上代码 文件上传 pom依赖添加commons-io <!– 上传/下载jar https://mvnrepository.com/artifact/co…

    Linux 2023年6月14日
    097
  • 维修数列代码及简易题解

    总体方案:将左右端点分别转到根和根的右儿子,将目标序列挤到以根的右儿子的左儿子为根的子树中,然后进行一系列骚操作即可 建树:用类似线段树的方法建树,递归即可,注意加两个边界点 插入…

    Linux 2023年6月6日
    0114
  • 干货速看!同行盆友来稿:一文带你搭建K8S高可用集群,以及在上面搭建Prometheus和Grafana。

    写在开篇 kubeadm工具快速部署k8s集群实现故障自动发现、转移及修复,集群中部署prometheus+grafan可实现自动收集集群的各项新性能指标数据,可视化界面提升客户对…

    Linux 2023年6月7日
    090
  • Linux常用命令

    基本操作 创建目录: mkdir xxx 删除目录: rm -rf xxx 切换目录: cd xxx,返回: cd – 创建文件: touch xxx.txt 复制文件: cp x…

    Linux 2023年6月8日
    0117
  • linux 普通分区与lvm分区

    安装linux系统时 有时候会提示lvm分区与标准分区 首先普及一下lvm分区:lvm是 logical volume manager (逻辑卷管理),linux环境下对磁盘分区的…

    Linux 2023年6月14日
    094
  • ELK收集MySQL慢日志并告警

    采用的是 filebeat采集日志, Redis做日志存储, logstash消费处理日志,将处理过的日志存储到 ES, kibana做日志展示, Elastalert做监控告警长…

    Linux 2023年5月27日
    094
  • JavaScript编程基础(一)

    目的: 熟练掌握JavaScript的语言基础,包括数据类型、常量和变量、运算符和表达式、基本语句和函数。 理解JavaScript如何动态产生HTML代码,以及控制CSS。 要求…

    Linux 2023年6月13日
    088
  • 关于ubuntu执行32位程序报错execvp():No such file or directory的解决方案

    一、前言 &#x5728;ubuntu 执行一个程序时,居然报错 execvp():No such file or directory ,报错截图如下图所示: ls -al…

    Linux 2023年6月8日
    0106
  • redis 常用命令

    批量删除redis key redis-cli -a xxx keys “prefix_tb_supplier:spl_id*” | xargs redis…

    Linux 2023年5月28日
    085
  • 一位美国教授的科研诀窍:每周工作100小时(转)

    今天看到了,Xinyu Zhang 的一篇文章,深受启发,转载一下。 OSU计算机系一位教授到北大讲座,学生提问:您组里发了那么多牛paper,有什么诀窍? 教授回答:我们组里,从…

    Linux 2023年6月14日
    0103
  • Ubuntu2004使用dnsmasq+Clash+Iptables+Ipset

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月13日
    083
  • Linux系统卡死后紧急处理

    前言:Linux系统卡死了的情况有很多,最常见的是系统负载过高导致的。还可以运行内存耗用极大的程序(如虚拟机),也会迅速提升系统负载。注意:不能再试图依赖任何图形界面的东西,如 G…

    Linux 2023年6月7日
    097
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球