GDB调试32位汇编堆栈分析

测试源代码

#include <stdio.h>

int g(int x){
return x+5;
} int f(int x){
return g(x)+3;
} int main(ing argv,char *argc[]){
return f(7)+19;
}
  • main函数汇编代码

  • g函数汇编代码

  • f函数汇编代码

调试过程

  • 在汇编调试中单步执行使用si,而display /i $pc该语句可以使得我们每一次单步执行时输出正在执行的语句,i r $xxx则可以输出对应的寄存器中的值,方便我们跟踪调试

  • 根据代码,我们可以知道主函数只有return f(7)+19,在主函数中设下断点,可见当时%eip,%ebp,%esp,%eax的值(%eip为当前执行的指令的地址,%eax用于实参存储,计算,%ebp、%esp用于存储栈指针地址)

  • 调用f函数,call指令将会将下一条指令的地址入栈,且此时esp将会减4

  • 将eip中的值入栈,且此时esp已经发生了变化

  • 将上一个函数的基址入栈,当前%esp作为新基址

  • %esp的值减4,将值传入%eax中,并不是太懂这几步到底有什么具体的作用,只知道最后的值实在%eax中进行计算的,大概这几步是为了最后计算做准备





  • call指令将下一条指令地址入栈,开始调用函数g()

  • 地址入栈

  • 这几步和之前调用函数f()那几步作用应该是一样的,可能是传参用途(图值9、10)



  • 实参在%eax中进行计算

  • 出栈,将地址弹到%ebp中

  • ret指令将之前入栈的代码地址弹回%eip中,继续执行函数f()

  • 回到f函数中,进行实参的计算,然后出站,ret将代码地址弹回%eip,继续执行主函数main





  • 在主函数中完成计算,之后代码结束





堆栈分析

指令 %esp %ebp %eip %eax 堆栈
movl $0x7,(%esp) 0xbffff074 0xbffff078 0x8048414 0x1 0x0
call 0x80483f8 0xbffff074 0xbffff078 0x804841b 0x1 0x0
push %ebp 0xbffff070 0xbffff078 0x80483f8 0x1 0x8048420 0x0
mov %esp,%ebp 0xbffff06c 0xbffff078 0x80483f9 0x1 0xbffff078 0x8048420 0x0
sub $0x4,%esp 0xbffff06c 0xbffff06c 0x80483fb 0x1 0xbffff078 0x8048420 0x0
mov 0x8(%ebp),%eax 0xbffff068 0xbffff06c 0x80483fe 0x1 0xbffff078 0x8048420 0x0
mov %eax,(%esp) 0xbffff068 0xbffff06c 0x8048401 0x7 0xbffff078 0x8048420 0x0
call 0x80483ed 0xbffff068 0xbffff06c 0x8048404 0x7 0xbffff078 0x8048420 0x0
push %ebp 0xbffff064 0xbffff06c 0x8048404 0x7 0x8048409 0xbffff078 0x8048420 0x0
mov %esp,%ebp 0xbffff060 0xbffff06c 0x80483ee 0x7 0xbffff06c 0x8048409 0xbffff078 0x8048420 0x0
mov 0x8(%ebp),%eax 0xbffff060 0xbffff060 0x80483f0 0x7 0xbffff06c 0x8048409 0xbffff078 0x8048420 0x0
add $0x5,%eax 0xbffff060 0xbffff060 0x80483f3 0x7 0xbffff06c 0x8048409 0xbffff078 0x8048420 0x0
pop %ebp 0xbffff060 0xbffff060 0x80483f6 0x12 0xbffff06c 0x8048409 0xbffff078 0x8048420 0x0
ret 0xbffff064 0xbffff06c 0x80483f7 0x12 0x8048409 0xbffff078 0x8048420 0x0
add $0x3,%eax 0xbffff068 0xbffff06c 0x8048409 0x12 0xbffff078 0x8048420 0x0
leave 0xbffff068 0xbffff06c 0x804840c 0x15 0xbffff078 0x8048420 0x0
ret 0xbffff070 0xbffff078 0x804840d 0x15 0x8048420 0x0
add $0x13,%eax 0xbffff074 0xbffff078 0x8048420 0x15 0x0
leave 0xbffff074 0xbffff078 0x8048423 0x22 0x0
ret 0xbffff07c 0x0 0x8048424 0x22 0x0

