• 5.2 空表实验


    !!!本实验仅供信息防御学习,请勿用于非法用途!!!

    目录

    一、实验环境

    二、实验代码

    三、实验步骤

    1、识别堆表

    2、堆块的分配

    3、堆块释放

     4、堆块的合并


    一、实验环境

            操作系统:windows 2000 professional

            软件:ollydbg原版、vc++6.0

            !!!OD务必用原版,其他版本可能出现OD找不到出现入口地址的情况(如下图)!!!

    (图有点糊)

             VC++6.0 build版本:release版本(默认Debug版本)

            如何编译时改为release版本?

            (1)勾选组件:

             (2)选择Win32 Release版本

            此外,不能直接使用OD加载编译生成的exe文件,需要更改实时调试设置,改为“设置OllyICE为实时调试器”(请忽略OllyICE);设置为实时调试器后,编译C程序后,会直接跳到OD中。

             另外,因为堆管理函数会检测当前进程的状态,如果不按上述的来,堆管理函数就会检测到当前进程处于调试态,而使用调试态堆管理策略。

            调试态堆管理策略与常态堆管理策略有以下不同:

            (1)调试堆不使用快表,只用空表分配;

            (2)所有堆块都被加上了多余的16字节尾部防止溢出(防止程序溢出而不是堆溢出攻击),16字节中包括0字节的0xAB和8字节的0x00。如下图所示。

            (3)块首的标志位不同。正常的块首标志为10.

    二、实验代码

    1. #include
    2. main()
    3. {
    4. //本地内存对象句柄
    5. HLOCAL h1,h2,h3,h4,h5,h6;
    6. HANDLE hp;
    7. //创建一个堆对象,可被调用者使用
    8. hp = HeapCreate(0,0x1000,0x10000);
    9. __asm int 3
    10. h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,3);
    11. h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,5);
    12. h3 = HeapAlloc(hp,HEAP_ZERO_MEMORY,6);
    13. h4 = HeapAlloc(hp,HEAP_ZERO_MEMORY,8);
    14. h5 = HeapAlloc(hp,HEAP_ZERO_MEMORY,19);
    15. h6 = HeapAlloc(hp,HEAP_ZERO_MEMORY,24);
    16. //free block and prevent coaleses
    17. HeapFree(hp,0,h1); //free to freelist[2]
    18. HeapFree(hp,0,h3); //free to freelist[2]
    19. HeapFree(hp,0,h5); //free to freelist[4]
    20. HeapFree(hp,0,h4); //coalese h3,h4,h5,link the large block to freelist[8]
    21. return 0;
    22. }

    三、实验步骤

    1、识别堆表

            在VC编译后,直接会跳到OD中;

             可以看到,程序停在CC INT3处,HeapCreate函数创建一个堆区,会返回指向堆的指针;

            数据窗口跳转到0x0036000,堆表中包含的信息依次为:

    • 段表索引(Segment List)
    • 虚表索引(Virtual Allocation list)
    • 空表使用标识(freelist usage bitmap)
    • 空表索引区

            !!!我们更关注偏移地址为0x178的空表索引区!!!

             当一个堆初始化的时候,只有一个空闲态的大块,这个块被称为“尾块”。空表中含有128项,每项两个指针地址。除了偏移地址为0X178位置开始的四个字节,指向尾块,其余项均指向自己。

             感谢前辈的分享精神,首先回顾快首中各字段的含义。

            (1)占用态堆块的数据结构

            (2)空闲态堆块的数据结构

            在数据窗口中,跳转到0x360688处,0x360688前面的八个字节代表块首,0x360688开始为块身。块身的前八个字节为下一个节点的地址,因为尾块就是最后一个块,故指向索引表。

    2、堆块的分配

            对于堆分配我们应该注意以下几点:

            (1)堆块的大小包括块首在内,也就是如果请求32字节,实际会分配的堆块为40字节:8+32;

            (2)堆块的单位为8字节,不足8字节的部分按8字节分配;

            (3)按照内存块的大小不一样,对应的分配和释放方案如下:

    对应的分配和释放策略
    分配释放
    小块

    首先进行快表分配;

    若快表分配失败,进行普通空表分配;

    若普通空表分配失败,使用堆缓存(heap cache)分配;

    若堆缓存分配失败,尝试零号空表分配;

    若零号空表分配失败,进行内存紧缩后再尝试分配;

    若仍无法分配,返回NULL。

    优先链入快表(只能链入四个空闲块);

    如果快表满,则将其链入相应的空表。

    大块

    首先使用堆缓存进行分配;

    若堆缓存分配失败,使用free[0]中的大块进行分配。

    优先将其放入堆缓存

    若堆缓存满,将其链入freelist[0]

    巨块

    一般来说,巨快申请非常罕见,要用到虚分配方法

    基本遇不到

    直接释放,没有堆表操作

            初始状态下,快表和空表都为空,不存在精确分配。请求将使用“次优块”进行分配,这个次优块就是位于偏移地址为0x0688处的尾块。

            (4)由于次优分配的发生,分配函数会陆续从尾块中切走一些小块,并修改尾块块首的size信息,最后把free[0]指向新的尾块位置。

            对于6次内存请求,实际分配情况:

    实际分配情况
    句柄申请字节数实际分配(堆单位)实际分配字节数
    h13216
    h25216
    h36216
    h48216
    h519432
    h624432

           

             申请完h1,查看数据窗口:

            

             完成所有申请请求:

           

    3、堆块释放

            完成h1的释放,可见数据窗口,修改了flag位为00,并且将h1链入free[2]。

            !!!注:块表只出现在可拓展的堆中,需要使用HeapCreate(0,0,0)命令,故,不会链入块表。

             数据窗口跳转到0x360178处,可见空表索引区free[2]的指针指向0x00360688(即h1处)

            

            释放h3,h3插入链表尾部,链入free[2];

            具体指向请参考:(一次释放h1、h3、h5)

     

            释放h5,链入free[4];

     4、堆块的合并

            释放h4时,因为h3、h4、h5在一块,故会发生堆块合并现象。

            做法:

            (1)首先将这三个空闲块从空表中拿下;

            (2)然后重新计算堆块的大小;

            (3)最后按照合并后的大小把新块链入空表。

            在数据窗口中,可以看到堆块大小已经改为08,且指向0x3601B8

            

            在数据窗口中,跳转到0x3601B8处,可以发现0x3601B8就是空表索引free[8],free[4]处也指向了其本身。

  • 相关阅读:
    JVM面试篇
    火灾隐患是查不完的,消防监管要着力于提升单位消防能力
    前端设计之03_接口文档
    该如何训练好深度学习模型?
    What is SVM algorithm
    lotus MaxStorage 限制存储空间使用
    HMM隐马尔可夫模型用于序列标注
    计算机专业毕业设计项目推荐14-文档编辑平台(SpringBoot+Vue+Mysql)
    pymssql 保存进db Unclosed quotation mark after the character string
    iptables的使用
  • 原文地址:https://blog.csdn.net/qq_55202378/article/details/127080407