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

    20145219 gdb调试汇编堆栈分析

    代码gdbdemo.c

    int g(int x)
    {
    	return x+19;
    }
    
    int f(int x)
    {
    	return g(x);
    }
    
    int main(void)
    {
    	return f(19)+19;
    }
    

    gcc编译gdbdemo.c

    • 使用gcc -g gdbdemo.c -o gdbdemo -m32命令在64位的机器上产生32位汇编代码

    • 在产生32位汇编代码时可能会出现如下错误:

    • 解决方法是在终端输入如下命令:sudo apt-get install libc6-dev-i386,安装一个库

    • 安装成功后再次执行gcc -g gdbdemo.c -o gdbdemo -m32命令就可以顺利进行下一步了

    gdb调试可执行文件gdbdemo

    • 使用gdb gdbdemo指令打开gdb调试器

    • 使用break main指令在main函数处设置断点(可以使用l指令在屏幕上打印代码),然后,使用r指令运行代码,可以看到运行时在main函数位置停了下来

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

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

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

      因此,目前%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函数汇编代码

    • f函数汇编代码

    • g函数汇编代码

    • 从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调试分析汇总表

    指令 %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

    参考资料

  • 相关阅读:
    【版本控制工具】 Git进阶1
    【版本控制工具】 Git基础
    问题:com.alibaba.dubbo.rpc.RpcException: Failed to invoke ......
    互联网安全架构之常见的Web攻击手段及解决办法
    【Spring Boot】七、整合actuator实现监控管理
    问题:tomcat启动后,可以访问主页面,但是无法访问dubbo-admin
    【Spring Boot】六、整合dubbo(注解的方式)
    这篇文章,彻底搞懂八大开源框架源码
    Spring Cloud Greenwich.SR4 发布了,跟不上了……
    手把手教你画架构图,看一次就会了!
  • 原文地址:https://www.cnblogs.com/20145219songge/p/6117547.html
Copyright © 2011-2022 走看看