bins
global_max_fast
glibc(GNU C Library)中动态内存分配器(ptmalloc2) 的一个关键全局变量,用于控制 fast bins(快速分配区) 的最大内存块大小。
fast bin
单向链表
32位下fast bin范围为16到64
64位下fast bin范围为32到128
从块分配器的角度来看,fastbin 中的块被视为已分配的块。它们仅在 malloc_consolidate 中批量与相邻对象合并。
double free
1 | _int_free |
这里对double free漏洞的检查:
获取fastbin链表中最后入链的old,然后判断即将释放的fastbin和old的指针是否相同
unsorted bin
unsorted bins的bk和fd指向的是一个指针,而这个指针指向的是top chunk的地址,这个地址又储存在main_arena的0x58偏移处
main_arena - 0x10即为__malloc_hook的,__malloc_hook又是调用malloc时会调用的指针,所以可以通过劫持__malloc_hook来劫持程序控制流
然后通过fastbin attack将下一个堆块改为__malloc_hook - 0x23处,因为只有改为这处,视为堆块的此处的size位置才为正确的数据
binmap
Binmap的底层结构
物理存储
binmap
是malloc_state
结构体中的一个数组(unsigned int binmap[BINMAPSIZE]
),每个元素为32位无符号整数(unsigned int
)。总长度:固定为4个int(即128位,对应63个large bin的索引需求)
分组逻辑:每个int(32位)称为一个block,每个block负责管理32个连续的large bin状态
计算main_arena
通过上面的泄露unsorted_bin的fd指针
通过__malloc_trim函数直接获得
“比如把
.so
文件放到 IDA 中,找到malloc_trim
函数,就可以获得偏移了。” -–ctfwiki
tcache
glibc 2.26后
两个结构体
tcache dup
仅限glibc2.26,可以直接对其进行double free
tcache_entry
1 | /* We overlay this structure on the user-data portion of a chunk when |
一个单向链表
tcache_perthread_struct
1 | /* There is one of these for each thread, which contains the |
通过counts记录tcache_entry上空闲的chunk数目