堆的学习

0x01 空表的学习

实验环境:winxpsp3中文版。vc++6.0 release版本。调试器:OD
 
示例代码:
#include <windows.h>


int 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;
}

 

 
调试过程
 
一、堆分配:
采用heapcreate创建一个干净的堆,对堆进行学习。
 hp = HeapCreate(0, 0x1000, 0x10000)
堆创建后,返回的堆地址存放在EAX中。
 
 
位于堆偏移0x0688处开始进行真正的堆分配。(如果一开始选择创建可扩展堆,即HeapCreate(0,0,0)创建时,此处为块表所在地址。指向块表的指针位于0x584字节处。本实验里,块表指针为0.)
 
 
未进行分配前,freelist[0]指向了尾块,其他的freelist指向自己。
尾块的块首指向freelist[0] 。尾块大小为0130,计算单位为8个字节,也就是0130(16进制)->304(10进制)。304*8 = 2432(10进制) -> 980(16进制)
 
分配h1时
分配完h6时
 
 
二、堆释放
释放h1,h3,h5时
 
三、堆块的合并
释放h4时,由于h4和h3、h5相邻,故会发生堆块合并,合并后的堆块进行重新计算,链入对应的空表。
 
 
0x02 块表的学习

实验环境:winxpsp3简体中文版,vc++6.0 release版
 
示例代码
#include <stdio.h>
#include <windows.h>


void main()
{
    HLOCAL h1, h2, h3, h4;
    HANDLE hp;
    hp = HeapCreate(0, 0, 0);
    
    __asm int 3


    h1 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 8);
    h2 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 8);
    h3 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 16);
    H4 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 24);


    HeapFree(hp, 0, h1);
    HeapFree(hp, 0, h2);
    HeapFree(hp, 0, h3);
    HeapFree(hp, 0, h4);


    h2 = HeapAlloc(hp, HEAP_ZERO_MEMORY, 16);
    HeapFree(hp, 0, h2);
}

 

 
调试跟踪
1.查看HeapCreate创建的堆
 
 
 
2.进行h1、 h2、h3、h4分配后的情况
 
3.对h1进行释放
块表的情况
 
4.对h2释放的情况
 
5.对h3释放的情况
 
6.对h4释放的情况
 
小结:
 
7.对 h2进行分配,由下图可以看出,从块表上进行分配了
 
8.对h2再进行释放
 
 
总结
从上面的实验可以看出,链入块表中的堆块,其标识位为0x01,即busy状态,这也是块表中的堆块不进行合并的原因。且块首只存指向下一堆块的指针,不存指向前一堆块的指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值