【reverse】逆向7 堆栈图

前言

本章就是开始画堆栈图来打基础拉,堆栈熟悉了之后就可以开始C语言的逆向了。

这一章使用的exe文件,我已经上传到了我的个人网盘中,点击下载

1、准备工作

先看这张内容

我们首先打开OD,使用F3打开helloworld.exe程序

然后在任意位置,ctrl+G打开窗口,输入0x401168地址,然后点击OK,自动跳转到这里

然后在这个地址上打一个断点(F2)

然后我们F9运行,让程序运行到这里

然后就是我们画堆栈图的时候了

2、画堆栈图

我们先在OD上看esp栈顶和ebp栈底的内存地址

根据这个内存地址我们可以画出开始时候的堆栈图(这里的黄色表示中间有一定距离,不是每格4字节)

然后我们运行push 0x2 和 push 0x1的汇编指令

运行之后的堆栈图变成了这样

然后下一步的汇编指令是call 0040100A,是我们刚刚学习的call指令,会让我们eip指向0040100A,也就是跳转到这里,并且将这个00401171地址push进堆栈中

我们这里按F7步入

所以堆栈图如下图

然后我们发现我们进入的地址0040100A的语句是jmp 00401040,也就是跳转到00401040,这里没有堆栈操作,我们直接F8步过

接下来我们jmp到了一段比较长的地方,这里我们逐步分析

首先是push ebp,这个操作让堆栈存入ebp的地址,而此时我们的ebp的地址为0019FF30,所以堆栈图如下

这一步执行完了之后,就是mov ebp,esp

这一步的的作用就是将esp的值传给ebp,让ebp = esp,堆栈图如下

然后是sub esp,0x40

这一步是让esp栈顶上升0x40个单位,也就是16个4字节,也就是在堆栈上升16位,堆栈图如下

然后就是push ebp,esi,edi,将ebp、esi、edi这些寄存器存放的东西放入堆栈中,起到保护现场的作用

堆栈图如下

下一步lea edi,dword ptr ss:[ebp-0x40],这句汇编就是让edi存储ebp-0x40之后的内存地址

当然,lea指令是不会影响堆栈的

这里的ebp-0x40是不是非常熟悉?就在刚才,esp也是减去了0x40

所以这个时候的堆栈图如下,edi是存储了0019FE94这个地址的

然后就是

mov ecx.0x10
mov eax,0xcccccccc
rep stos dword ptr es:[edi]

这三句话其实要一起说明

首先ecx是存储循环次数的寄存器,可以看出来这里循环0x10,也就是16次

然后执行mov eax,0xcccccccc,就是让eax这个寄存器存储0xcccccccc这个值

最关键的rep stos dword ptr es:[edi],就是让edi存储eax的值,每次存完的数都会根据DF标志寄存器来决定存储地址+-4,DF=0就是加,DF=1就是减

这上面三句就是重复16次,也就是让堆栈中存储16个缓冲,组成缓冲区

堆栈图如下

然后就是mov eax,dword ptr ss:[ebp+0x8],这句话就是让eax存储ebp+0x8地址中的数据,也就是我们最开始存储的1

add eax,dword ptr ss:[ebp+0xC],这句话就是让eax中原有的数据加上ebp+0xC地址中的数据,也就是我们最开始存储的2,所以eax中是1+2,现在eax=0x3

这一步,堆栈图没有发生改变,但是这两句话却是函数核心,就是两参数相加

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

然后就是pop edi,pip esi,pop ebx

这三句就是为了还原现场。

还记得我们在刚刚开始的时候push了这三个寄存器吗,现在我们把他们pop出来,还原到最开始的状态。

堆栈图如下

然后就是mov esp,ebp

这句话就是把ebp的值赋给esp,这样就是esp = ebp了

堆栈图如下

然后就是pop ebp,这句话就是把现在栈顶指向的返回地址pop给ebp

我们其实也记得,刚刚在call执行完,存完了紫色的返回地址之后,我们push了ebp

这个时候也就是让我们的ebp返回到原来的地址上去

堆栈图如下

然后就是函数的最后 retn

retn就相当于指令 pop eip,就是把返回地址给eip,而eip就是当前指向地址,这就是最后的返回地址

堆栈图如下

当我们执行完retn之后,发现我们的esp并没有回到函数开始前的模样,现在还在绿色的位置

而我们要知道,每个程序都保证了堆栈平衡,也就是,函数运行完了之后,esp和ebp的位置要和运行之前是保持一致的。

我们来看看retn完了之后,OD的页面

eip = 00401171

这里的add esp,0x8就是让esp的地址加8

这样我们的esp就回到了原来的位置,实现了堆栈平衡

这种在函数执行完了之后实现的堆栈平衡,叫做外平栈

即——谁调用函数,谁平衡堆栈

堆栈图如下

3、总结

首先我们认清计算机中函数的概念:

计算机的函数,是一个固定的一个程序段,或称其为一个子程序,它在可以实现固定运算功能的同时还带有一入口和一个出口,所谓的入口,就是函数所带的各个参数,我们可以通过这个入口,把函数的参数值代入子程序,然后根据出口返回

