GDB调试汇编堆栈过程分析
测试代码
#include <stdio.h>
short val = 1;
int vv = 2;
int g(int xxx)
{
return xxx + vv;
}
static const int f(int xx)
{
return g(xx);
}
int main(void)
{
return f(9)+ val;
}
分析过程
-
通过
gcc - g gdb.c -o gdb -m32
指令在64位的机器上产生32位汇编 -
进入gdb调试,先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码
main函数汇编代码:
g函数汇编代码:
f函数汇编代码:
-
通过
info registers
列出使用的寄存器.
-
此时主函数的栈基址为
0xffffd028
,用x(examine)
指令查看内存地址中的值,目前%esp
所指堆栈内容为0,%ebp
所指内容也为0
-
结合
display
命令和寄存器或pc内部变量,做如下设置:display /i $pc
,其中$pc
代表当前汇编指令,/i
表示以十六进行显示。这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。
-
使用
si
执行下一条指令、%esp、%ebpinfo registers
和堆栈内容的变化x/na %esp
1.call将下一条指令的所在地址(即当时程序计数器PC的内容)入栈
2.将上一个函数的基址入栈,将当前%esp作为新基址
3.准备传参
4.call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:
6.执行g函数,g初始化栈指针
7.计算short+int
8.pop %ebp
指令将栈顶弹到%ebp中
9.ret返回g中call的调用位置
10.leave返回准备栈
11.ret结束main函数
12.%esp加立即数4
指令 | %eip | %esp | %ebp | %eax | 堆栈 |
---|---|---|---|---|---|
push $0x9 | 0x8048400 | 0xffffd024 | 0xffffd028 | 0xf7fb7dbc | 0x0 |
call 0x80483eb | 0x8048400 | 0xffffd020 | 0xffffd028 | 0xf7fb7dbc | 0x9 0x0 |
push %ebp | 0x80483eb | 0xffffd020 | 0xffffd028 | 0xf7fb7dbc | 0x8048405 0x9 0x0 |
mov %esp,%ebp | 0x80483ec | 0xffffd01c | 0xffffd028 | 0xf7fb7dbc | 0xffffd028 0x8048405 0x9 0x0 |
pushl 0x8(%ebp) | 0x80483ee | 0xffffd01c | 0xffffd01c | 0xf7fb8dbc | 0xffffd028 0x8048405 0x9 0x0 |
call 0x80483db | 0x80483f1 | 0xffffd018 | 0xffffd01c | 0xf7fb8dbc | 0x9 0xffffd028 0x8048405 0x9 0x0 |
push %ebp | 0x80483db | 0xffffd014 | 0xffffd01c | 0xf7fb8dbc | 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
mov %esp,%ebp | 0x80483dc | 0xffffd010 | 0xffffd01c | 0xf7fb8dbc | 0xffffd01c 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
mov 0x804a01c,%edx | 0x80483de | 0xffffd010 | 0xffffd010 | 0xf7fb7dbc | 0xffffd01c 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
mov 0x8(%ebp),%eax | 0x80483e4 | 0xffffd010 | 0xffffd010 | 0xf7fb7dbc | 0xffffd01c 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
add %edx,%eax | 0x80483e7 | 0xffffd010 | 0xffffd010 | 0x9 | 0xffffd01c 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
pop %ebp | 0x80483e9 | 0xffffd010 | 0xffffd010 | 0xb | 0xffffd01c 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
ret | 0x80483ea | 0xffffd014 | 0xffffd01c | 0xb | 0x80483f6 0x9 0xffffd028 0x8048405 0x9 0x0 |
add $0x4,%esp | 0x80483f6 | 0xffffd018 | 0xffffd01c | 0xb | 0x9 0xffffd028 0x8048405 0x9 0x0 |
leave | 0x80483f9 | 0xffffd01c | 0xffffd01c | 0xb | 0xffffd028 0x8048405 0x9 0x0 |
ret | 0x80483fa | 0xffffd020 | 0xffffd028 | 0xb | 0x8048405 0x9 0x0 |
add $0x4,%esp | 0x8048405 | 0xffffd024 | 0xffffd028 | 0xb | 0x9 0x0 |
mov %eax,%edx | 0x8048405 | 0xffffd028 | 0xffffd028 | 0xb | 0x0 |