目录
- 一、文件介绍:
- 1、源码
- 2、目标文件test1
- 3、使用dynamorio工具生成的注释文件(后面简称它注释文件吧)
- 二、使用gdb调试目标文件
- 1、设置断点
- 2、设置汇编格式为intel
- 3、打开tui界面(汇编+c语言)
- 4、run
- 5、查看当前指令
- 5、查看寄存器的值
- 三、阅读mytest函数汇编
一、文件介绍:
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中添加注释的快捷键为冒号和分号,我常用的是冒号)