20145219 gdb调试汇编堆栈分析
20145219 gdb调试汇编堆栈分析
代码gdbdemo.c
int g(int x)
{
return x+19;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(19)+19;
}
gcc编译gdbdemo.c
使用
gcc -g gdbdemo.c -o gdbdemo -m32命令在64位的机器上产生32位汇编代码在产生32位汇编代码时可能会出现如下错误:

解决方法是在终端输入如下命令:
sudo apt-get install libc6-dev-i386,安装一个库

安装成功后再次执行
gcc -g gdbdemo.c -o gdbdemo -m32命令就可以顺利进行下一步了
gdb调试可执行文件gdbdemo
使用
gdb gdbdemo指令打开gdb调试器

使用
break main指令在main函数处设置断点(可以使用l指令在屏幕上打印代码),然后,使用r指令运行代码,可以看到运行时在main函数位置停了下来

使用
disassemble指令获取汇编代码(因为之前执行的命令中有-m32,所以此处显示的是32位汇编代码)

用
i r指令查看各寄存器的值

可见此时主函数的栈基址为0xffffd058,用
x 0xffffd058指令查看内存地址中的值:

因此,目前%esp所指堆栈内容为0,%ebp所指内容也为0
,使用
display /i $pc(结合display命令和寄存器/pc内部变量)指令进行设置

这使得在每次执行下一条汇编语句时,都会显示出当前执行的语句,方便查看。
依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
- 1、使用
si指令单步跟踪一条机器指令 - 2、使用
i r指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp) - 3、使用
x/na %esp对应的值指令查看堆栈变化
之后一直重复执行上述三步,直至结束
- 1、使用
main函数汇编代码

f函数汇编代码

g函数汇编代码

从main函数开始,
push $0x13分配4字节的栈空间,并且设置arg1=19


call调用f(0x80483e6)

执行f函数,f初始化帧指针,将上一个函数的基址入栈,将当前%esp作为新基址

f分配栈空间,为传参做准备

pushl 0x8(%ebp)将%esp中的8存入栈中

call调用g(0x80483db)

执行g函数,g初始化栈指针

g分配栈空间

pushl 0x8(%ebp)将%esp中的8存入栈中

将 %eax 与立即数 19 相加

pop %ebp在g结束前弹栈

ret返回g中call的调用位置,结束g函数

将 %esp 与立即数 4 相加

leave返回准备栈

ret返回f中call的调用位置,结束f函数

进入main函数,将 %esp 与立即数 4 相加

将 %eax 与立即数 19 相加

leave返回准备栈

ret结束main函数

