[翻译]Windows 内核池原理 (win7 x86)

0x00:前言

查了一下好像没看到啥关于内核池原理的翻译,国外的一个论文有详细说Win7池溢出的原理。内容比较长,今天来翻译阅读一下Win 7内核的池部分的原理。

0X01:正文

在本节中,我们将详细介绍内核池管理结构和涉及池内存分配和释放的算法。理解内核池行为对于正确评估其安全性和健壮性至关重要。为了简单起见,我们假设是x86架构(32位)。但是,大多数结构都适用于AMD64/x64(64位)。第2.9节讨论了x86和x64架构之间内核池的显著差异。

1. 非一致内存体系结构(NUMA)

对于每个新版本的Windows,内存管理器都得到了增强,以更好地支持非统一内存体系结构(NUMA),这是一种在现代多处理器系统中使用的内存设计体系结构。NUMA将不同的内存库分配给不同的处理器,允许更快地访问本地内存,而更慢地访问远程内存。处理器和内存被分组在称为节点的更小的单元中,由执行内核中的KNODE结构定义。

typedef struct _KNODE
{
/*0x000*/ union _SLIST_HEADER PagedPoolSListHead;
/*0x008*/ union _SLIST_HEADER NonPagedPoolSListHead[3];
/*0x020*/ struct _GROUP_AFFINITY Affinity;
/*0x02C*/ ULONG32 ProximityId;
/*0x030*/ UINT16 NodeNumber;
/*0x032*/ UINT16 PrimaryNodeNumber;
/*0x034*/ UINT8 MaximumProcessors;
/*0x035*/ UINT8 Color;
/*0x036*/ struct _flags Flags;
/*0x037*/ UINT8 NodePad0;
/*0x038*/ ULONG32 Seed;
/*0x03C*/ ULONG32 MmShiftedColor;
/*0x040*/ ULONG32 FreeCount[2];
/*0x048*/ struct _CACHED_KSTACK_LIST CachedKernelStacks;
/*0x060*/ LONG32 ParkLock;
/*0x064*/ ULONG32 NodePad1;
/*0x068*/ UINT8 _PADDING0_[0x18];
} KNODE, *PKNODE;

在多节点系统(nt!KeNumberNodes > 1),内存管理器总是试图从理想的节点分配。因此,KNODE提供了关于在color字段中何处找到本地内存的信息。此值是一个数组索引,分配和自由算法使用该索引将节点与其首选池关联起来。此外,KNODE为空闲池页面定义了四个单链接的每个节点后备列表(在第6节中讨论)。

2. 系统内存池

在系统初始化时,内存管理器根据系统节点的数量创建动态大小的内存池。每个池都由一个池描述符定义,这是一个管理结构,用于跟踪池的使用并定义池属性(如内存类型)。有两种不同类型的池内存:分页内存和非分页内存。

分页池内存可以从任何进程上下文中分配和访问,但只能在中断级别小于DPC/dispatch级别使用。正在使用的分页池的数量由nt!ExpNumberOfPagedPools提供。在单处理器系统上,定义了四(4)个分页池描述符,用nt中的索引1到4表示!ExpPagedPoolDescriptor数组。在多处理器系统上,每个节点定义一个分页池描述符。在这两种情况下,为原型池/全页分配定义了一个额外的分页池描述符,在nt!ExpPagedPoolDescriptor中以索引0表示。因此,在大多数桌面系统中定义了五(5)个分页池描述符。

此外,会话池内存(由win32k使用)用于会话空间分配,并且对于每个用户会话都是惟一的。当非分页会话内存使用全局非分页池描述符时,分页会话池内存在nt!MM_SESSION_SPACE中定义了自己的池描述符。为了获得会话池描述符,Windows 7解析相关的nt!EPROCESS结构去获取绘画空间结构,然后找到嵌入的分页池描述符。

3. 内核池的描述符

与用户模式堆非常相似,每个内核池都需要一个管理结构。池描述符负责跟踪正在运行的分配的数量、正在使用的页面和关于池使用的其他信息。它还帮助系统跟踪可重用的池块。池描述符由以下结构定义(nt!_POOL_DESCRIPTOR)。

typedef struct _POOL_DESCRIPTOR
{
/*0x000*/ enum _POOL_TYPE PoolType;
union {
/*0x004*/ struct _KGUARDED_MUTEX PagedLock;
/*0x004*/ ULONG32 NonPagedLock;
};
/*0x040*/ LONG32 RunningAllocs;
/*0x044*/ LONG32 RunningDeAllocs;
/*0x048*/ LONG32 TotalBigPages;
/*0x04C*/ LONG32 ThreadsProcessingDeferrals;
/*0x050*/ ULONG32 TotalBytes;
/*0x054*/ UINT8 _PADDING0_[0x2C];
/*0x080*/ ULONG32 PoolIndex;
/*0x084*/ UINT8 _PADDING1_[0x3C];
/*0x0C0*/ LONG32 TotalPages;
/*0x0C4*/ UINT8 _PADDING2_[0x3C];
/*0x100*/ VOID** PendingFrees;
/*0x104*/ LONG32 PendingFreeDepth;
/*0x108*/ UINT8 _PADDING3_[0x38];
/*0x140*/ struct _LIST_ENTRY ListHeads[512];
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;

池描述符包含内存管理器使用的几个重要列表。pendingfrees指向的延迟释放列表是等待释放的池块的单链接列表。第8节对此作了详细说明。ListHeads是一个由相同大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值