20145312 GDB调试汇编堆栈过程分析

本文详细介绍了使用GDB调试器分析C程序的汇编堆栈过程,包括编写C程序、生成汇编文件、反汇编、设置断点、查看寄存器值及跟踪函数调用堆栈变化等关键步骤。

20145312 GDB调试汇编堆栈过程分析

参考资料

卢肖明同学的博客:《GDB调试汇编堆栈过程分析》: http://www.cnblogs.com/lxm20145215----/p/5982554.html

分析过程

  • 使用vim example.c命令编写C程序
    885499-20161203185216381-1926032786.png

  • 保存退出后使用gcc -S example.c命令生成example.s文件,并使用cat example.s命令查看汇编文件
    885499-20161203185546568-723136438.png
    885499-20161203185558490-526767845.png

  • 打开example.s文件进行修改:删去所有.*的语句,并保存,再次使用cat example.s命令查看汇编代码
    885499-20161203185812959-1317702281.png

  • 使用gcc example.c -o example生成example.o文件,并使用objdump -d example命令进行反汇编
    885499-20161203190216521-741273074.png
  • 这里出现了一个错误:我先是按照书上的步骤输入objdump -d example.o命令进行反汇编,出现错误:objdump:example.o:无此文件,于是我打开目录文件夹,发现example.o文件的命名为example,重新修改命令,成功。
  • 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器
    885499-20161203191000240-274746507.png
    885499-20161203191012427-1026754312.png
  • 进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:
    877166-20161020190739420-1434552985.png
    877166-20161020190933045-676608455.png
  • 使用display /i $pc命令,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。
    cSHGdrW.png?_=6123266
    Mg8fglj.png?_=6123266
  • 执行call指令将下一条指令的地址入栈
    Det4GeF.png?_=6123266
    7mMh0jP.png?_=6123266
    r0s4mcb.png?_=6123266
    SnIVipr.png?_=6123266

分析如下
  • 从main:开始执行,保存%ebp,并设置新的帧指针
 pushl   %ebp
 movl    %esp,%ebp
  • pushl $8分配4字节的栈空间,并且设置arg1=8,相当于
subl    $4,%esp
movl    $8,(%esp)
  • call调用b,b同样初始化帧指针,分配栈空间
pushl   %ebp
movl    %esp,%ebp
  • pushl 8(%ebp)将%esp中的8存入栈中,相当于
subl    $4,%esp
movl    8(%ebp),%eax
  • call调用a,a被调用,初始化栈指针,分配栈空间,将 %eax 与立即数 1 相加
addl    $1,%eax

分析如下

  • 从main:开始执行,保存%ebp,并设置新的帧指针
 pushl   %ebp
 movl    %esp,%ebp
  • pushl $8分配4字节的栈空间,并且设置arg1=8,相当于
subl    $4,%esp
movl    $8,(%esp)
  • call调用b,b同样初始化帧指针,分配栈空间
pushl   %ebp
movl    %esp,%ebp
  • pushl 8(%ebp)将%esp中的8存入栈中,相当于
subl    $4,%esp
movl    8(%ebp),%eax
  • call调用a,a被调用,初始化栈指针,分配栈空间将 %eax 与立即数 1 相加
addl    $1,%eax
  • 在a结束前弹栈
popl    %ebp
  • ret返回b中call的调用位置
  • b也结束,return返回main中call调用的位置
  • main继续 %eax 加14的操作
addl    $14,%eax
  • leave为返回准备栈,相当于%ebp出栈,最后ret结束
popl    %ebp
  • ret返回b中call的调用位置
  • b也结束,return返回main中call调用的位置
  • main继续 %eax 加14的操作
addl    $14,%eax
  • leave为返回准备栈,相当于%ebp出栈,最后ret结束
执行过程中%ebp、%esp、堆栈值的变化
指令%esp%ebp堆栈
push $0x80xbffff0980xbffff0980x0
call 0x80484010xbffff0940xbffff0980x8 0x0
push %ebp0xbffff0900xbffff0980x8048412 0x8 0x0
mov %esp,%ebp0xbffff08c0xbffff0980xffffd068 0x8048412 0x8 0x0
mov 0x804a020,%edx0xbffff08c0xbffff08c0xffffd068 0x8048412 0x8 0x0
call 0x80483ed0xbffff0880xbffff08c0xa 0xffffd068 0x8048412 0x8 0x0
push %ebp0xbffff0840xbffff08c0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
mov %esp,%ebp0xbffff0800xbffff08c0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
Pop %ebp0xbffff0800xbffff0800xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
ret0xbffff0840xbffff08c0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0
leave0xbffff09c0xbffff08c0xffffd068 0x8048412 0x8 0x0
ret0xbffff0900xbffff0980x8048412 0x8 0x0
add $0x4,%esp0xbffff0940xbffff0980x8 0x0
mov $0x3,%edx0xbffff0980xbffff0980x0
ret0xbffff09c0x0

转载于:https://www.cnblogs.com/yx20145312/p/6129455.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值