首页
社区
课程
招聘
[原创]新人PWN堆Heap总结(一)
发表于: 2021-8-8 23:23 19166

[原创]新人PWN堆Heap总结(一)

2021-8-8 23:23
19166

开个堆系列,先声明一下,本人堆学的不是太好,如果有错误,烦请各位师傅指出,谢谢!


1.arena:堆内存本身

(1)主线程的main_arena:由sbrk函数创建。

①最开始调用sbrk函数创建大小为(128 KB + chunk_size) align 4KB 的空间作为 heap

②当不够用时,用sbrk或者mmap增加heap大小。

(2)其它线程的per thread arena:由mmap创建。

①最开始调用 mmap 映射一块大小为HEAP_MAX_SIZE(32 位系统上默认为 1MB,64 位系统上默认为 64MB)的空间作为 sub-heap。

②当不够用时,会调用 mmap 映射一块新的 sub-heap,也就是增加 top chunk 的大小,每次 heap 增加的值都会对齐到4KB。

2.malloc_state:管理arena的一个结构,包括堆状态信息,bins链表等等

(1)main_arena对应的malloc_state存储在glibc的全局变量中

(如果可以泄露malloc_state结构体的地址,那么就可以泄露glibc的地址)

(2)per thread arena对应的malloc_state存储在各自本身的arena

3.bins:用链表结构管理空闲的chunk块,通过free释放进入的chunk块(垃圾桶)

4.chunks:一般意义上的堆内存块

▲内存中的堆情况:

全局变量glibc:main_arena = struct malloc_state:

 

Free

chunk1

Free

chunk2

Top

chunk

低地址------------------------------------------------------------- ------------------>高地址

由sbrk创建的main_arena

(1)可以把bin也当作一个chunk,不同Bins管理结构不同,有单向链表管理和双向链表管理。

(2)top里的bk保存Topchunk的首地址。

(bk和fd只用于Bins链表中,allocated_chunk中是属于用户可以使用的内容)

 

 

 

1.在使用中的allocated_chunk和未被使用的free_chunk:

(1)allocated_chunk:

(2)free_chunk:

2.prev_size:8字节,保存前一个chunk的大小,在allocatedchunk中属于用户数据,参考上述的图片,free_chunk的下一个chunk的pre_size位为该free_chunk的size。

3.size:8字节,保存当前chunk大小。(free和allocated都有用)一个chunk的size以0x10递增,以0x20为最小chunk。

(1)malloc(0x01):会有0x20这么大,实际用户可用数据就是0x18。size=0x21

(2)malloc(0x01-0x18):仍然0x20这么大,实际用户可用数据就是0x18。size=0x21

(3)malloc(0x18):会有0x30这么大,实际用户可用数据是0x28。size=0x31

所以size这个8字节内存的最低4位都不会被用到,所以malloc管理机制给最低的3位搞了个特殊形式标志位,A,M,P,分别代表不同内容。

①A:NON_MAIN_ARENA,代表是否属于非main_arena,1表是,0表否。就是线程的不同。

②M:IS_MMAPPED,代表当前chunk是否是mmap出来的。

③P:PREV_INUSE,代表前一个chunk是否正在被使用,处于allocated还是free。

(标志位为1都代表是,0都代表否)


 

1.fastbins:放在struct malloc_state中的mfastbinptr fastbinsY[NFASTBINS]数组中。

(1)归类方式:只使用fd位

①bin的index为1,bins[0],bins[1]组成一个bin。

②规定大小的chunk归到一类,但个数有限,不同版本不同,同时也可以设置其范围:

M_MXFAST即为其最大的参数,可以通过 mallopt()进行设置,但最大只能是80B。

(2)单向链表:

▲例子:a=malloc(0x10); b=malloc(0x10); c=malloc(0x10); d=malloc(0x10)

FastbinY,d,c,b,a

①free(a)之后:

②free(b)之后:

③free(c)之后:

④free(d)之后:

(3)后进先出:

①m=malloc(0x10):          m->d

②n=malloc(0x10):           n->c

