zoukankan      html  css  js  c++  java
  • 20145310 GDB调试汇编堆栈分析

    GDB调试汇编堆栈分析

    由于老师说要逐条分析汇编代码,所以我学习卢肖明同学的方法,重新写了一篇博客。

    代码:

    #include<stdio.h>
    
    short addend1 = 1;
    static int addend2 = 2;
    const static long addend3 = 3;
    
    static int g(int x)
    {
    	return x + addend1;
    }  
    
    static const int f(int x)
    {
    	return g(x + addend2);
    }
    
    int main(void)
    {
    	return f(8) + addend3;
    }
    

    GCC编译

    使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器

    注:这里在我第一次做的时候出现使用-m32指令报错的现象,使用sudo apt-get install libc6-dev-i386命令安装所需库即可。

    分析代码过程

    首先进入gbd之后先在main函数处设置一个断点,再run一下,可以看到运行时在main函数位置停了下来

    使用disassemble指令获取汇编代码

    可见此时主函数的栈基址为0xffffd068,用x(examine)指令查看内存地址中的值,但目前%esp所指堆栈内容为0,%ebp所指内容也为0

    依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:
    1、使用si指令单步跟踪一条机器指令
    2、使用i r(info registers)指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)
    3、使用x/na %esp对应的值指令查看堆栈变化

    将上一个函数的基址入栈,从当前%esp开始作为新基址:

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

    先为传参做准备:

    将栈中的数据push

    leave返回准备栈

    ret结束main函数

    问题总结

    在一开始忽略了一个步骤:使用display /i $pc(结合display命令和寄存器/pc内部变量)指令进行设置,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。
    由于没有设置这个步骤,每一次都要手工输入x/I $pc,非常麻烦,好在后来改正了。

    这次的小实验让我对gdb有了深刻的理解,结合小明同学的博客,学习了gdb调试程序,设置断点等方法。其实感觉gdb在很多方面比图形调试界面还要好用,这可能就是命令行的魅力吧。
    这三周被学校结核体检折磨的够呛,总是要去医院,还要被隔离,耽误了很多很多课。如果下周二体检通过没事情了的话,课程方面落下了好多,还要很努力的去追赶吧。

    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
  • 相关阅读:
    Linux环境下安装jdk1.8(CentOS7)
    MySQL创建外键报错ERROR 3780 (HY000): Referencing column ‘user_id’ and referenced column ‘id’ in foreign key constraint ‘fk_user_id’ are incompatible.
    scrapy框架的使用
    开源《热血传奇》服务端引擎(C#编写),可以顺利进行游戏(更新编译和部署教程)
    记录一下今天刚开通的博客
    Sql Server 2005中还原整个数据库重命名问题
    第一次学开车
    转载:c#与ASP.NET中DateTime.Now函数详解
    winform进度条收藏
    今天新注册的,庆祝一下
  • 原文地址:https://www.cnblogs.com/pigeondandelion/p/6130033.html
Copyright © 2011-2022 走看看