堆入门系列(2)之gdb动态调试

1 篇文章 0 订阅
1 篇文章 0 订阅

前言

之前学栈时gdb调试太少了,这次通过学堆把动态调试过程都再了掌握一遍。刚开始学堆,可能存在错误或不足,之后会不定时修改补充。



一 :gdb动态调式时常见的基本命令

1、基本的调试命令

s step,si单步步进
 
n 执行下一条指令 ni步入
 
b 在某处下断点,可以用 b * adrress(地址) 与 b function_name(函数名字)
 
info b 查看断点信息
 
delete 删除所有断点
 
c 继续
 
r 重新执行

3、P命令的使用

p system/main 显示某个函数地址
 
p $esp 显示寄存器
 
p/x p/a p/b p/s。。。
 
p 0xff - 0xea 计算器
 
print &VarName 查看变量地址
 
p * 0xffffebac 查看某个地址处的值

3、X命令的使用

命令格式:x/<n/f/u> <addr>
 
n是一个正整数,表示需要显示的内存单元的个数
 
f 表示显示的格式(可取如下值: x 按十六进制格式显示变量。d 按十进制格式显示变量。u 按十进制格式显示无符号整型。o 按八进制格式显示变量。t 按二进制格式显示变量。a 按十六进制格式显示变量。i 指令地址格式c 按字符格式显示变量。f 按浮点数格式显示变量。)
 
u 表示从当前地址往后请求的字节数 默认4byte,u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。
 
<addr>表示一个内存地址
 
x/xw addr 显示某个地址处开始的16进制内容,如果有符号表会加载符号表
 
x/x $esp 查看esp寄存器中的值
 
x/s addr 查看addr处的字符串
 
x/b addr 查看addr处的字符
 
x/i addr 查看addr处的反汇编结果

4、堆中常见命令的使用

heap:查看堆中的chunk情况,之后结合x命令查看每一个chunk的内部情况

bins:查看程序运行过程中bin链表的分布情况。



二 :手动输入调试过程

(1)打开gdb,运行程序

首先打开gdb,r运行一下程序。先执行两次add命令,来查看chunk的分布。

程序链接:https://buuoj.cn/challenges#hitcontraining_uaf
在这里插入图片描述



(2)heap命令查看chunk个数

ctrl + c断掉,然后再heap命令查看程序中的堆分布
_70,g_se,x_16)

存在6个chunk,根据其大小可以确定其中 ②~⑤ 号chunk是由我们分配的,
(其中第一个分配的chunk具体是什么我也不是很清楚,但是每一个程序都有。最后一个chunk是top chunk,我们分配的chunk就是从这里面来的。)

这些chunk如何分布的,大小如何确定,内容是如何存放的,这个我们打开chunk来具体分析一下。


## (3) X命令查看chunk里内容 查看chunk里面的内容主要靠一个x命令(前面有讲),其中x命令的地址是从第②个chunk开始(32位用wx,64位用gx。这样的目的是为了方便查看,至于输出大小自己决定)

在这里插入图片描述

②~⑤这些chunk是由我们自己来决定的,我们就重点讲一下

  • 首先 ②和③ chunk是输入第一次add时开辟的,执行一次add开辟两个chunk,说明add函数当中存在两次malloc,具体的情况需要结合ida来分析。

  • ②的是0x11,首先chunk存在一个head头,size与pre_size占了8个字节,然后后面还有一个打印的函数以及它的参数(打印的位置),至于为什么知道是一个puts函数,打开ida点击跳转到地址==》然后输入地址就会跳转到该函数。这就是0x10,还有一字节是因为size字段的低三位是一个状态标识,当前面的chunk不为空时表示为1,

  • ③的是0x21,这个chunk才是由用户自己决定的,包括其大小与内容。0x21 = 0x10(你自己输入的大小) + 0x8(32位的head的size与pre_size占8个字节)+ 0x1(状态标识) + 0x8(此处留坑)。可以看到我们输入的内容aaaa存在这个chunk里面,而且puts函数的参数指向的也是这里。

  • 接下来看一下整体流程,我们add创建一个堆空间,它开辟了两个chunk,第一个chunk大小固定 是puts函数,它的参数是一个地址,指向我们输入的内存处。第二个chunk是我们自己决定的,可以输入大小以及内容,

  • ④和⑤和前面的②和③一样,只不过我们自己在前面开辟的大小是0x20罢了。

