前言
在《glibc内存管理ptmalloc - largebin》中我们详细解释了
- largebins共63个,并用表格点出了每个bin的size的范围
- largebin在free一些内存后的状态
特别是第2点,我其实不太满意,因为只有全部free后的一个结果,并没有中间状态。比如一个chunk是如何到的unsortedbin, 又如何从unsortedbin move到的largebin? 如果能把这个变化的过程打出来,对照着源码理解起来岂不美哉?!
确实有个工具叫pwndbg,它有些命令(largebins, heap)可以打印这些链表,我们在bin链的头上watch,只要头变了我们就调用heap打印链表的内容。当然我们可能打在一个链表变化的中间状态(下文有提到)上,比如头已经改变但它还没指向以前的头,先不管三七二十一,试试再说。
注:所用代码还是上节的
pwndbg第一印象
pwndbg的安装大家去github上找吧,我把它安装在redhat9上,对应的glibc版本是2.34,来个“第一印象”:
heap命令打印了各个chunk的信息,largebins -v命令不仅列出了链表的内容而且给出了各个链表的size范围,应该与我们上节制作的表格相符,我大概看了几个都对得上。
除此之外,还有fastbins, smallbins, unsortedbin命令。
实时打印链表变化
重新运行到第20行for-free,
找到存储unsortedbin链表头的地方:
watch unsortedbin & 第一个largebin
说点题外话:FD链已串好,BK链还没有放入 0x4052b0.
这应该是显示corrupted的原因,也是我一开始担心的(链表变化的中间状态)
验证下0x4052b0:
我就不在一步步执行了,continue n次,unsortedbin变化如下:
后面的largebin的变化不再赘述。
理论上我们能把arena中所有的bin头都watch起来,甚至arena.top也watch起来,这样就能看到ptmalloc管理内存的基本脉络了,甚至可以改改pwndbg的代码新添加一个这样的命令。