malloc_chunk结构体
文章参考了了网上的一些师傅文章内容,总结了一些自己的理解。
malloc_chunk结构体成员解析
malloc_chunk
结构定义
cpp
1 | /* |
各个成员的作用
prev_size
- 如果该
chunk
物理地址相邻的前一chunk
(两个指针的差值为前一个chunk大小)是空闲的chunk
,这个字段记录的是前一个字符段的大小 - 用于储存物理地址相邻的
chunk
(低地址chunk)的信息 - 被共享,如果当前
chunk
大不够用,可以占用下一个chunk
的prev_size
字段
- 如果该
size
存储当前
chunk
的大小,chunk的大小内存申请,与SIZE_SZ
有关,如果不是2*SIZE_SZ
的整数倍,会自动向上取整到2*SIZE_SZ
的整数倍,32位操作系统中SIZE_SZ
是32位4个字节,64位操作系统中SIZE_SZ
是64位8个字节。32位必须8字节对齐,64位必须16字节对齐,无论32位还是64位,size
最后三位都没有用,所用可以用来存储其他信息NON_MAIN_ARENA
IS_MAPPED
记录当前chunk是否是由
mmap
申请PREV_INUSE
记录前一个 chunk 块是否被分配。一般来说,堆中第一个被分配的内存块的 size 字段的 P 位都会被设置为 1,以便于防止访问前面的非法内存。当一个 chunk 的 size 的 P 位为 0 时,我们能通过 prev_size 字段来获取上一个 chunk 的大小以及地址。这也方便进行空闲 chunk 之间的合并。
fd
和bk
- chunk处于分配状态时,fd地址段存放的是用户数据。chunk在空闲的时候通过链表管理
fd
指向上一个空闲(非物理空闲)的chunkbk
指向下一个空闲(非物理空闲)的chunk
fd_nextsize
和bk_nextsize
-
chunk被使用时内存结构
python1
2
3
4
5
6
7
8
9
10
11
12
13
14chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if unallocated (P clear) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of chunk, in bytes |A|M|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| User data starts here... .
. .
. (malloc_usable_size() bytes) .
next . |
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (size of chunk, but used for application data) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of next chunk, in bytes |A|0|1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+chunk被释放时内存结构
python1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of previous chunk, if unallocated (P clear) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`head:' | Size of chunk, in bytes |A|0|P|
mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Forward pointer to next chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Back pointer to previous chunk in list |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused space (may be 0 bytes long) .
. .
next . |
chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
`foot:' | Size of chunk, in bytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Size of next chunk, in bytes |A|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
内存对齐
malloc函数申请的chunk地址都是8字节或者16字节对齐(32位8字节,64位16字节),所谓字节对齐,就是所有的地址最后8位或16位都是一样的(大多数时候为8的整数倍),常见的内存对齐有8字节对齐和16字节对齐
8字节对齐
地址的最后8位(2进制位)10进制表示为8
16字节对齐
地址的最后8位(2进制位)10进制表示为0
下面用pwndbg展示32位下chunk内存结构
pwndbg分析chunk在内存中的结构
测试源码
c
1 |
|
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.