ctf堆概述

堆概述

参考:https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/heap-overview/

1.堆概述

1.1 堆

在程序运行过程中,堆可以提供动态分配的内存,允许程序申请大小未知的内存。堆其实就是程序虚拟地址空间的一块连续的线性区域,它由低地址向高地址方向增长。

1.2 堆管理器

我们一般称管理堆的那部分程序为堆管理器。

堆管理器处于用户程序与内核中间,主要做以下工作

  1. 响应用户的申请内存请求,向操作系统申请内存,然后将其返回给用户程序。同时,为了保持内存管理的高效性,内核一般都会预先分配很大的一块连续的内存,然后让堆管理器通过某种算法管理这块内存。只有当出现了堆空间不足的情况,堆管理器才会再次与操作系统进行交互。
  2. 管理用户所释放的内存。一般来说,用户释放的内存并不是直接返还给操作系统的,而是由堆管理器进行管理。这些释放的内存可以来响应用户新申请的内存的请求。

Linux 中早期的堆分配与回收由 Doug Lea 实现,但它在并行处理多个线程时,会共享进程的堆内存空间。因此,为了安全性,一个线程使用堆时,会进行加锁。然而,与此同时,加锁会导致其它线程无法使用堆,降低了内存分配和回收的高效性。同时,如果在多线程使用时,没能正确控制,也可能影响内存分配和回收的正确性。Wolfram Gloger 在 Doug Lea 的基础上进行改进使其可以支持多线程,这个堆分配器就是 ptmalloc 。在 glibc-2.3.x. 之后,glibc 中集成了 ptmalloc2。

目前 Linux 标准发行版中使用的堆分配器是 glibc 中的堆分配器:ptmalloc2。ptmalloc2 主要是通过 malloc/free 函数来分配和释放内存块。

需要注意的是,在内存分配与使用的过程中,Linux 有这样的一个基本内存管理思想,只有当真正访问一个地址的时候,系统才会建立虚拟页面与物理页面的映射关系。 所以虽然操作系统已经给程序分配了很大的一块内存,但是这块内存其实只是虚拟内存。只有当用户使用到相应的内存时,系统才会真正分配物理页面给用户使用。

所有堆管理器:

•dlmalloc – General purpose allocator

•ptmalloc2 – glibc (敲黑板)

•jemalloc – FreeBSD and Firefox

•tcmalloc – Google libumem – Solaris

堆管理器并非由操作系统实现,而是由libc.so.6链接库实现。 封装了一些系统调用,为用户提供方便的动态内存分配接口的同时,力求高效地管理由系统调用申请来的内存。

1.3 概念示图

2.堆的基本操作

2.1 申请内存malloc

malloc__libc_malloc 的别名:

strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc)

函数原型:

void *__libc_malloc (size_t bytes) 
param1: 申请的堆块的大小
return: 指向申请的堆块的数据部分的起始位置
备注:   还对一些特殊情况进行处理:
    	bytes = 0, 返回一个最小的chunk,大部分32位系统最小chunk为16字节,64位系统返回24或者32位。
    	bytes < 0, 由于大部分系统,size_t是无符号数,那么程序就会申请很大的空间,但是系统没有那么多的内存可以分配,因此大多数情况都会失败

示例图:

2.2 释放内存free

free()__libc_free() 的别名:

strong_alias 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值