- win32堆结构
在解决实际问题以前,先来了解一下相关概念
1. 堆结构
堆->段->块
堆是由段,段是由块组成的,块就是用户最终向系统申请的虚拟内存的数据结构。(目前我们用户态程序只需要理解块就可以了)
2. _HEAP_ENTRY结构
每个堆,每个段,每个块都会有相应的_HEAP_ENTRY结构,里面描述了该区域内容的信息。比如块的_HEAP_ENTRY结构就存放了所属的堆,段,前项大小和当前大小等信息。
- windbg堆的相关命令
- 查看所有堆的概览信息:!heap -s
- 某个堆所有的段和块信息:!heap -a 0xXXXXXXXX
- 查看某个内存地址所在的_HEAP_ENTRY信息:!heap -x 0xXXXXXXXX
- 统计某个堆的概览信息:!heap -stat -h 0xXXXXXXXX
- 列出所有大小为X的块地址:!heap -flt s X
- 查看堆的调试支持:!gflag
- 查看内存块的内容 dc 0xXXXXXXXX
- 堆破坏的调试
1. 什么叫做堆破坏
堆破坏其实就是块破坏,由于对超出地址所在分配的空间读写,导致破坏了_HEAP_ENTRY结构(如果是CRT堆,就是破坏了CRT堆的末尾检查结构,甚至破坏了下一个块的结构)
2. 一个堆破坏的例子
这里故意写了一个越界的操作,编译成release版本,用windbg挂上去
查看一下ptr的值
查看一下ptr所在的_HEAP_ENTRY结构,发现属于00b30000这个堆,在00b34420这个块里面
我们看到上述块后续的块都已经被破坏,所以堆破坏的特征基本就长这样。但是该例程并不会导致崩溃。
3. 总结一下分析思路
a) 找到该崩溃的块所在的堆(可以根据地址范围判断)。
b) 查看该堆所有块信息。
c) 从最后一个尚未被破坏的块找到相应的信息。(如果业务逻辑是从小往大地址写,就会破坏往后块,否则就是相反)