(4)不改变IN_USE位(p位):

如果某个chunk进入到fastbin中,那么该chunk的下一个chunk的IN_USE位还是为1,不会改变成0。

例子:a=malloc(0x10); b=malloc(0x10); c=malloc(0x10);

①free(a)之后:        b.p=1

②free(b)之后:     c.p=1;      b.p=1

p位不会变成0,如果该chunk进入到fastbins中。

可以进行free(0),free(1),free(0),但是不能直接free(0)两次。

(5)除了malloc_consolidate函数会清空fastbins,其它的操作都不会减少fastbins中chunk的数量。

 

 

2.smallbins:放在bins[2]-bins[125]中,共计62组,是一个双向链表。最大chunk的大小不超过1024字节

(1)归类方式:

①相同大小的chunk归到一类:大小范围[0x20,0x3f0],0x20、0x30、....0x3f0。每组bins中的chunk大小一定。

②每组bin中的chunk大小有如下关系:Chunk_size=2 * SIZE_SZ * index,index即为2-63,下图中64即为largebins的范围了。(SIZE_SZ在32,64位下分别位4,8。)

(2)双向链表:

▲例子:a=malloc(0x100); b=malloc(0x100); c=malloc(0x100)

①free(a)之后:          smallbin,a

②free(b)之后:        smallbin,b,a

③free(c)之后:     smallbin,c,b,a

(fd,bk为bins[n],bins[n+1]。fd和bk共同构成一个Binat。)

(3)先进先出:

①m=malloc(0x100):                m->a

②n=malloc(0x100):                 n->b

(4)当有空闲chunk相邻时,Chunk会被合并成一个大chunk,这里指的是物理上的地址相邻,不是链表中相邻。通过判断当前chunk的in_use位的值来判断前一个chunk是否处于Free,如果是,那么合并。再通过当前chunk首地址加上size取得下一个chunk首地址,再将下一个chunk首地址加上它自己的size,取得下下个chunk的首地址,然后判断下下个chunk的in_use位的值看是否下个chunk处于Free,如果处于Free,则合并。

 

 

3.largebins:放在bins[126]-bins[251],共计63组,bin的index为64-126,最小chunk的大小不小于1024个字节。

(1)归类方式:范围归类,例如bins[126]-bins[127]中保存chunk范围在[0x400,0x440]。且chunk在一个bin中按照从大到小排序,便于检索。其它与smallbins基本一致。

①范围模式:由以下代码定义范围:

②范围具体实例:

(2)双向链表,但是有两种排列方式:

①取用排列:

首先依据fd_nextsize,bk_nextsize两个指针大小找到适合的,然后按照正常的FIFO先进先出原则,通过fd,bk来排列。

②大小排列:

每个进入largebin的chunk

其chunk_addr+0x20处即为其fd_nextsize指针,chunk_addr+0x28处为其bk_nextsize指针。

然后通过fd_nextsize,bk_nextsize两个指针依据从大至小的顺序排列:

(这张图片我也忘记从哪里整的了...侵删)

其中size顺序为:D>C>B>A,但是释放顺序却不一定是这样的。设置这个的原因是当申请特定大小的堆块时,可以据此来快速查找,提升性能。

(3)特殊解链:

由于largebin中会存在fd_nextsize指针和bk_nextsize指针,所以通常的largebin_attack就是针对这个进行利用的。

借用星阑科技的一张图说明一切:

 

 

4.unsortedbins:bins[0]和bins[1]中,bins[0]为fd,bins[1]为bk,bin的index为1,双链表结构。

(1)归类方式:只有一个bin,存放所有不满足fastbin,未被整理的chunk。

(2)双向链表:

a=malloc(0x100); b=malloc(0x100); c=malloc(0x100)

①free(a)之后:          unsortedbin,a


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-8-8 23:26 被PIG-007编辑 ,原因:
收藏
免费 6
支持
分享
最新回复 (1)
雪    币: 547
活跃值: (331)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2021-8-17 11:59
0
游客
登录 | 注册 方可回帖
返回
//