使用gdb打印寄存器和地址的值

一、文件介绍:

1、源码

#include <stdio.h>

// 演示函数参数的传递过程
// 可以使用vscdoe调试,或者gdb调试
// 编译命令 icx test1.c -o test1 -g -O0 -static

int mytest(int rdi, int rsi, int rdx, int rcx, int r8, int r9, int rsp8, int rsp9) {
    
    
    if (rdi==1){
    
    
        return rdi+rsi+rdx+rcx+r8+r9+rsp8+rsp9;
    } else {
    
    
        return 1;
    }
}

void mytest2(int *a) {
    
    
    int b[8];
    for (int i=0; i<8; i++){
    
    
        b[i] = a[i];
    }
}

int main()
{
    
    
    int a[8] = {
    
    1, 2, 3, 4, 5, 6, 7, 8};
    int sum = mytest(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
    mytest2(a);

    return 0;
}

2、目标文件test1

编译命令

icx test1.c -g -O0 -static -o test1
或者 gcc test1.c -g -O0 -static -o test1

使用IDA PRO可以查看目标文件的反汇编,在函数列表那里可以搜索main函数,切换到汇编的窗口。如图
在这里插入图片描述
同理,可以查看mytest函数和mytest2函数的汇编。当然也可以,双击main函数里的mytest来进行函数跳转
在这里插入图片描述

3、使用dynamorio工具生成的注释文件(后面简称它注释文件吧)

我之前写了个小工具,用于自动打印每条汇编对应的寄存器的值,工具链接
假设生产的文件名为test1.asm

二、使用gdb调试目标文件

主要参考之前gdb调试的文档,此处略写

1、设置断点

$ b main
$ b mytest
$ b mytest2
$ info b

2、设置汇编格式为intel

$ set disassembly-flavor intel 

在这里插入图片描述

3、打开tui界面(汇编+c语言)

在这里插入图片描述

使用命令
$ layout split
 注意:由于我们有源码,所以可以同时打开asm和src两个界面
 然后可以使用focus cmd来选中命令窗口(之前的文档里有写这一步的作用)

在这里插入图片描述

4、run

$ run

在这里插入图片描述
代码在第一个断点处停下来。

5、查看当前指令

(注意:可以发现我们的断点是在main+15处停下来的,而不是main处停下来的,这是因为gdb帮我们跳过了前面的一部分,前面的一般是申请堆栈内存+保存现场等)
当前指令如图
在这里插入图片描述
它对应于IDApro中的指令,如图
在这里插入图片描述
对应自己写的小工具的注释:
在这里插入图片描述

5、查看寄存器的值

首先,注释文件里已经打印出了源操作数的值,即[0x00491eb0]的值为0x00000002 0x00000001
下面我们在gdb中验证一下
命令为(x命令)

一次打印两个32bit的数据(16进制)
$ x /2wx 0x491eb0

可以看到,值分别为1和2,和注释文件里的值是一样的。
在这里插入图片描述

三、阅读mytest函数汇编

main函数的汇编,暂时略过。
在gdb中使用命令c跳到第二个断点,即mytest函数处
在这里插入图片描述
参数顺序参考下图
在这里插入图片描述

每条汇编的注释如下(ida中添加注释的快捷键为冒号和分号,我常用的是冒号)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_29809823/article/details/120547707
今日推荐