0x12 gdb调试
gdb调试
- run(r):运行程序,在短点处停止
- continue(c):继续执行
- next(n):单步跟踪,不进入函数
- step(s):单步调试如果有函数调用,则进入函数
- until: 运行程序直到退出循环体
- until+:运行至某处,不仅仅跳出循环
- call:调用可见的函数,并传递参数 call gdb_test(55)
- quit(q):退出
- break n(b n):在第n行设置断点,可带代码路径和名称
- delete 断点号n:删除第n个断点
- disable 断点号n:暂停第n个断点
- enable 断点号n:开启
- info b(info breakpoints):显示断点情况
- delete breakpoints:删除所有断点
- set args参数:指定运行时的参数
- print(p)
- x/wx address:查看address中的内容
w可以换成b/h/g分别对应1/2/8 byte
/后可以列出数字,表示一次列出几个
第二个x可以换成u/d/s/is/i/以不同方式表示
u:unsigned int
d:十进制
s:字符串
i:指令
- info r:查看寄存器
- vmmap:查看每个address的权限
- find:在内存中查找信息,通常用来查找字符串
CGCTF——480小时精通C++
学习了一波后尝试可以用gdb调试来做这道题
- linux下运行发现输出了加密后的flag
- 扔到ida下发现了StringEncryptFunction(unsigned int8 *a1, int a2)这个函数,里面有一大堆的加密函数,可是却没有找到引用此函数的地方,后来看见是把它们都nop掉了。。。。但是后来想到能不能尝试更改程序的流程使它运行StringEncryptFunction(unsigned int8 *a1, int a2)这一个函数。
- 寄存器中有一个cs:ip,即代码段寄存器,所以我们可以修改指针指令寄存器(ip值)来更改程序的流程是我们运行这个加密函数,于是使用gdb调试器。
- 设置断点:b* 0x424556,运行便可以查看到加密后的flag
- 要想运行加密的函数,首先往这个函数里传递参数,分析了一下后发现$rsi存放了函数的第二个参数,也就是数据的长度,而$rdi则存放了数据的地址,于是设置参数:set $rdi=0x7fffffffde00,set $rsi=36;其次修改$rip的值使其跳转到这个函数:set $rip=0x4224f6,接着c执行,就可以在栈中看到flag了。