linux 堆溢出学习之malloc堆管理机制原理详解

前言

在pwn的学习过程中,最为难啃的骨头莫过于堆相关的利用,然而无论是在实际情况下还是在ctf比赛中,堆利用都是绝对的主流,是漏洞的主要类型之一。鉴于国内相关资料有限,系统讲解堆溢出利用的更是少之又少,我在此整理相关内容,既能作为自己学习的记录,也希望能够给大家带来一定的作用,不过鉴于本人也在学习之中,如有错误希望大家包涵,并且能够积极指正。

堆的基础知识

什么是堆

堆是一种全局的数据结构,用以动态管理系统内存,与之相对应的广为人知的是栈,栈也是一种动态的内存结构,但是栈并不是人工分配用以存储数据的,而是由系统自动分配的,相比较而言,堆具有更多的灵活性,典型的区分就是在C语言当中,在函数当中的局部变量就是存在函数的栈当中,是自动分配的,而使用malloc函数,calloc函数等进行分配的内存则位于堆空间,是我们向系统“索取”的内存空间

堆的分布

堆在内存当中的分布示意如下
内存分布
从高地址到低地址依次为:

  • 内核的空间:我们在编写应用程序(非内核空间程序)的时候,这一块地址我们是不能够使用的,

  • 栈区域(User stack)主要是用于函数的局部变量和函数参数的存放 .共享库的映射空间(Memory mapped region for shared libraries),用以将程序调用的外部函数所在的共享库映射到这个空间,这样才能够使用外部函数,详情可参考《程序员的自我修养》

  • 运行时堆(Run-time heap),由malloc,calloc等创建的空间,是运行的时候由程序申请的(注意这里和下面的data所在的空间其实不一定是连起来的,如果使用了ASLR,即内存地址随机化保护,这里就会有一段随机的间隔)

  • 可读写数据(read/write data),比如全局变量 .只读代码和数据(Read-only code and data),就是可执行文件的代码和一些不能够修改的数据了

GNC C库的实现

背景常识

Glibc提供了一些堆管理函数的实现,典型的有malloc, free, realloc等等,这些函数的实现其实又来源于ptmalloc2,历史不是我们的重点我就不在这里赘述。

其实现方法是通过调用系统调用(可以粗略的理解为操作系统提供的非常基础的函数,用来和操作系统进行交互)brk或者mmap,再加上自己的一些管理的数据结构和算法来加快或者方便管理,关于brk和mmap系统调用的作用这里不再赘述,可以很轻松的查到相关信息。

实现综述

Ptmalloc2通过几种数据结构来进行管理,主要有arena,heap,chunk三种层级。Chunk为分配给用户的内存的一个单位。 对于这一块内容如果感觉不是太懂,可以结合后面数据结构部分去看,其实arena和heap我感觉都是对chunk的一种组织方式,方便之后的分配,arena又是对heap的组织。

  • arena 对于32位系统,数量最多为核心数量2倍,64位则最多为核心数量8倍,可以用来保证多线程的堆空间分配的高效性。主要存储了较高层次的一些信息。有一个main_arena,是由主线程创建的,thread_arena则为各线程创建的,当arena满了之后就不再创建而是与其他arena共享一个arena,方法为依次给各个arena上锁(查看是否有其他线程正在使用该arena),如果上锁成功(没有其他线程正在使用),则使用该arena,之后一直使用这个arena,如果无法使用则阻塞等待。

  • heap heap的等级就比arena要低一些了,一个arena可以有多个heap,也是存储了堆相关的信息。

  • chunk chunk为分配给用户的内存的一个单位,每当我们分配一段内存的时候其实就是分配得到了一个chunk,我们就可以在chunk当中进行一定的操作了。不过为了进行动态分配,chunk本身也有一些数据(元数据),是用来指示其分配等等的数据。

我们这里给出分配的一个总体过程,使得有一个大致印象,根据后面的细节,如果有什么地方不太懂,可以参考这个过程。现在可能有一些名词还不是很明白,可以先阅读后文,再回来看这个过程。

  • Malloc: 根据线程的arena决定使用哪个arena的heap,然后根据大小确定使用哪种bin,然后在相应的bin中去寻找可以分配的合适的chunk,分配chunk之后将该chunk从相应的bin链表中移除。如果所有bin中都没有可以使用的chunk可以选择,则到top chunk当中取一段区域来使用,剩下的chunk作为remainder,也成为新的top chunk,如果top chunk不够了则使用系统调用来增加空间。Main_arena和thread_arena的系统调用方式不同,main_arena通过brk,这样可以直接在原来的基础上增加一块连续的区域,这样就只需要一个heap,而thread_arena通过mmap,如果要再进行申请就需要一个新的heap,一个新的heap结构,这些heap结构

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值