GDB调试32位汇编堆栈分析的更多相关文章

  1. 20145314郑凯杰《信息安全系统设计基础》GDB调试32位汇编堆栈分析

    20145314郑凯杰<信息安全系统设计基础>GDB调试32位汇编堆栈分析 本篇博客将对第五周博客中的GDB调试32位汇编堆栈进行分析 首先放上以前环境配置的图: 图1: 测试代码: #i ...

  2. gdb运行时结合汇编堆栈分析

    一.从源代码文件到可执行文件         从C文件到可执行文件,一般来说需要两步,先将每个C文件编译成.o文件,再把多个.o文件和链接库一起链接成可执行文件.但具体来说,其实是分为四步,下面以ex ...

  3. 20145318 GDB调试汇编堆栈分析

    20145318 GDB调试汇编堆栈分析 代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const sta ...

  4. 20145219 gdb调试汇编堆栈分析

    20145219 gdb调试汇编堆栈分析 代码gdbdemo.c int g(int x) { return x+19; } int f(int x) { return g(x); } int mai ...

  5. gdb调试汇编堆栈分析

    代码(src/05/gdb.c) int g(int x) { return x + 4; } int f(int x) { return g(x); } int main(void) { retur ...

  6. 20145310 GDB调试汇编堆栈分析

    GDB调试汇编堆栈分析 由于老师说要逐条分析汇编代码,所以我学习卢肖明同学的方法,重新写了一篇博客. 代码: #include<stdio.h> short addend1 = 1; st ...

  7. 32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用

    32位汇编第一讲x86和8086的区别,以及OllyDbg调试器的使用 一丶32位(x86也称为80386)与8086(16位)汇编的区别 1.寄存器的改变 AX 变为 EAX  可以这样想,16位通 ...

  8. 32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式

    32位汇编第三讲,RadAsm,IDE的配置和使用,以及汇编代码注入方式 一丶RadAsm的配置和使用 用了怎么长时间的命令行方式,我们发现了几个问题 1.没有代码提醒功能 2.编写代码很慢,记不住各 ...

  9. 32位汇编第四讲,干货分享,汇编注入的实现,以及快速定位调用API的数量(OD查看)

    32位汇编第四讲,干货分享,汇编注入的实现,以及快速定位调用API的数量(OD查看) 昨天,大家可能都看了代码了,不知道昨天有没有在汇编代码的基础上,实现注入计算器. 如果没有,今天则会讲解,不过建议 ...

随机推荐

  1. nginx负载均衡基于ip_hash的session粘帖

    nginx负载均衡基于ip_hash的session粘帖 nginx可以根据客户端IP进行负载均衡,在upstream里设置ip_hash,就可以针对同一个C类地址段中的客户端选择同一个后端服务器,除 ...

  2. laravel 输出sql

    $queries = DB::getQueryLog(); $a = end($queries); $tmp = str_replace('?', '"'.'%s'.'"', $a ...

  3. js颠倒数组元素顺序reverse()

    颠倒数组元素顺序reverse() reverse() 方法用于颠倒数组中元素的顺序. 语法: arrayObject.reverse() 注意:该方法会改变原来的数组,而不会创建新的数组. 定义数组 ...

  4. dataset 修改小数点位数

    #region dataset过滤器(修改小数点位数)导出使用 public DataSet ChangeDataSetValue(DataSet dataset) { foreach (DataTa ...

  5. 【MongoDB】递归获取字段更新表达式,更新复杂数据类型对象

    在实际更新Mongo对象时发现,原有的更新代码无法更新复杂的数据类型对象.恰好看到张占岭老师有对该方法做相关的改进,因此全抄了下来. 总的核心思想就是运用反射与递归,对对象属性一层一层挖掘下去,循环创 ...

  6. 以前用SQL实现的机构职能树,再看看

    DECLARE CNT NUMBER; TMP ); vtmp ); ltmp1 ); ltmp2 ); ltmp3 ); ltmp4 ); NTMP NUMBER; CURSOR CSR_TEST ...

  7. 给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。

    题目描述: 给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除. 输入: 两个整数n(2<=n<=1000),a(2<=a<=1000) 输出: 一个整数. ...

  8. IBatis.Net使用总结(二)-- IBatis返回DataTable/DataSet(网上例子的集合)

    IBatis返回DataTable,DataSet ibatis.net QueryForDataTable 完整的为ibatis.net 引入datatable支持要改动很多地方,所以描述的是最小化 ...

  9. idapython在样本分析中的使用-字符解密

    最近接手的一个样本,样本中使用了大量的xor加密,由于本身样本不全,无法运行(好吧我最稀饭的动态调试没了,样本很有意思,以后有时间做票大的分析),这个时候就只好拜托idapython大法了(当然用id ...

  10. 分布式缓存技术redis学习系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...