Windows堆管理器概述
2021-07-01
187
0
在Windows下,堆管理器的原理如下图:
堆的空间布局
堆的创建
每个进程在创建时,加载器执行用户态的初始化函数,调用RtlCreateHeap函数为进程创建第一个堆,即默认堆。
应用程序也可调用HeapCreate创建 其它堆,且只能为本进程自己用,此堆为私有堆。
进程的进程环境块(PEB)存放当前进程的所有堆。
PEB结构体变量名 | 含义 |
---|---|
ProcessHeap | 进程默认堆句柄,即默认堆的起始地址 |
NumberOfHeaps | 进程中堆的数量 |
MaximuNumberOfHeaps | 进程堆数组的目前大小 |
ProcessHeaps | 存放堆句柄的数组(起始地址,结束地址) |
堆的清理
应用程序可不必销毁进程的默认堆和私有堆,系统在进程退出时会自动清理堆,而且是两次清理,调用的函数都是MmCleanProcessAddressSpace。
1.调用NtTerminateProcess或最后一个线程退出时。
2.系统工作线程删除进程对象时。
堆的管理函数
用户态的堆管理函数 NTDLL.dll |
内核态的堆管理函数 NTOSKRNL.exe |
功能 |
---|---|---|
Ntdll!RtlAllocateHeap | nt!RtlAllocateHeap | 从堆上分配内存 |
Ntdll!RtlCreateHeap | nt!RtlCreateHeap | 创建堆 |
Ntdll!RtlDestroyHeap | nt!RtlDestroyHeap | 销毁堆 |
Ntdll!RtlFreeHeap | nt!RtlFreeHeap | 释放堆块 |
Ntdll!RtlSizeHeap | nt!RtlSizeHeap | 取堆大小 |
Ntdll!RtlZeroHeap | nt!RtlZeroHeap | 堆空间清零 |
Ntdll!RtlExtendHeap | nt!RtlExtendHeap | 扩展堆大小 |
堆块空间的释放
堆块空间可通过系统API实现,如malloc等。
堆块空间释放一般不是真正意义上的释放,只在以下条件才调用zWFreeVirtualMemory进行释放即归还系统。
1.本次堆释放的堆块大小超过了堆参数DeCommitFreeBlockThreshold(0x1000,4K)的阈值。
2.累计总空闲空间超过DeCommitTotalFreeThreshold(0x10000,64K)
堆的溢出检查
1.HVC(Heap Validation on Call)堆的调用时验证,即堆函数在每次调用时进行检查,一般默认关闭,因为影响速度。
2.HTC(heap tail check)堆尾检查,在堆块末尾增加8个字节(0xAB),可在堆释放时检查出堆溢出。
3.DPH(Debug Page Heap)调试的页堆(Win2000后引入)。主要是在可用数据前后加入只读页,当写入时触发异常。