当前位置: 首页 > news >正文

滴水逆向 Day05:函数嵌套调用的内存布局(图文版)

0基础小白学逆向记录贴,一起来学逆向。https://mp.weixin.qq.com/s/EPDY6i2-R-WQI101KTJvtg

一、核心目标:搞懂一个函数调用另一个函数时,栈空间是怎么变化的、参数怎么传递、返回值怎么回来、ebp/esp 到底在干什么。


二、示例代码(C 语言)

我们用一个最简单的两层嵌套调用来分析:

#include<stdio.h>int plus(int x, int y){return x+y;}int plus1(int x, int y , int z){int m;m=plus(x,y);return m+z;}int main(){int r ;r=plus1(1,2,3);printf("%d",r);return 0;}

调用关系:main → plus2 → plus1这是最典型的函数嵌套调用


三、关键知识点(必须理解)

  1. 函数调用统一遵循栈规则

    • 参数从右向左入栈

    • 先压入返回地址

    • 保存旧 ebp,ebp = esp建立栈帧

    • 局部变量在 ebp 上方

  2. 嵌套调用本质:就是在一个函数的栈帧内部,再开启一个新的子函数栈帧。调用完子函数,栈会恢复到调用前的状态,继续执行父函数。

  3. 整个过程:

    • main

      调用plus2(1,2,3)

    • plus2

      内部又调用plus1(x,y)

    • plus1

      计算完成,返回结果给plus2

    • plus2

      再加上 z,返回给main

    • 最终r = 1+2+3 = 6


四、内存布局(栈空间)说明

1. 整体栈走向

esp始终指向栈顶

  • ebp

    用于定位当前函数的栈底,方便访问参数和局部变量

2. 调用 plus2 时的栈布局

  • 从右往左入栈参数:321

  • 压入main中调用plus2返回地址

保存旧 ebp(main 的 ebp)

  • 新 ebp = esp,建立 plus2 栈帧

  • 分配局部变量空间(如 int m)

3. 嵌套调用 plus1 时

在 plus2 函数内部,再次执行完整调用流程:

  • 从右往左入栈:yx

  • 压入 plus2 内部的返回地址

  • 保存当前 ebp(plus2 的 ebp)

  • 新 ebp = esp,建立 plus1 栈帧

  • 执行计算,通过 eax 带回返回值

4. 返回过程

  • plus1

    执行完毕,销毁自己的栈帧,回到 plus2

  • plus2

    拿到返回值,继续计算,再销毁自己栈帧,回到 main

  • 最终结果存入 main 中的变量 r

一句话总结:嵌套调用,就是栈帧的层层嵌套;返回时,栈帧层层弹出恢复。


五、总结

函数嵌套调用的完整流程

  1. 参数入栈顺序:从右向左

  2. 栈帧结构:旧 ebp → 返回地址 → 参数 → 局部变量

  3. 嵌套本质:栈帧里再套栈帧,调用完逐层恢复

理解这套内存布局,是后续看懂反汇编、栈溢出、HOOK、函数调用约定的基础。

关注"0基础学逆向",一起学逆向

http://www.cnnetsun.cn/news/1986959.html

相关文章:

  • PDown实战:解锁百度网盘下载的隐藏秘籍
  • XML 与 CSS:构建现代网页的关键技术
  • Windows操作系统,如何设置开启自动启动指定的程序?
  • Spring Boot项目里遇到Tomcat报RFC 7230/3986错误?别慌,教你两招搞定URL特殊字符问题
  • Janus-Pro-7B辅助LaTeX文档编写:智能排版与公式纠错
  • 别再花钱买NAS了!用HFS+Nat123在Windows上5分钟搭建个人网盘(附中文汉化)
  • 告别拖拽画布:用ABAP Dialog Screen手搓一个订单管理界面(附完整代码)
  • Canvas水印实战:5分钟搞定前端图片防盗,附完整代码与避坑指南
  • python kics
  • SSL/TLS 的演进
  • OpCore-Simplify深度解析:智能化EFI配置如何重塑黑苹果体验
  • Mysql--基础知识点--104--大表添加字段
  • 局域网快传大文件之Everything
  • SpringBoot+Vue基于爬虫的在线新闻聚合平台源码+论文
  • SQL如何高效统计分类下的多项指标_善用CASE WHEN与SUM聚合
  • 从科研计算到并行加速:在CodeBlocks中为Fortran项目配置OpenMP的两种方法实测
  • 【2026奇点智能技术大会权威内参】:AGI人才争夺战已打响,HR必须掌握的5大精准匹配模型与实时评估框架
  • 深度解析大气层整合包:从架构设计到实战应用的全方位指南
  • C++实际开发之泛型编程(模版编程)
  • CodeBlocks重装后编译器配置失效?保姆级修复与手动链接MinGW教程
  • Go语言怎么做地理围栏_Go语言地理位置计算教程【指南】
  • ROS2机械臂控制实战:用NMPC实现高精度轨迹跟踪(附避坑指南)
  • 赛元SC95F8617触摸库实战:从电机干扰到人体检测,我的按摩椅项目避坑实录
  • Android系统开发与优化:从基础到高级实践
  • C++运行时多态深度解析:从原理到实践
  • 尝试 Gemini CLI 替代Claude,Jeecg skills基本通畅,但遇致命问题
  • 基于Ollama本地部署RVC相关大语言模型辅助工具链
  • CSS如何通过BEM提升质量_应用命名规范减少Bug产生
  • RTKLIB开发者笔记:如何为自定义RTCM3消息编写解析模块?
  • 从RTL到GDSII:UPF文件在DC综合与ICC布局布线中的“变形记”与协同要点