现在的位置: 首页 > 综合 > 正文

Windows运用AVL树对进程地址空间的管理

2013年10月13日 ⁄ 综合 ⁄ 共 3101字 ⁄ 字号 评论关闭

32位Windows系统中,进程在用户态可用的地址空间范围是低2G(x64下是低8192G)。随着进程不断的申请和释放内存,这个2G的地址空间,有的地址范围是保留状态(reserved),有的地址范围是提交状态(映射到了物理页面,committed),有的地址范围是空闲的。Windows采用平衡二叉树把这些离散的地址范围管理起来。

常见的平衡二叉树有红黑树和AVL树两种,其中红黑树应用更广,C#/Java/C++STL等若干数据结构内部都是用红黑树实现的,然而Windows这次选择了AVL树。根据 《数据结构与算法C语言描述》,AVL树的最大高度是1.44 * log(N+2) - 1.328,红黑树的最大高度是2.00* log(N+1)。与红黑树相比,AVL树的插入删除操作更慢一些,但是查询操作更快。想必对进程地址空间的查询操作更频繁一些,所以AVL得以入选。

AVL树的节点结构是

typedef struct _MMADDRESS_NODE {
    ULONG_PTR StartingVpn;  // 起始虚拟地址
    ULONG_PTR EndingVpn;   // 终止虚拟地址
    struct _MMADDRESS_NODE *Parent;
    struct _MMADDRESS_NODE *LeftChild;
    struct _MMADDRESS_NODE *RightChild;
} MMADDRESS_NODE, *PMMADDRESS_NODE;

AVL树的根节点保存在进程内核对象_EProcess中。_EProcess的结构没有出现在文档中,但是我们可以通过windbg获取。在Windows 2003中,用windbg获取如下输出:

kd> dt _EProcess
nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x078 ProcessLock      : _EX_PUSH_LOCK
   +0x080 CreateTime       : _LARGE_INTEGER
   +0x088 ExitTime         : _LARGE_INTEGER
   ……
   +0x24c PriorityClass    : UChar
   +0x250 VadRoot          : _MM_AVL_TABLE
   +0x270 Cookie           : Uint4B

上图中偏移量为0x250处的VadRoot字段保存了AVL输根节点所在的地址。因此,在驱动程序中,通过以下代码可以获取当前进程的AVL树的根节点地址。

PMMADDRESS_NODE ZsaGetVmRoot(){
	char * pEProcess = (char*)PsGetCurrentProcess();
	char * avlRoot = pEProcess + 0x250;
	char * p_MM_AVL_TABLE = avlRoot;
	return (PMMADDRESS_NODE) p_MM_AVL_TABLE;
}

既然获得了根地址,则可以对二叉树进行遍历,打印出整个数据结构。以下是某个测试进程在进行了1024*1024次new分配后,AVL树的内容。可以看到,树基本是平衡的。

 

 

0,0

├─────N

└─────280,2b3

            ├─────150,24f

            │          ├─────130,134

            │          │          ├─────20,20

            │          │          │          ├─────10,10

            │          │          │          └─────30,12f

            │          │          └─────140,140

            │          └─────260,275

            │                      ├─────250,25f

            │                      └─────N

            └─────10200,10372

                        ├─────400,502

                        │          ├─────310,315

                        │          │          ├─────2c0,300

                        │          │          └─────370,37f

                        │          │                      ├─────320,360

                        │          │                      └─────380,382

                        │          └─────c10,140f

                        │                      ├─────610,80f

                        │                      │          ├─────510,60f

                        │                      │          └─────810,c0f

                        │                      └─────2410,440f

                        │                                  ├─────1410,240f

                        │                                  └─────4410,840f

                        └─────7c930,7c9ff

                                   ├─────10540,1853f

                                   │          ├─────10480,10536

                                   │          └─────7c800,7c92a

                                   │                      ├─────18540,2853f

                                   │                      └─────N

                                   └─────7ffdd,7ffdd

                                               ├─────7ffa0,7ffd2

                                               │          ├─────7f6f0,7f7ef

                                               │          └─────N

                                                └─────7ffde,7ffde

抱歉!评论已关闭.