深入浅析Windows内核——VAD篇
为何叫深入浅析呢?所谓深入指的是我们将要面对的是微软公开的Windows源码,适用于Windows XP/Windows Server 2003。所谓浅析当然是指本人水平有限,这能望文生义,做一做表面文章。
大家都知道,在x86的平台上Windows操作系统为每个进程描述了一个完整的4G的地址空间,这4G空间由低位2G的用户地址空间和高位2G的系统地址空间构成。每个进程的用户地址空间是相互隔离的,不可见的。但是系统地址空间是各个进程间共享的,对于进程有不同的视图。用户的私有的数据代码还有加载的动态链接库(DLL)都存放在用户地址空间中。现在有个问题是,总要有个地方记录着这2G地址空间,到底那些被预留了,那些被提交了,那些被访问了吧。还有个问题就是,对于程序来讲,地址不是连续的,是分段的。代码段、数据段、堆、栈等等。可是进程的空间是连续的,从0x0000000到0x7FFFFFF。总要有个数据结构描述程序的各个段对应那段地址空间。这两个重要任务就交个了VAD,即虚拟地址描述符(Virtual Address Descriptor)。
在Windows中,每个进程是由一个EPROCESS结构描述的,这个结构里有一个域MM_AVL_TABLE VadRoot,这就是进程VAD的入口。MM_AVL_TABLE的结构定义如下:
typedef struct _MM_AVL_TABLE {
MMADDRESS_NODE BalancedRoot;
ULONG_PTR DepthOfTree: 5;
ULONG_PTR Unused: 3;
#if defined (_WIN64)
ULONG_PTR NumberGenericTableElements: 56;
#else
ULONG_PTR NumberGenericTableElements: 24;
#endif
PVOID NodeHint;
PVOID NodeFreeHint;
} MM_AVL_TABLE, *PMM_AVL_TABLE;
另外还有两个个相关的结构是MMVAD和MMADDRESS_NODE,定义如下:
typedef struct _MMVAD {
union {
LONG_PTR Balance : 2;
<