zoukankan      html  css  js  c++  java
  • 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有了更深的认识。汇编代码是一种机器语言,理解起来较为困难,没有高级语言那样容易。

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

  • 相关阅读:
    用Sklearn画一颗决策树
    硬核机器学习干货,手把手教你写KNN!
    nginx源码分析源码结构
    linux流量监控iftop命令安装详解
    fping简介及使用方法
    进程与线程的区别(网络摘抄)
    linux nload命令简介及安装方法
    php中heredoc使用方法
    201920201学期 20192430 《网络空间安全专业导论》第一周学习总结1
    五种I/O模型
  • 原文地址:https://www.cnblogs.com/nostalgia-/p/6114629.html
Copyright © 2011-2022 走看看