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 ...
随机推荐
- Effective Java 62 Document all exceptions thrown by each method
Principle Always declare checked exceptions individually, and document precisely the conditions unde ...
- 学习HTML5必读之《HTML5设计原理》
引子:很久前看过的一遍受益匪浅的文章,今天再次转过来,希望对学习HTML5的朋友有所帮助. 今天我想跟大家谈一谈HTML5的设计.主要分两个方面:一方面,当然了,就是HTML5.我可以站在这儿只讲HT ...
- js日期时间函数
日期时间脚本库方法列表 Date.prototype.isLeapYear 判断闰年Date.prototype.Format 日期格式化Date.prototype.DateAdd 日期计算Date ...
- JSP过滤器Filter配置过滤类型汇总
一.配置方法1 映射过滤应用程序中所有资源<filter> <filter-name>loggerfilter</filter-name> <fi ...
- jQuery form插件的使用--ajaxForm()和ajaxSubmit()的可选参数项对象
一.前提说明 Form Plugin API 里提供了很多有用的方法可以让你轻松的处理表单里的数据和表单的提交过程. 测试环境:部署到Tomcat中的web项目. 二.简单介绍 本文演示的是:jQue ...
- sql 查询基本语法
1.计算列 select * from emp --*表示所有的 --from emp 表示从emp表查询 select empno,enam ...
- How to use python remove the '^M' when copy words from Windows to Linux
今天帮同事用Python写了一个小工具,实现了在linux下批量文件名和去掉windows 文件到linux过程中产生^M的脚本,代码如下: !/opt/exptools/bin/python imp ...
- GitHub中wiki的Markdown编辑方法!!
Hello MarkDown!正常的文本 一级大标题用一个#号 一级中等标题用两个#号 一级小标题用三个#号(一次类推,一共有6级标题) 下面是无序列表 无序标题1-只需要在标题前面加上*号就可以了或 ...
- 两台SQL Server数据同步解决方案
复制的概念 复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式.使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可 ...
- Start cluster zookeeper in shell script
cat start-zookeeper.sh #!bin/sh for node in namenode01 datanode01 datanode02 do echo "s ...