1.堆分配机制
在许多文章上看到若在fastbin和smallbin中找不到相应大小的堆块,会将fastbin进行合并。
但经过我的测试,fastbin貌似并不会合并,根据做题经验fastbin也不会合并,不然这么uaf。
所以我认为堆的分配顺序应该是:
1.在fastbin和smallbin中寻找有没有大小正好的,若有则直接分配,若没有,进入2.
2.在unsortedbin中寻找,从尾部开始,遍历过的堆块放入smallbin和largebin中,0x400为分界,直到找到大小正好的,分配,若没找到,进入3.
3.在larginbin中寻找大小正好的,没找到则进入4.
4.重新从fastbin开始找,从小到大找,找最近的比它大的,然后切割,若切割完剩下的大于0x20,则放入unsortedbin,小于0x20,则全部分配出去。
5.都不行,则从topchunk分配。
2.larginbin结构
这是只有一个largebin的情况,可以看到 fd和bk都指向largebin的链表头,fd_nextsize和bk_nextsize都指向自己。
可以看到largebin中每个bin的大小其实都是一个范围。
这是2个largebin的情况,同一个bin中larginbin是从大到小排序的,尾部最小,尾部的fd指向表头,bin中第一个chunk的bk指向表头,双方的fd_nextsize和bk_nextsize都指向最近的大小不一样的chunk。
add(0,0x410)
add(6,0x20)
add(1,0x410)
add(7,0x20)
add(2,0x420)
add(8,0x20)
add(3,0x420)
add(4,0x20)
delete(2)
delete(3)
delete(1)
delete(0)
add(5,0x480)
gdb.attach(io)
pause()
这是接下来的脚本,穿插0x20是防止合并。
可以看到上面我们是先释放体积大的chunk。
但通过此图可以看到,最后体积大的chunk就是在前面,所以是largebin会自动排序,将体积大的排在前面。
此图可以看出,相同大小的largebin只有第一个释放的有fd_nextsize和bk_nextsize。