GDB堆栈跟踪与汇编调试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GDB堆栈跟踪与汇编调试相关的知识,希望对你有一定的参考价值。

GDB堆栈跟踪与汇编调试

 

分析过程

?使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编 出现错误:fatal error

这时需要下载安装库文件

命令:sudo apt-get install libc6-dev-i386

之后再进行一次操作就可以产生汇编了

?使用gdb gdb1指令打开gdb调试器
技术分享

?使用break main指令在main函数处设置断点,并记得先用r指令运行代码,可以看到运行时在main函数位置停了下来,否则会出现如图的错误:

技术分享

?使用disassemble指令获取汇编代码(因为之前执行的命令中有-m32,所以此处显示的是32位汇编代码)

技术分享

?用i r指令查看各寄存器的值

技术分享

?可见此时主函数的栈基址为0xffffd068,用x 0xffffd068指令查看内存地址中的值:

技术分享

由此,当前%esp所指堆栈内容为0,%ebp所指内容也为0

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

技术分享

这使得在每次执行下一条汇编语句时,都会显示出当前执行的语句,方便查看。

?依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:

?(1)、使用si指令单步跟踪一条机器指令

?(2)、使用i r指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)

?(3)、使用x/na %esp对应的值指令查看堆栈变化

之后一直重复执行上述三步,直至结束

?main函数汇编代码

技术分享

?从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堆栈跟踪与汇编调试的主要内容,如果未能解决你的问题,请参考以下文章

如何获取 gdb 调用堆栈跟踪?

gdb 显示奇怪的堆栈跟踪

学汇编的时候可以拿IDA之类的反汇编工具辅助学习,再用gdb或者IDA动态调试,跟踪每条指令的 执行结果。都不难

在反汇编代码中跟踪调用堆栈

GDB 损坏的堆栈帧 - 如何调试?

深入理解Linux系统调用