首页
社区
课程
招聘
[原创]windows10下的堆结构及unlink分析
发表于: 2018-8-31 00:26 17677

[原创]windows10下的堆结构及unlink分析

2018-8-31 00:26
17677

最近调试windows下堆的cve的时候发现对windows下的堆管理理解不够,对javascript堆分配和利用基础不够,由于windows下没有源码可以看,只能通过网上的博客和调试器自己学习。windows堆管理在不断更新,博客内容会有所偏差,接下来的笔记是windows10上的堆结构。

这个函数创建一个只有调用进程才能访问的私有堆。进程从虚拟地址空间里保留出一个连续的块并且为这个块特定的初始部分分配物理空间。

HANDLE HeapCreate(DWORD flOptions , DWORD dwInitialSize , DWORD dwMaxmumSize);

参数:

flOptions:堆的可选属性。这些标记影响以后对这个堆的函数操作,函数有:HeapAlloc , HeapFree , HeapReAlloc , HeapSize .

下面给_出在此可以指定的标记:

HEAP_NO_SERIALIAZE:指定当函数从堆里分配和释放空间时不互斥(不使用互斥锁)。当不指定该标记时默认为使用互斥。序列化允许多个线程操作同一个堆而不会错误。这个标记是可忽略的。

HEAP_SHARED_READONLY:这个标记指定这个堆只能由创建它的进程进行写操作,对其他进程是只读的。如果调用者不是可靠的,调用将会失败,错误代码ERROR_ACCESS_DENIDE 。

注解:为了使用标记为HEAP_SHARED_READONLY的堆,运行在kernel mode(核心状态)是必须的。

dwInitialSize:堆的初始大小,单位为Bytes。这个值决定了分配给堆的初始物理空间大小。这个值将向上舍入知道下个page boundary(页界)。若需得到主机的页大小,使用GetSystemInfo 函数。

dwMaxmumSize:如果该参数是一个非零的值,它指定了这个堆的最大大小,单位为Bytes。该函数会向上舍入该值直到下个页界,然后为这个堆在进程的虚拟地址里保留舍入后大小的块。如果函数 HeapAlloc 和 HeapReAlloc 要求分配的空间超过参数 dwInitialSize 指定的大小,系统会分配额外的空间给该堆直到这个堆的最大大小。If dwMaximumSize is nonzero, the heap cannot grow and an absolute limitation arises where all allocations are fulfilled within the specified heap unless there is not enough free space. (如果该参数非零,除非没有足够的空间,这个堆总可以增长到该大小)。如果该参数为零,那么该堆大小的唯一限制是可用的内存空间。分配大小超过 0x0018000 Bytes的空间总会失败,因为获得这么大的空间需要系统调用 VirtualAlloc 函数。需要使用大空间的应用应该把该参数设置为零。

返回值:

成功:一个指向新创建的堆的指针。

失败:NULL

调用函数 GetLastError 获得更多的错误信息。

附注:

这个函数在调用进程里创建一个私有堆,进程可调用 HeapAlloc 函数分配内存空间。这些页在进程的虚拟空间内创建了一个块,在那里堆可以增长。

如果 HeapAlloc 函数请求的空间超过了现有的页大小,如果物理空间足够的话,额外的空间将会从已保留的空间里附加。

只有创建私有堆的进程可以访问私有堆。

如果一个DLL(动态链接库)创建了一个私有堆,那么这么私有堆是在调用该DLL的进程的地址空间内,且仅该进程可访问。

系统会使用私有堆的一部分空间去储存堆的结构信息,所以,不是所有的堆内空间对进程来说是可用的。例如:HeapAlloc函数从一个最大大小为 64KB 的堆里申请 64KB 的空间,由于系统占用的一部分空间,这个请求通常会失败。

LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes,
);

hHeap
要分配堆的句柄,可以通过HeapCreate()函数或GetProcessHeap()函数获得。

dwFlags
堆分配时的可选参数,其值可以为以下的一种或多种:
HEAP_GENERATE_EXCEPTIONS
如果分配错误将会抛出异常,而不是返回NULL。异常值可能是STATUS_NO_MEMORY, 表示获得的内存容量不足,或是STATUS_ACCESS_VIOLATION,表示存取不合法。
HEAP_NO_SERIALIZE
不使用连续存取。
HEAP_ZERO_MEMORY
将分配的内存全部清零。

dwBytes
要分配堆的字节数。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-1-28 13:49 被admin编辑 ,原因:
收藏
免费 2
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  demoscene   +1.00 2018/09/14
最新回复 (14)
雪    币: 11877
活跃值: (3484)
能力值: (RANK:520 )
在线值:
发帖
回帖
粉丝
2
感谢分享!
2018-8-31 10:08
0
雪    币: 3818
活跃值: (4012)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
感谢分享!
2018-8-31 10:31
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
4
Windows的堆管理搞不动搞不动,太变态了
2018-8-31 10:56
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
5
不过也不能说glibc粗糙,Windows堆这套东西影响了多少性能大家也不是不清楚。。benchmark跑一跑就知道了。。。
2018-8-31 11:02
0
雪    币: 3671
活跃值: (651)
能力值: ( LV15,RANK:379 )
在线值:
发帖
回帖
粉丝
6
holing 不过也不能说glibc粗糙,Windows堆这套东西影响了多少性能大家也不是不清楚。。benchmark跑一跑就知道了。。。
但是感觉关键的最后一步。glibc没有   多检验一次fd指针处的堆有效性感觉代价没有那么高2333
2018-8-31 11:05
0
雪    币: 328
活跃值: (39)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
感谢分享!
2018-8-31 12:29
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
8
sixty的梦想 但是感觉关键的最后一步。glibc没有 多检验一次fd指针处的堆有效性感觉代价没有那么高2333
这个怎么检测,堆的内存页都不一定连续
2018-9-1 19:52
0
雪    币: 3671
活跃值: (651)
能力值: ( LV15,RANK:379 )
在线值:
发帖
回帖
粉丝
9
holing 这个怎么检测,堆的内存页都不一定连续
比windows少一个堆块的有效性校验。windows chunk头部多一个字节用于校验。加密后伪造不了。linux没这个
2018-9-2 00:00
0
雪    币: 714
活跃值: (82)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
10
能伪造加密标志位或者HEAP的解密秘钥吗?
2018-9-2 10:48
0
雪    币: 3671
活跃值: (651)
能力值: ( LV15,RANK:379 )
在线值:
发帖
回帖
粉丝
11
xyy吸氧羊 能伪造加密标志位或者HEAP的解密秘钥吗?
只能在可写范围内伪造   但是这样伪造没有什么意义。因为已经有可写权限了
2018-9-2 12:14
0
雪    币: 3567
活跃值: (467)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
12
tql tql
2018-9-8 19:33
0
雪    币: 1
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
glibc开源,细节可以在代码中看到;windows不开源,细节只能通过逆了;
2019-8-4 23:58
0
雪    币: 1
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你好,对于0x30以上的堆块,没有你提到的unlink检测,0x20就有该检测机制
2021-5-17 22:28
1
雪    币: 1
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
就是有的有检测,有的堆块没检测,这是有什么规律吗
2021-5-17 22:29
1
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册