📄 jiurl玩玩win2k内存篇 vad.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0066)http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/MmVad.htm -->
<HTML><HEAD><TITLE>JIURL玩玩Win2k内存篇 VAD</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<STYLE type=text/css>.title {
FONT-FAMILY: "黑体", Arial, sans-serif; FONT-SIZE: 21px; FONT-WEIGHT: bold; LINE-HEIGHT: 48px; TEXT-DECORATION: none
}
.author {
FONT-FAMILY: "宋体"; FONT-SIZE: 12px; LINE-HEIGHT: 16px
}
.content {
FONT-SIZE: 14px; LINE-HEIGHT: 20px
}
</STYLE>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY bgColor=#f7f7f7 topMargin=5>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=29 width="96%">
<TBODY>
<TR>
<TD class=title height=41 width="100%">
<P align=center><FONT face=宋体>JIURL玩玩Win2k内存篇 </FONT><FONT
face=宋体>VAD</FONT></P></TD></TR></CENTER>
<TR>
<TD class=author height=9 width="100%">
<P align=center><FONT face=宋体>作者: <A
href="mailto:jiurl@mail.china.com">JIURL</A> </FONT></P></TD></TR>
<TR>
<TD class=author height=6 width="100%">
<P align=center><FONT
face=宋体>
主页: <A href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A>
</FONT></P></TD></TR>
<TR>
<TD class=author height=2 width="100%">
<P align=center><FONT face=宋体> 日期: 2003-7-30</FONT>
</P></TD></TR></TBODY></TABLE></DIV>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=1 width="96%">
<TBODY>
<TR>
<TD height=1 width="100%">
<HR color=#396da5 SIZE=3>
</TD></TR></TBODY></TABLE></CENTER></DIV>
<DIV align=center>
<TABLE border=0 cellPadding=0 cellSpacing=0 class=content height=4300
width="96%">
<TBODY>
<TR>
<TD height=2132 vAlign=top width="131%"> 在程序中我们可以使用
VirtualAlloc
在用户地址空间(4G地址空间中的低2G)中申请(保留或者提交)指定地址和大小的一段地址空间。那么系统如何知道指定的这段地址空间是不是已经被分配(保留或者提交)。对于指定地址空间是否已经被提交了物理内存,可以通过页目录和页表来判断,不过这样做很麻烦。而对于指定地址空间是否已经被保留,通过页目录和页表没有办法判断。Win2k
中使用 VAD 来解决这个问题。
<P> VAD 是 virtual address descriptor 的缩写,即
虚拟地址描述符。一个VAD保存一段被分配地址空间的信息,所有VAD组成一个二叉排序树来描述用户地址空间的情况。每个进程有自己的用户地址空间,所以每个进程也有自己的VAD二叉排序树。VAD二叉排序树的根的地址保存在进程结构
EPROCESS 中。对于 Win2k build 2195 来说,VadRoot 在 EPROCESS 偏移 +194 处。</P>
<P>
二叉排序树是一棵二叉树,每个节点最多有左右两个子树。左子树上的所有节点的值均小于它的根节点的值,右子树上所有节点的值均大于它的根节点的值。使用二叉排序树是为了保证查找速度。</P>
<P>VAD 结构定义如下</P>
<P>typedef struct _VAD_HEADER {<BR>/*00*/ PVOID StartVPN;<BR>/*04*/ PVOID
EndVPN;<BR>/*08*/ _VAD_HEADER* ParentLink;<BR>/*0C*/ _VAD_HEADER*
LeftLink;<BR>/*10*/ _VAD_HEADER* RightLink;<BR>/*14*/ ULONG CommitCharge :
20;<BR>/*14*/ ULONG Flags : 12;<BR>/*18*/ PVOID ControlArea;<BR>/*1C*/
PVOID FirstProtoPte;<BR>/*20*/ PVOID LastPTE;<BR>/*24*/ ULONG
Unknown;<BR>/*28*/ LIST_ENTRY Secured;<BR>/*30*/ } VAD_HEADER,
*PVAD_HEADER;<BR><BR>StartVPN<BR>这个VAD所描述的那段地址空间的开始虚拟页号<BR><BR>EndVPN<BR>这个VAD所描述的那段地址空间的结束虚拟页号<BR><BR>CommitCharge<BR>提交的物理页数</P>
<P>VAD 结构的一些其他字段,会在其他用到的地方做更多的介绍。</P>
<P>下面我们使用 kd 看一个实际的例子<BR><BR>\\ 系统进程的PID为8<BR>kd> !process 8
0<BR>!process 8 0<BR>Searching for Process with Cid == 8<BR>PROCESS
8141e020 SessionId: 0 Cid: 0008 Peb: 00000000 ParentCid: 0000<BR>DirBase:
00030000 ObjectTable: 81452a68 TableSize: 106.<BR>Image: System<BR>\\
系统进程的 EPROCESS 地址为 8141e020<BR><BR>\\ 对于 Win2k build 2195 来说 VadRoot 在
EPROCESS 偏移 +194 处<BR>kd> !strct eprocess 8141e020<BR>...<BR>+194 void
*VadRoot = 8141BB48<BR>...<BR>\\ VadRoot 地址为 8141BB48<BR><BR>kd> !vad
8141BB48<BR>!vad 8141BB48<BR>VAD level start end commit<BR>8141bb48 ( 0)
10 42 0 Mapped READWRITE<BR>810f8208 ( 2) 60 60 1 Private
READWRITE<BR>810ba508 ( 3) 70 70 0 Mapped READWRITE<BR>813e6ca8 ( 1) 77f80
77ff8 3 Mapped Exe EXECUTE_WRITECOPY<BR><BR>Total VADs: 4 average level: 2
maximum depth: 3<BR><BR>\\ 我们来看一下根节点的VAD中的具体内容,根节点在 8141bb48 处<BR>kd>
dd 8141bb48 l 30/4<BR>dd 8141bb48 l 30/4<BR>8141bb48 00000010 00000042
00000000 00000000<BR>8141bb58 813e6ca8 04000000 8141bae8
e10089e0<BR>8141bb68 e1008aa8 40000000 00000000
00000000<BR><BR>需要指出的是,只有系统进程的用户地址空间会这么简单,一般的程序的VAD二叉树都会有20多个节点。<BR>下面我们再来看一个例子,这是我写的一个程序
<A
href="http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/JiurlVadSee.zip">JiurlVadSee</A>
的输出,它可以列出指定进程的VAD二叉树。系<BR>统中运行进程的ID可以通过 Windows任务管理器
获得。<BR><BR>ProcessId(Decimal): 556<BR>0 - Min Information 1 - Max
Information<BR>Type: 1<BR><BR>Vad Level StartVPN EndVPN Commit
Flags<BR><BR>0x82b05928 [ 1] 0x00010 0x00010 1 c40<BR>StartVirtualAddress:
0x00010000 EndVirtualAddress: 0x00010fff<BR>/*00*/ PVOID StartVPN; =
0x00010<BR>/*04*/ PVOID EndVPN; = 0x00010<BR>/*08*/ _VAD_HEADER*
ParentLink; = 0x810482a8<BR>/*0C*/ _VAD_HEADER* LeftLink; =
0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; = 0x82b05da8<BR>/*14*/ ULONG
CommitCharge:20; = 0x00001<BR>/*14*/ ULONG Flags :12; = 0xc40<BR>/*18*/
PVOID ControlArea; = 0x02018001<BR>/*1C*/ PVOID FirstProtoPte; =
0x20646156<BR>/*20*/ PVOID LastPTE; = 0x00005240<BR>/*24*/ ULONG Unknown;
= 0x0000533f<BR>/*28*/ LIST_ENTRY Secured; = 0x8106d2e8
0x00000000<BR><BR><BR>0x82b05da8 [ 2] 0x00020 0x00020 1
c40<BR>StartVirtualAddress: 0x00020000 EndVirtualAddress:
0x00020fff<BR>/*00*/ PVOID StartVPN; = 0x00020<BR>/*04*/ PVOID EndVPN; =
0x00020<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x82b05928<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x8269a808<BR>/*14*/ ULONG CommitCharge:20; = 0x00001<BR>/*14*/ ULONG
Flags :12; = 0xc40<BR>/*18*/ PVOID ControlArea; = 0x02018001<BR>/*1C*/
PVOID FirstProtoPte; = 0x20646156<BR>/*20*/ PVOID LastPTE; =
0x0007ffd8<BR>/*24*/ ULONG Unknown; = 0x0007ffd8<BR>/*28*/ LIST_ENTRY
Secured; = 0x84875a28 0x00000000<BR><BR><BR>0x8269a808 [ 3] 0x00030
0x0012f 3 840<BR>StartVirtualAddress: 0x00030000 EndVirtualAddress:
0x0012ffff<BR>/*00*/ PVOID StartVPN; = 0x00030<BR>/*04*/ PVOID EndVPN; =
0x0012f<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x82b05da8<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x826f9ba8<BR>/*14*/ ULONG CommitCharge:20; = 0x00003<BR>/*14*/ ULONG
Flags :12; = 0x840<BR>/*18*/ PVOID ControlArea; = 0x02018001<BR>/*1C*/
PVOID FirstProtoPte; = 0x20646156<BR>/*20*/ PVOID LastPTE; =
0x000777f0<BR>/*24*/ ULONG Unknown; = 0x000777fd<BR>/*28*/ LIST_ENTRY
Secured; = 0x82a65c28 0x82f11e88<BR><BR><BR>0x826f9ba8 [ 4] 0x00130
0x0022f 4 840<BR>StartVirtualAddress: 0x00130000 EndVirtualAddress:
0x0022ffff<BR>/*00*/ PVOID StartVPN; = 0x00130<BR>/*04*/ PVOID EndVPN; =
0x0022f<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x8269a808<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x810b7fc8<BR>/*14*/ ULONG CommitCharge:20; = 0x00004<BR>/*14*/ ULONG
Flags :12; = 0x840<BR>/*18*/ PVOID ControlArea; = 0x02018001<BR>/*1C*/
PVOID FirstProtoPte; = 0x45746146<BR>/*20*/ PVOID LastPTE; =
0x834e40e8<BR>/*24*/ ULONG Unknown; = 0x8351dde8<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x810b7fc8 [ 5] 0x00230
0x0023f 0 040<BR>StartVirtualAddress: 0x00230000 EndVirtualAddress:
0x0023ffff<BR>/*00*/ PVOID StartVPN; = 0x00230<BR>/*04*/ PVOID EndVPN; =
0x0023f<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x826f9ba8<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x8109d6c8<BR>/*14*/ ULONG CommitCharge:20; = 0x00000<BR>/*14*/ ULONG
Flags :12; = 0x040<BR>/*18*/ PVOID ControlArea; = 0x86346148<BR>/*1C*/
PVOID FirstProtoPte; = 0xe33eda40<BR>/*20*/ PVOID LastPTE; =
0xe33eda7c<BR>/*24*/ ULONG Unknown; = 0x00000000<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x8109d6c8 [ 6] 0x00240
0x00255 0 010<BR>StartVirtualAddress: 0x00240000 EndVirtualAddress:
0x00255fff<BR>/*00*/ PVOID StartVPN; = 0x00240<BR>/*04*/ PVOID EndVPN; =
0x00255<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x810b7fc8<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x82b057a8<BR>/*14*/ ULONG CommitCharge:20; = 0x00000<BR>/*14*/ ULONG
Flags :12; = 0x010<BR>/*18*/ PVOID ControlArea; = 0x810e83c8<BR>/*1C*/
PVOID FirstProtoPte; = 0xe2beb380<BR>/*20*/ PVOID LastPTE; =
0xe2beb3d4<BR>/*24*/ ULONG Unknown; = 0x80000000<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x82b057a8 [ 7] 0x00260
0x0028e 0 010<BR>StartVirtualAddress: 0x00260000 EndVirtualAddress:
0x0028efff<BR>/*00*/ PVOID StartVPN; = 0x00260<BR>/*04*/ PVOID EndVPN; =
0x0028e<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x8109d6c8<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x82b05768<BR>/*14*/ ULONG CommitCharge:20; = 0x00000<BR>/*14*/ ULONG
Flags :12; = 0x010<BR>/*18*/ PVOID ControlArea; = 0x810e7be8<BR>/*1C*/
PVOID FirstProtoPte; = 0xe2becd20<BR>/*20*/ PVOID LastPTE; =
0xe2becdd8<BR>/*24*/ ULONG Unknown; = 0x80000000<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x82b05768 [ 8] 0x00290
0x002d0 0 010<BR>StartVirtualAddress: 0x00290000 EndVirtualAddress:
0x002d0fff<BR>/*00*/ PVOID StartVPN; = 0x00290<BR>/*04*/ PVOID EndVPN; =
0x002d0<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x82b057a8<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x82b05728<BR>/*14*/ ULONG CommitCharge:20; = 0x00000<BR>/*14*/ ULONG
Flags :12; = 0x010<BR>/*18*/ PVOID ControlArea; = 0x810e7828<BR>/*1C*/
PVOID FirstProtoPte; = 0xe2bed600<BR>/*20*/ PVOID LastPTE; =
0xe2bed700<BR>/*24*/ ULONG Unknown; = 0x80000000<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x82b05728 [ 9] 0x002e0
0x002e3 0 010<BR>StartVirtualAddress: 0x002e0000 EndVirtualAddress:
0x002e3fff<BR>/*00*/ PVOID StartVPN; = 0x002e0<BR>/*04*/ PVOID EndVPN; =
0x002e3<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x82b05768<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
0x82b056e8<BR>/*14*/ ULONG CommitCharge:20; = 0x00000<BR>/*14*/ ULONG
Flags :12; = 0x010<BR>/*18*/ PVOID ControlArea; = 0x810e7648<BR>/*1C*/
PVOID FirstProtoPte; = 0xe139cfa0<BR>/*20*/ PVOID LastPTE; =
0xe139cfac<BR>/*24*/ ULONG Unknown; = 0x80000000<BR>/*28*/ LIST_ENTRY
Secured; = 0x00000000 0x00000000<BR><BR><BR>0x82b056e8 [10] 0x002f0
0x00330 0 010<BR>StartVirtualAddress: 0x002f0000 EndVirtualAddress:
0x00330fff<BR>/*00*/ PVOID StartVPN; = 0x002f0<BR>/*04*/ PVOID EndVPN; =
0x00330<BR>/*08*/ _VAD_HEADER* ParentLink; = 0x82b05728<BR>/*0C*/
_VAD_HEADER* LeftLink; = 0x00000000<BR>/*10*/ _VAD_HEADER* RightLink; =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -