美文网首页
Windows堆的分析

Windows堆的分析

作者: 萍水间人 | 来源:发表于2019-06-18 19:15 被阅读0次

    又把0day安全翻了一下收获了很多,还是关于堆的知识
    源代码:

    #include <windows.h>
    main()
    {
        HLOCAL h1,h2,h3,h4,h5,h6;
        HANDLE hp;
        hp = HeapCreate(0,0x1000,0x10000);
        __asm int 3
    
        h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,3);
        h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,5);
        h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,6);
        h4 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
        h5 = HeapAlloc(hp,HEAP_ZERO_MEMORY,19);
        h6 = HeapAlloc(hp,HEAP_ZERO_MEMORY,24);
        
        //free block and prevent coaleses
        HeapFree(hp,0,h1); //free to freelist[2] 
        HeapFree(hp,0,h3); //free to freelist[2] 
        HeapFree(hp,0,h5); //free to freelist[4]
        
        HeapFree(hp,0,h4); //coalese h3,h4,h5,link the large block to freelist[8]
    
        
        return 0;
    }
    

    堆的起始地址为3a0000
    偏移3a0178处为freelist
    可以看到这里有好多指针



    3a0688处的这一个堆块是最大的,后续的分配从这里开始


    第一次分配16字节:返回的句柄为3a0688,但是实际上在之前还有16个字节的块首
    02代表分配的是16字节,


    此时的freelist指向了3a0698



    再分配16字节

    然后freelist的指针继续修改


    继续分配:
    此时已经分配了4个16个字节


    接下来分配两次32字节的
    这是所有分配出去的


    此时freelist0指向了3a0708,这应该很明显了吧

    接下来开始释放,释放掉h1和h3,它们都是16个字节的,所以由freelist2来管理它们

    第一次释放掉h1


    3a0188就是freelist2
    freelist2也指向了h1


    继续释放掉h3
    此时
    freelist2的flink指向,h1的flink指向h3,h3的flink指向freelist2
    就是一个单链表的指向关系


    释放掉h5, h5是32个字节,链接到freelist4

    然后释放掉h4
    触发合并操作

    这是合并之后的堆块
    3a01b8恰好就是freelist8


    Q&A
    堆中的数据存放在哪里?
    一定要对堆的结构很清楚,占用态的堆是由程序员来管理,空闲态的堆是由空表或者快表管理的,所以空闲态的堆块需要用链表链接起来,而对于占用态的堆块的管理这个锅就丢给了程序员。占用态的堆块是没有前向指针和后向指针的,而返回给程序员的句柄只是指向了块身,所以堆块最小也是16个字节(8+8个字节的块首),数据就会存放在块身处

    相关文章

      网友评论

          本文标题:Windows堆的分析

          本文链接:https://www.haomeiwen.com/subject/ltjqqctx.html