GDB调试汇编堆栈过程分析

GDB调试汇编堆栈过程分析

代码如下:

 

 

使用gcc –S –o 20145211shiyanlou.s  20145211.c -m32编译

  • 20145211shiyanlou.s文件如下:

     

删除gcc产生代码中以"."开头的编译器指令,分析汇编语言

 

    1. 保存%ebp,并设置新的帧指针

    2. pushl $8分配4字节的栈空间

    3. call调用f,f初始化帧指针,分配栈空间

    4. 在f中第六句call调用g,g被调用,初始化栈指针,分配栈空间,将%eax与立即数15相加,弹栈

    5. 执行ret返回f中call的调用位置

    6. f结束,返回main中call调用的位置

    7. main %eax加15

    8. leave为返回准备栈,相当于%ebp出栈,最后ret结束gdb调试可执行文件

 

gdb调试可执行文件

  • 使用gdb gdbdemo指令打开gdb调试器

  • 使用break main指令在main函数处设置断点(可以使用l指令在屏幕上打印代码),然后,使用r指令运行代码,可以看到运行时在main函数位置停了下来;并使用disassemble指令获取汇编代码(因为之前执行的命令中有-m32,所以此处显示的是32位汇编代码)


  • 使用display /i $pc(结合display命令和寄存器/pc内部变量)指令进行设置

  • 可见此时主函数的栈基址为0xffffd068,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0
  • 用i r指令查看各寄存器的值
  • 依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
  • 1、使用si指令单步跟踪一条机器指令
  • 2、使用i r指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)
  • 3、使用x/na %esp对应的值指令查看堆栈变化
  • 之后一直重复执行上述三步,直至结束
  • call调用f(0x80483ef)

     

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

  • call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:0xffffcfa0,0xffffcfa8

     

  • 为传参做准备,将0x804a01c的值存入%edx中
  • 将栈中的数据push
  • leave返回准备栈ret结束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

总结体会

  这次的学习虽然还未完全掌握利用gdb对汇编代码的调试,但使我对gdb有了更深的认识。汇编代码是一种机器语言,理解起来较为困难,没有高级语言那样容易。

  不过万变不离其宗,只要肯下功夫,还是可以取得较大收获的。

posted @ 2016-11-29 17:57  20145211  Views(319)  Comments(2Edit  收藏  举报