一、源C代码&编译指令

top chunk
地址最高的chunk
当所有的bin都无法满足时,若 top chunk 大于申请的空间,则分割,分割后剩余的部分作为新的 top chunk。
初始情况下,我们可以将 unsorted chunk 作为 top chunk。
名词:
chunk:块
arena:操作系统分配给程序的一块较大的(大于所申请的)内存区域
last remainder:在用户使用 malloc 请求分配内存时,ptmalloc2 找到的 chunk 可能并不和申请的内存大小一致,这时候就将分割之后的剩余部分称之为 last remainder chunk ,unsort bin 也会存这一块。top chunk 分割剩下的部分不会作为 last remainer.
堆操作:
malloc(size_t n)
返回对应大小字节的内存块的指针
当 n=0 时,返回当前系统允许的堆的最小内存块
当 n 为负数时,由于在大多数系统上,size_t 是无符号数(这一点非常重要),所以程序就会申请很大的内存空间,但通常来说都会失败,因为系统没有那么多的内存可以分配
使用brk申请的堆空间会挨着数据段,而使用mmap的堆空间在较高的地址
这些内存在释放之后一般不会返回系统而是在程序中等待申请
malloc()会使用两种系统调用:
1)brk()或者sbrk()函数
操作系统提供了 brk 函数,glibc 库提供了 sbrk 函数,sbrk会调用brk
初始时,堆的起始地址 start_brk 以及堆的当前末尾 brk 指向同一地址
brk(address) 直接将program break修改到address,返回值 0成功 -1 失败
sbrk(n) 修改program break向高地址增长n个字节,返回开辟之前的program break地址
sbrk(0)返回当前program break的地址
但是program break的增长不是无限制的,天花板是Memory Mapping Segment
2)mmap()
当申请的空间大于128k时,malloc()调用mmap()
二、调试过程
2.1 分配xy1、xy2、xy3,释放xy1,赋值xy2和xy3



2.2 分配xy1、xy2、xy3、xy4,释放xy1,赋值xy2和xy3



2.3 分配xy1、xy2、xy3、xy4、xy5,释放xy1,赋值xy2和xy3




2.4 分配xy1、xy2、xy3、xy4、xy5,释放xy1、xy2,赋值xy2和xy3


2.5 分配xy1、xy2、xy3、xy4、xy5、xy6,释放xy1、xy2,赋值xy2和xy3






2.6 分配xy1、xy2、xy3、xy4、xy5、xy6,释放xy1-xy5,赋值xy2和xy3


三、总结
PWN-堆的调试技巧包括:
list显示源码;
gcc -g参数可以添加调试信息;
next,step,start,break,x,vmmap,bin,heap:这是常见的gdb调试命令;
malloc和free是常见的堆分配函数,是以chunk为单位进行分配,由双向链表连接不同的chunk。
四、参考文献
http://www.manongjc.com/detail/29-tufsgqnbxnlmcod.html


