xp下调试堆溢出(上)–HeapAlloc分配堆块

    题记:win10都开始推广了,我还在折腾xp,真low…

    DWORD SHOOT的原理是利用Release版发布的程序在正常启动(非调试启动)情况下,使用Lookaside表(又称块表)管理程序中堆频繁的申请/释放操作不检验返回给调用者地址的合法性造成的漏洞。本文以堆溢出学习笔记和<0day安全 软件漏洞分析技术>为基础,改进而来。

    首先要明确Lookaside表是一个单链表,每次HeapFree释放的堆块被插到链表头,每次HeapAlloc都从链表头取一项然后返回给申请者;链表尾指向空。进程内存空间中有这样的单链表共128项,以数组形式管理。嗯,概念太多还是用程序说话

先简单介绍一下程序的流程:因为系统堆经历太多风雨,因此代码中新建一个私有堆便于观察现象。调用HeapAlloca为h1-h7分配堆块时,由于私有堆块表中还不存在可用记录(新创建时,堆中快表为空),因此这些堆块都来自空闲表。之后调用HeapFree时系统并不马上回收堆块并重新加入空闲链表,取而代之,系统将这些堆块加入各个块表的单链表中,因此块表逐渐丰满起来,最后h8 h9分配到的堆块就是从块表中取出的元素。

来看下调试过程,在命令行下运行程序,程序会等待console输入,先用windbg attach程序,然后F5并在console上按键。由于int 3的作用,调试器会中断程序运行,接受用户的输入。如果去掉这两句,程序直接return返回了,gg。由于程序是release版,没有调试符号,只能忍受汇编指令。不过由于程序比较简单,重复观察push/push/push/call操作即可,因此希望你不要觉得可怕而中途溜走。

为了证明开始时几个HeapAlloc分配得到的堆块来自私有堆空闲链表,可用HEAP验证: 解释一下

1.程序开始时,堆管理器中只有一大块空闲内存,由FreeList[0]指向,当前FreeList[0]的地址是0x003a0178,空闲内存地址是0x3a1e90。对于这段代码,开始的几句HeapAlloc都是瓜分这块内存区域的内存;
2._HEAP!FrontEndHeap指向程序快表地址,对于这段代码,快表位于0x3a0688;

3.由于MS并没有公开快表结构,对于xp系统,只知每个快表项占0x30B,按调试的结论,可能是这样的结构

4._HEAP!FrontEndHeap指向的区域的头0x30B可能是一个快表数组管理结构,之后才是快表数组。目前整个快表数组都是空的
重复以上的调试过程,观察h1/h2/h3/h4分配到的内存空间:

联合h1的值0x3a1e90,每次分配到的内存都和前面相差0x10B,好奇怪啊,每次调用HeapAlloc请求分配8B,结果分配到0x10B,而且前后间隔是等间距的,why

因为对于非调试运行的Release程序HeapAlloc每次分配8+8*N的空间,其中8B是用户空间的管理结构HEAP_ENTRY(细节可参考张银奎老师<软件调试>23章),记载着调用HeapAlloc时分配的空间大小,紧随HEAP_ENTRY之后的8*N8是用户请求空间的数值向上取整的结果,作为用户可用空间返回给请求者;

来源:Yuri800

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年6月4日
下一篇 2016年6月5日

相关推荐