gdb调试分析汇总表
| 指令 | %eip | %ebp | %esp | %eax | 堆栈 |
|---|---|---|---|---|---|
| push $0x13 | 0x80483f9 | 0xffffd058 | 0xffffd058 | 0xf7fbadbc | 0x00000000 |
| call 0x80483e6 | 0x80483fb | 0xffffd058 | 0xffffd054 | 0xf7fbadbc | 0x13 0x0 |
| push %ebp | 0x80483e6 | 0xffffd058 | 0xffffd050 | 0xf7fbadbc | 0x8048400 0x13 0x0 |
| mov %esp,%ebp | 0x80483e7 | 0xffffd058 | 0xffffd04c | 0xf7fbadbc | 0xffffd058 0x8048400 0x13 0x0 |
| pushl 0x8(%ebp) | 0x80483e9 | 0xffffd04c | 0xffffd04c | 0xf7fbadbc | 0xffffd058 0x8048400 0x13 0x0 |
| call 0x80483db | 0x80483ec | 0xffffd04c | 0xffffd048 | 0xf7fbadbc | 0x13 0xffffd058 0x8048400 0x13 0x0 |
| push %ebp | 0x80483db | 0xffffd04c | 0xffffd044 | 0xf7fbadbc | 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| mov %esp,%ebp | 0x80483dc | 0xffffd04c | 0xffffd040 | 0xf7fbadbc | 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| mov 0x8(%ebp),%eax | 0x80483de | 0xffffd040 | 0xffffd040 | 0xf7fbadbc | 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| add $0x13,%eax | 0x80483e1 | 0xffffd040 | 0xffffd040 | 0x13 | 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| pop %ebp | 0x80483e4 | 0xffffd040 | 0xffffd040 | 0x26 | 0xffffd04c 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| ret | 0x80483e5 | 0xffffd04c | 0xffffd044 | 0x26 | 0x80483f1 0x13 0xffffd058 0x8048400 0x13 0x0 |
| add $0x4,%esp | 0x80483f1 | 0xffffd04c | 0xffffd048 | 0x26 | 0x13 0xffffd058 0x8048400 0x13 0x0 |
| leave | 0x80483f4 | 0xffffd04c | 0xffffd04c | 0x26 | 0xffffd058 0x8048400 0x13 0x0 |
| ret | 0x80483f5 | 0xffffd058 | 0xffffd050 | 0x26 | 0x8048400 0x13 0x0 |
| add $0x4,%esp | 0x8048400 | 0xffffd058 | 0xffffd054 | 0x26 | 0x13 0x0 |
| add $0x13,%eax | 0x8048403 | 0xffffd058 | 0xffffd058 | 0x26 | 0x0 |
| leave | 0x8048406 | 0xffffd058 | 0xffffd058 | 0x39 | |
| ret | 0x8048407 | 0x0 | 0xffffd05c | 0x39 |
参考资料
20145219 gdb调试汇编堆栈分析的更多相关文章
- 20145318 GDB调试汇编堆栈分析
20145318 GDB调试汇编堆栈分析 代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const sta ...
- 20145310 GDB调试汇编堆栈分析
GDB调试汇编堆栈分析 由于老师说要逐条分析汇编代码,所以我学习卢肖明同学的方法,重新写了一篇博客. 代码: #include<stdio.h> short addend1 = 1; st ...
- gdb调试汇编堆栈分析
代码(src/05/gdb.c) int g(int x) { return x + 4; } int f(int x) { return g(x); } int main(void) { retur ...
- GDB调试汇编堆栈
GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...
- GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...
- 20145212——GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...
- gdb调试汇编堆栈过程的学习
gdb调试汇编堆栈过程的学习 以下为C源文件 使用gcc - g code.c -o code -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 进入之 ...
- 20145223《信息安全系统设计基础》 GDB调试汇编堆栈过程分析
20145223<信息安全系统设计基础> GDB调试汇编堆栈过程分析 分析的c语言源码 生成汇编代码--命令:gcc -g example.c -o example -m32 进入gdb调 ...
- 20145337 GDB调试汇编堆栈过程分析
20145337 GDB调试汇编堆栈过程分析 测试代码 #include<stdio.h> short addend1 = 1; static int addend2 = 2; const ...
随机推荐
- XP重装之后蓝屏
最近帮公司的电脑重装XP系统,发现重装之后电脑重启的时候蓝屏 解决方法:开机-->f2-->找到SATA Configration --> 选择ide 重启,就ok了
- Effective Java 30 Use Enums instead of int constants
Enumerated type is a type whose legal values consist of a fixed set of constants, such as the season ...
- PHP模拟发送POST请求之四、加强file_get_contents()发送POST请求
使用了笨重fsockopen()方法后,我们开始在PHP函数库里寻找更简单的方式来进行POST请求,这时,我们发现了PHP的文件函数也具有与远程URL交互的功能. 最简单的是fopen()和fread ...
- 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
一.access_token简介 为了使第三方开发者能够为用户提供更多更有价值的个性化服务,微信公众平台 开放了许多接口,包括自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等, 开 ...
- 计算几何 平面最近点对 nlogn分治算法 求平面中距离最近的两点
平面最近点对,即平面中距离最近的两点 分治算法: int SOLVE(int left,int right)//求解点集中区间[left,right]中的最近点对 { double ans; //an ...
- java lambda小纪
一个通俗的说法是 :C#委托和Java中实现了 函数式编程的方法,它是函数式编程中的概念,为了更快的处理集合,在Java,c#等静态类型语言中想要引用一个函数的一种方式,(实现了通过封装匿名方法来达到 ...
- mvc area区域和异步表单,bootstrap简单实例
码农最怕眼高手低 今天来练习mvc Area技术和bootstrap以及异步表单的C#代码实现. 1.area区域架构对于建立复杂业务逻辑很有帮助,由 AreaRegistration.Regist ...
- 边工作边刷题:70天一遍leetcode: day 86-2
Best Meeting Point 要点: 题本身不难理解,manhattan distance.follow up就变成weighted了(因为一个地方可以有多个住户) 注意input是grid的 ...
- 如何解决inline-block元素的空白间距
早上在博客中有人提了这样一个问题:“li元素inline-block横向排列,出现了未知间隙”,我相信大家在写页面的时候都遇到过这样的情况吧. 我一般遇到这情况都会把li浮动起来,这样就没有间隙.但是 ...
- HDU 3333 Turing Tree --树状数组+离线处理
题意:统计一段序列[L,R]的和,重复元素只算一次. 解法:容易看出在线做很难处理重复的情况,干脆全部讲查询读进来,然后将查询根据右端点排个序,然后离散化数据以后就可以操作了. 每次读入一个数,如果这 ...