Debugging Tools for Windows

!vtop

!vtop扩展命令将虚拟地址转换成对应的物理地址,并且显示其他的页表和页目录信息。

语法

Windows 2000的语法

!vtop PFN VirtualAddress 

Windows XP和之后的语法

!vtop PFN VirtualAddress 
!vtop 0 VirtualAddress 

参数

DirBase
指定进程页目录的基址。每个进程都有自己的虚拟地址空间。使用!process扩展命令来查看进程的页目录基址。
PFN
指定进程页目录基址的页面帧序号(PFN)。
0
(Windows XP和之后)!vtop使用当前的进程上下文进行地址转换。
VirtualAddress
指定要转换的页面的虚拟地址。

DLL

Windows NT 4.0 Kdextx86.dll
Windows 2000 Kdextx86.dll
Windows XP和之后 Kdexts.dll

注释

要使用这个命令,首先应该用!process扩展来查看进程的页目录基址。页目录基址的页面帧序号(PFN)可以通过将它的地址最后三个16进制0数字去掉来获得(换句话说,就是右移12位)。

下面是一个示例:

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
....
PROCESS ff779190  SessionId: 0  Cid: 04fc    Peb: 7ffdf000  ParentCid: 0394
    DirBase: 098fd000  ObjectTable: e1646b30  TableSize:   8.
    Image: MyApp.exe

如果页目录基地址为0x098FD000,那么它的PFN 为0x098FD。

kd> !vtop 98fd 12f980
Pdi 0 Pti 12f
0012f980 09de9000 pfn(09de9)

注意最后三个0是可选的(貌似原文有错漏Notice how the trailing three zeros are optional.)。!vtop扩展命令会显示页目录索引(page directory index (PDI))、页表索引(page table index (PTI))、输入的虚拟地址、物理页面开始位置的物理地址、以及页表项(PTE)的页面帧序号(PFN)。

如果要将虚拟地址0x0012F980 转换成物理地址,只需要简单的将最后三个16进制数字 (0x980)加到页面开始处的物理地址(0x09DE9000)上。得到的物理地址为0x09DE9980。

如果忘记去掉那三个0,并且将完整的页目录基址传递给了!vtop,而不是 使用PFN,那么结果通常都会是正确的。这是由于!vtop接收到一个太大的PFN数字时,会将它右移16位后再使用:

kd> !vtop 98fd 12f980
Pdi 0 Pti 12f
0012f980 09de9000 pfn(09de9)

kd> !vtop 98fd000 12f980
Pdi 0 Pti 12f
0012f980 09de9000 pfn(09de9)

但是,最好还是使用PFN,因为有些页目录基址在这种情况下不会被转换。

附加信息

关于获得这些结果的其他方法,查看将虚拟地址转换成物理地址。还可以查看!ptov!vpdd。关于页表和页目录的信息,查看Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals

Build machine: CAPEBUILD