###Date:2018-1-21
###Author: SoaringLee
========================================================================
序
程序的漏洞定位和缺陷检查一直是一个令程序员头痛的问题,当然也有很多优秀的缺陷检查软件,比如跨平台的静态检查软件Coverity,内存泄漏软件Valgrind,以及Windows下的调试软件WinDbg等。
最近在调试分析一个MPEG-4解码库的源数据读访问越界问题时,采用了WinDbg中的gflags工具进行调试,这绝对是检查程序访问越界问题的一把利器。
原理
什么是 Page Heap (页堆)?
从 Windows 2000 开始操作系统开始在堆管理器引入“校验层”,即 Page Heap 管理器。这个校验层处于 Ntdll.dll模块内。可以验证应用程序所有的动态内存操作(读写、分配、释放及其它操作)。
页堆有两种类型:正常页堆和完全页堆( Full Page Heap )
完全页堆:
当分配一块内存时,通过调整内存块的分配位置,使其结尾恰好与系统分页边界对齐,然后在边界处再多分配一个不可访问的页作为保护区域。这样,一旦出现内存读 / 写越界时,进程就会 Crash ,从而帮助及时检查内存越界。
因为每次分配的内存都要以这种形式布局,尤其对于小片的内存分配,即使分配一个字节,也要分配一个内存页,和一个保留的虚拟内存页(注意在目前的实现中,这个用作边界保护区域的页从来不会被提交)。这就需要大量的内存,到底一个进程需要多少内存,很难估算,因此在使用 Page Heap 前,至少保证你的机器至少设置了 1G 虚拟内存以上。
正常页堆:
正常页堆原理与 CRT 调试内存分配函数类似,通过分配少量的填充信息,在释放内存块时检查填充区域。来检测内存是否被损坏,此方法的优点是极大的减少了内存耗用量。缺点是只能在释放块时检测,不太好跟踪出错的代码位置。
Page Heap 选项位于注册表目录: HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Image File Execution Options/ 你的可执行程序名 / 。当 Windows 开始启动一个进程时, Window 通过检查这个注册表目录的设置,对该进程应用相应的 PageHeap 选项。PageHeap的功能是操作系统本身就有的,gflags工具只是用来对可执行程序设置PageHeap选项。
测试方法
gflags /p:查看当前跟踪的程序。
/p /enable: 使用path,启用gflags。
/full:说明分配的空间是独占的,并且相邻的是不可访问的空间。
/unaligned:说明分配空间时不对齐,保证一旦越界立即发现,不会因为内存对齐而隐藏起来。
参考
http://blog.csdn.net/lunasea0_0/article/details/6292968
http://blog.csdn.net/zhufangyou/article/details/6563878
http://blog.csdn.net/hgy413/article/details/9137771
https://www.cnblogs.com/cswuyg/archive/2011/09/27/gflags.html
http://blog.csdn.net/mergerly/article/details/8308724