GDB调试汇编堆栈分析
由于老师说要逐条分析汇编代码,所以我学习卢肖明同学的方法,重新写了一篇博客。
代码:
#include<stdio.h>
short addend1 = 1;
static int addend2 = 2;
const static long addend3 = 3;
static int g(int x)
{
return x + addend1;
}
static const int f(int x)
{
return g(x + addend2);
}
int main(void)
{
return f(8) + addend3;
}
GCC编译
使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器
注:这里在我第一次做的时候出现使用-m32指令报错的现象,使用sudo apt-get install libc6-dev-i386
命令安装所需库即可。
分析代码过程
首先进入gbd之后先在main函数处设置一个断点,再run一下,可以看到运行时在main函数位置停了下来
使用disassemble指令获取汇编代码
可见此时主函数的栈基址为0xffffd068,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0
依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
1、使用si指令单步跟踪一条机器指令
2、使用i r(info registers)指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)
3、使用x/na %esp对应的值指令查看堆栈变化
将上一个函数的基址入栈,从当前%esp开始作为新基址:
call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
先为传参做准备:
将栈中的数据push
leave返回准备栈
ret结束main函数
问题总结
在一开始忽略了一个步骤:使用display /i $pc
(结合display命令和寄存器/pc内部变量)指令进行设置,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。
由于没有设置这个步骤,每一次都要手工输入x/I $pc,非常麻烦,好在后来改正了。
这次的小实验让我对gdb有了深刻的理解,结合小明同学的博客,学习了gdb调试程序,设置断点等方法。其实感觉gdb在很多方面比图形调试界面还要好用,这可能就是命令行的魅力吧。
这三周被学校结核体检折磨的够呛,总是要去医院,还要被隔离,耽误了很多很多课。如果下周二体检通过没事情了的话,课程方面落下了好多,还要很努力的去追赶吧。
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 |