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 ...
随机推荐
- 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则
第10章 LSP:Liskov替换原则 Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...
- Visual Studio发布Web项目报错:Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The specified file could not be encrypted.
背景 Visual Studio下的Web项目 现象 发布时遇到Unable to add 'xxx' to the Web site. Unable to add file 'xxx'. The ...
- 每日Scrum--No.7
Yesterday:学习和设计路线的编程 Today:编写代码 Problem:.在设计查询参观路线的时候,整个逻辑特别的混乱,设想了各种树,图以及网的遍历问题,但经过多次与同学的交流以及网上的查询资 ...
- 【转】App开发者必备的运营、原型、UI设计工具整理
一.运营类 1. APPVIEW,网址:http://lab.hakim.se/appview/ 帮助iOS 应用开发者追踪所有地区App Store最近的用户评论,可以按时间.评分.地区排序,缺点是 ...
- 烂泥:【解决】Ubuntu下使用SSH连接centos系统很慢
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 这几天在Ubuntu下使用SSH连接centos系统,发现连接很慢.建议一个连接大约需要30s.很是坑爹,如下: 后来查询相关资料,发现这个是Ubunt ...
- Redis系列(一)——简介及安装
摘自:redis中文网(http://www.redis.net.cn/) 参考:http://www.cnblogs.com/hoojo/p/4466024.html,http://keenwon. ...
- 精----Java读取xml文件的四种方法
xml文件: Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT> <VA ...
- c++ initialize_list
看到这么一个东西,可以实现花括号( "{" "}" )初始化容器类. 使用时需包含头文件 #include <initialize_list> 我们 ...
- C语言使用宏实现2个变量的交换
记录哪个方法更普适,更高效,这些方法不包括使用函数的方法,如果使用函数的话,使用指针的方法更合适. 使用中间变量 形如 int tmp, tmp = a; a=b; b = tmp; #define ...
- SQL Server 2012 AlwaysOn集群配置指南
1. AlwaysOn介绍 AlwaysOn是SQL Server 2012提供的全新综合.灵活.高效经济的高可用性和灾难恢复解决方案.它整合了镜像和群集的功能,基于OS 故障转移群集(Windows ...