查看完以后要想再继续调试,就按c继续执行,然后输入命令
在这里插入图片描述

手动调试肯定是比较慢的,真的做题需要使用脚本进行调试,前期像我这样的不会做,就一行一行代码的去调试查看,查看差别,来弄懂程序的实现过程。



三 :写脚本调试

(1)首先需要一个基本的脚本代码(像libc一样),先编写一个脚本保存,之后遇到题目以后根据题目的输入输出格式进行修改。这里我的一个脚本大家可以参考

from pwn import *

r = process("./pwn")
context(log_level = 'debug')

def add(size, content):
	r.recvuntil(":")
	r.sendline("1")
	r.recvuntil(":")
	r.sendline(str(size))
	r.recvuntil(":")
	r.sendline(content)

def delete(index):
	r.recvuntil(":")
	r.sendline("2")
	r.recvuntil(":")
	r.sendline(str(index))

def show(index):
	r.recvuntil(":")
	r.sendline("3")
	r.recvuntil("Index :")
	r.sendline(str(index))

gdb.attach(r)
pause()

r.interactive()

主要就是三个函数,有些程序有四个程序多了一个fill函数,这些函数的构造就是按照这个程序的流程进行的。比如add函数:首先要执行add函数,看目录需要先按1,然后add函数里面需要输入大小以及内容。具体题目具体分析修改。
然后就是下面两行代码是进行动态调式的两行关键代码,还有其他代码也可以请自行百度

gdb.attach®

pause()

(2)具体如何调试
首先先加两个add函数,然后python运行脚本。这样的效果和我们前面自己手动输入的效果是一样的
在这里插入图片描述

前面讲了add函数,接下来讲讲释放以后的内存布局
在这里插入图片描述
在这里插入图片描述

可以发现第一个chunk已经被清空,但是需要注意的是第二个chunk没有清空,我觉得这儿说明这个程序存在问题,再查看chunk内部,发现puts地址和内容已经被清空
在这里插入图片描述

之后就是自己根据题目,一步一步的去调试了。前期先看别人的脚本,一行一行的去调试,然后看懂每一行的代码的作用含义。真正弄懂一道题以后就发现自己已经不一样了。

在这里插入图片描述

总结

学会了动态调试,就看着别人的脚本一步一步去调试吧。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要对SLAM程序进行GDB调试,首先需要进入GDB调试环境。可以使用命令"gdb [程序名]"来进入GDB调试。例如,在ORB_SLAM3的ROS示例中,可以使用命令"gdb Stereo"进入GDB调试环境。 进入GDB调试后,可以使用一些常用的GDB命令进行调试。例如,可以使用"run"命令来运行程序,使用"break"命令设置断点,使用"step"命令逐行执行程序,使用"print"命令打印变量的值等等。这些命令可以帮助我们分析程序的执行过程和调试问题。 请注意,GDB是一个命令行模式的调试工具,因此需要熟悉一些基本的GDB命令才能进行有效的调试。在GDB调试过程中,可以通过加上"-q"参数来禁止输出一些不必要的信息,以便更清晰地查看调试信息。 总结一下,要对SLAM程序进行GDB调试,可以使用"gdb [程序名]"命令进入GDB调试环境,并使用一些常用的GDB命令进行调试,例如"run"、"break"、"step"、"print"等命令[2]。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SLAM工具|GDB调试入门到精通](https://blog.csdn.net/Yong_Qi2015/article/details/122463019)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [GDB调试 ORBSLAM3](https://blog.csdn.net/qq_41861406/article/details/125034738)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值