Glibc-2.23 源码分析——malloc部分上

阅读量    162102 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

前言

终于抽出时间对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的内存布局结构

Allocated chunk

结构示意图

标志位

标志位判定代码

P   0b0001
M   0b0010
A   0b0100

Free chunk

结构示意图

标志位

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的执行流程

hook的获取与调用

获取malloc_hook的值,只要值不为空,跳转malloc_hook的值进行函数执行(修改__malloc_hook为onegadget或其他执行流的执行点)

Hook取值 malloc_hook_ini 后跳转执行

情况1:未有topchunk时申请chunk

在调用malloc_hook后hooks.c malloc_hook_ini()执行

清空 malloc_hook 之后调用 arena.c>ptmalloc_init()
返回后在进入__libc_malloc()接着调用 _int_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

情况2:已有 topchunk时申请小size的chunk

初始化堆块后__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,请注明来源。

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多