汇编中的函数:

来张好看点的

函数的入口

函数的出口

提醒:

  1. 这里ebp+4是返回地址(在pwn中是要考的!!!)

  2. 函数虽然有入口和出口,但是入口不一定需要传值,出口也不一定要返回(void)

  3. 传参不一定是push,还可能是寄存器传参等等...

  4. 返回值也不一定只通过寄存器返回,也可以通过内存返回

一张windows堆栈的补充图:

【reverse】逆向7 堆栈图的更多相关文章

  1. 【 D3.js 高级系列 — 3.0 】 堆栈图

    堆栈图布局(Stack Layout)能够计算二维数组每一数据层的基线,以方便将各数据层叠加起来.本文讲解堆栈图的制作方法. 先说说什么是堆栈图. 例如,有如下情况: 某公司,销售三种产品:个人电脑. ...

  2. 针对JCC指令练习的堆栈图

    堆栈图,主要目的就是练习一下JCC指令的熟练度,供参考 版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-10,23:41:41.作者By-----溺心与沉浮----博客园 ...

  3. 使用RetionalRose根据现有的java工程逆向生成类图

    1.进入RetionalRose选择J2EE模板 2.在菜单栏选择tools->java/j2EE->reverse engineer 3.编辑路径Edit CLASSPATH选择要生成类 ...

  4. 如何将C++代码逆向生成类图 (VS2013)

    1. 将代码添加到VS2013工程中: 2. 切换到"类视图": 3. 选中项目 右键"视图"->"查看类图". 如果项目文件太多的话 ...

  5. Mac逆向--思维导图

  6. 逆向学习周记-C语言空函数

    实验环境:WIN7虚拟机 软件:VC6 首先在VC6里面写一个空函数Fun(): F7编译运行一下,没有出错,接着在函数处使用F9下断点,使程序运行到Fun函数时停下. 接着F5开始运行这个程序 程序 ...

  7. FusionCharts-堆栈图、xml格式、刷新数据、添加事件link、传参

    *起因* 本来想用Chart.js来搞图表的, 但是来了个新需求,想搞的华丽点,毕竟对Chart.js来说,实现有点难度, *做出的改变* 最终选择了FusionCharts, *难点* 网上关于Fu ...

  8. 在 Visual Studio 中调试时映射调用堆栈上的方法

    本文转自:https://msdn.microsoft.com/zh-cn/library/dn194476.aspx 1.创建代码图,以便在调试时对调用堆栈进行可视化跟踪. 你可以在图中进行标注以跟 ...

  9. 20145230GDB调试汇编堆栈过程分析

    20145230GDB调试汇编堆栈过程分析 分析过程 出现的问题:一开始无法编译,是因为我们的Linux中没有安装一个库. 进入之前先设置断点,之后disassemble可以获取汇编代码,用i r指令 ...

随机推荐

  1. .NET 云原生架构师训练营(建立系统观)--学习笔记

    目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ...

  2. 极简!一个注解就能创建Jaeger的Span

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  3. 模仿写了一个摸鱼APP解决原作者的问题

    前几天见到微博里有人提到摸鱼APP,发现需要在windows store下载才可以使用,文件约100多M左右的样子,自已没有登录微软Store的习惯.想想只有一个介面,没有必要这么大,于是,自已动手写 ...

  4. 你假笨JVM参数 - 1 CMSScavengeBeforeRemark

    参数:-XX:CMSScavengeBeforeRemark含义:Enable scavenging attempts before the CMS remark step.开启或关闭在CMS重新标记 ...

  5. java 编程基础:注解(Annotation Processing Tool)注解处理器 利用注解解读类属性生成XML文件

    APT的介绍: APT(Annotation Processing Tool)是一种注解处理工具,它对源代码文件进行检测,并找出源文件所包含的注解信息,然后针对注解信息进行额外的处理. 使用APT工具 ...

  6. tcp十种状态;关于tcp中time_wait状态(2MSL问题)

    tcp十种状态 注意: 当一端收到一个FIN,内核让read返回0来通知应用层另一端已经终止了向本端的数据传送 发送FIN通常是应用层对socket进行关闭的结果 关于tcp中time_wait状态的 ...

  7. [源码解析] PyTorch 分布式之弹性训练(2)---启动&单节点流程

    [源码解析] PyTorch 分布式之弹性训练(2)---启动&单节点流程 目录 [源码解析] PyTorch 分布式之弹性训练(2)---启动&单节点流程 0x00 摘要 0x01 ...

  8. Vue2使用Axios发起请求教程详细

    当你看到该文章时希望你已知晓什么是跨域请求以及跨域请求的处理,本文不会赘述 本文后台基于Springboot2.3进行搭建,Controller中不会写任何业务逻辑仅用于配合前端调试 Controll ...

  9. JAVA删除某个文件夹(递归删除文件夹的所有文件)

    /** * 递归删除文件夹下所有内容 最后删除该文件夹 * @param filePath 要删除的文件夹路径 * @return */ public boolean deleteFiles(Stri ...

  10. 【LeetCode】344. Reverse String 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 新构建字符串 原地翻转 日期 题目地址:https://lee ...