前言
终于抽出时间对glibc动态内存管理部分源码进行初略的探究,试着从源码和动调来分析free函数执行过程和一些pwn的攻击技巧,分析的不是很全面,有错误的地方望提出指正,共同进步。ps:欢迎白帽子们关注 涂鸦智能安全响应中心
相关结构体
Chunk的结构体 malloc_chunk
对于inuse的chunk 只有malloc_chunk.size是生效的,fd,bk指针对于free chunk生效,fd_nextsize,bk_nextsize对于largebins生效。
Malloc_par 结构体
与sbrk 与 mmap的申请与释放相关结构体,源码中变量 mp_.
64bits 下chunk的内存布局结构
结构示意图
标志位判定代码
P 0b0001
M 0b0010
A 0b0100
结构示意图
P: 标志前一个chunk是否在使用中,配合 size_of_previous_chunk使用进行合并堆块。
P=0 前一个堆块并未被alloc,prev_size生效
P=1 前一个堆块在使用中
offset name
0x10-0x17 *fd 指向bins中的下一个bin
0x11-0x1f *bk 指向bins中的上一个bin
Freechunk是Largebin 的情况下
0x20-0x27 *fd_nextsize 指向下一个largebin.size
0x28-0x2f *bk_nextsize 指向上一个largebin.size
动态内存申请执行流程
hook跳转的定义部分
Malloc的执行流程
获取malloc_hook的值,只要值不为空,跳转malloc_hook的值进行函数执行(修改__malloc_hook为onegadget或其他执行流的执行点)
Hook取值 malloc_hook_ini 后跳转执行
在调用malloc_hook后hooks.c malloc_hook_ini()执行
清空 malloc_hook 之后调用 arena.c>ptmalloc_init()
返回后在进入__libc_malloc()接着调用 _int_malloc()
1.对可用arenas进行检索
2.对fastbin进行申请堆块大小的检索
此时 getmax_fast为0 跳过检索
3.对smallbins进行检索
Victim == 0 进入执行 malloc_consolidate()
在malloc_consolidate()中不满足检索条件 进入 malloc_init_state()执行进行堆空间的初始化
4.初始化top过程
av->top赋值
5.sysmalloc 初始化 heap区域
之后跳回__int_malloc()中,当前未有heap空间且未初始化堆,进入sysmalloc()
使用 sbrk()从系统 中分配 size 大小的虚拟内存块,第一次申请0x20 的chunk,sysmalloc()会指向申请一个topchunk 0x1000
申请完brk后 将brk地址挂载入 struct malloc_par mp.sbrkbase
挂在后的程序内存分布以及 mp结构体查看
之后对申请的空间设置chunk头,先设置申请大小的空间并且设置inuse位, 0x21001
6.计算申请chunk大小,对heap进行分割
申请出的区域先写上申请到的chunk_size
之后再写上top_chunk的chunk_size
初始化申请堆空间调用执行顺序为
malloc_hook -> malloc_hook_ini -> libc_malloc -> _int_malloc -> sysmalloc() -> brk
初始化堆块后__malloc_hook == 0,直接进入 _int_malloc 执行
1.对av(main_arena)校验是否存在,进入之后对bins检索需要申请的空间大小
2.Fastbins 检索
3.unsortedbins 检索
4.use_top_chunk
之后进入 use_top 分割topchunk
通过set_head函数 同上一节写入 chunk_size的方式分别写入 new_chunk 和 topchunk头
本文作者:Jambolt@涂鸦智能安全实验室
漏洞悬赏计划:涂鸦智能安全响应中心(https://src.tuya.com) 欢迎白帽子来探索。
招聘内推计划:涵盖安全开发、安全测试、代码审计、安全合规等所有方面的岗位,简历投递sec@tuya.com,请注明来源。
发表评论
您还未登录,请先登录。
登录