• 20145212——GDB调试汇编堆栈过程分析


    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
  • 相关阅读:
    HBase Flush 机制
    HBase 预分区 & Phoenix 加盐
    Phoenix 索引
    python 列表、元组、字典、集合的比较操作
    Redis HA
    基于 Redis 和 ZooKeeper 的分布式锁
    Ubuntu 系统设置 Swappiness 值
    Ubuntu_16.04 安装 Pyhon3.6
    Win10创意者更新秋季版升级常见问题解决方案
    如何使用注册表在Win10中调整屏幕亮度
  • 原文地址:https://www.cnblogs.com/alovera/p/6131338.html
Copyright © 2020-2023  润新知