堆溢出利用

本文深入探讨堆的工作原理,包括堆块和堆表的数据结构,以及申请、使用和释放堆内存的过程。堆表由空闲双向链表和快速单向链表组成,申请时先查找快表,未找到则从普通表分配。释放时先尝试快表,满则归还普通表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x00 堆的工作原理

0x0 数据结构

堆块

堆块包括块首与块身(返回的指针指向),块首是一个堆块头部的几个字节,用来标识这个堆块自身的信息。


这里写图片描述
未被占用的堆区


这里写图片描述
被占用的堆区

堆表

位于堆区的起始位置,堆表分为两种空闲双向链表Freelist(空表 128条)和快速单向链表Lookaside(快表 最多只有四项)

堆区一开始的堆表区中有一个128项的指针数组(看到有人说把它看成队列的),被称作空表索引。该数组的每一项包含两个指针,用于表示一条空表。
free[1] 标识了所有堆中所有大小为8字节的空闲堆块,之后每个索引指示的空闲堆块递增8个字节。即:
free[2]标识了16个字节的空闲堆块。
free[k] 标识了 k * 8 个字节的空闲堆块。


这里写图片描述
空闲双向链表Freelist(空表)


这里写图片描述
快速单向链表Lookaside(快表)


0x1 申请

堆块的分配有三类:
- 块表分配
- 普通表份分配
- 零号表分配(free[0])

堆的申请首先在快表中查询,如果没有去普通表中查询,如果还没有从内存空间分配。

0x2 使用

直接利用堆表中的指针查询堆块,利用返回的指针使用堆内存,并对其操作。

0x3 释放

堆的释放首先释放在快表中,如果快表满了再释放到普通表中。


空表 内存分布
0x00520178 Freelist[0]  
0x00520188 Freelist[1]
0x00520198 Freelist[2]
0x005201a8 Freelist[3]

块区
0x00520680 h1 (加上8byte头字节)
0x00520690 h2
0x005206a0 h3
0x005206b0 h4

快表 内存分布
0x003606E8 Lookaside[1]
0x00360718 Lookaside[2]
0x00360748 Lookaside[3]
0x00360788 Lookaside[4]
堆区
0x00361E98 h1
0x00361Ea8 h3
0x00361E98 h5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值