1

The !pte command in WinDbg gives all the information one may need regarding a virtual address (PDE and PTE location and content), but even on systems with PAE it says nothing about the Page Directory Pointer Table. I know that I can get the physical base of the PDPT by looking at CR3, and then use the highest 2 bits of the VA as a index in that table to get to the PDPT Entry, but I'm just curious if there is a command that works like !pte when it comes to PAE as it will be a nice tool to verify my address translations step by step.

Also, is there a way to determine MAXPHYADDR? I know it is at most 52.

2 Answers 2

2

for va to phys address translation there is a windbg bang command
!vtop 0 < VirtualAddress > .

a sample output from that command below

kd> !vtop 0 403000
X86VtoP: Virt 00403000, pagedir 11800480
X86VtoP: PAE PDPE 11800480 - 00000000387a9001
X86VtoP: PAE PDE 387a9010 - 000000001b6b7067
X86VtoP: PAE PTE 1b6b7018 - 800000001bb2e225
X86VtoP: PAE Mapped phys 1bb2e000
Virtual address 403000 translates to physical address 1bb2e000.

below is a windbg script that i wrote (can be buggy havent tested this in a 64 bit machine )
this script takes a process name and a virtual address in that process splits it into pd pde pte and offset and retrieves the physical address and prints the contents.

script contents

r $t0 = ${$arg1}
r $t1 = ${$arg2}
r $t2 = (( @$t1 & 0xc0000000 ) >> 0n29 )
r $t3 = (( @$t1 & 0x3fe00000 ) >> 0n21 )
r $t4 = (( @$t1 & 0x001ff000 ) >> 0n12 )
r $t5 = (( @$t1 & 0x00000fff ) >> 0n00 )
.printf "Page Directory Index      \t%x\n" , @$t2
.printf "Page Directory Entry Index\t%x\n" , @$t3
.printf "Page Table Entry Index    \t%x\n" , @$t4
.printf "Offset                    \t%x\n" , @$t5
.foreach /pS 1 /ps 100 ( place { !process 0 0 ${$arg1} } ) { r $t6 = place }
.process /p /r @$t6
db @$t1
r $t7 = @@c++( *(ULONG *)@$proc->Pcb.DirectoryTableBase )
.printf "printing PDINDEX[%08x]\n",@$t2
!dd @$t7 + @$t2 * @@c++(sizeof(INT64)) l1
.printf "printing PDEINDEX[%08x]\n",@$t3
.foreach /pS 1 /ps 100 (place {!dd @$t7 + @$t2 * @@c++(sizeof(INT64)) l1 } ) {r $t8 = ( place & 0xfffff000 ) ; !dd ( place & 0xfffff000) l1 }
.printf "printing PTEINDEX[%08x]\n",@$t4
.foreach /pS 1 /ps 100 (place {!dd @$t8 + @$t3 * @@c++(sizeof(INT64)) l1 } ) {r $t9 = ( place & 0xfffff000 ) ; !dd ( place & 0xfffff000) l1 }
.printf "printing Offset[%08x]\n",@$t5
.foreach /pS 1 /ps 100 (place {!dd @$t9 + @$t4 * @@c++(sizeof(INT64)) l1 } ) {r $t10 = ( place & 0xfffff000 ) ; !db ( place & 0xfffff000) }

output of a sample run

lkd> $$>a< .\scripts\splitva.txt msgbox.exe 403000
Page Directory Index        0
Page Directory Entry Index  2
Page Table Entry Index      3
Offset                      0
Implicit process is now 86389020
Loading User Symbols
..........
00403000  49 63 7a 65 6c 69 6f 6e-27 73 20 74 75 74 6f 72  Iczelion's tutor
00403010  69 61 6c 20 6e 6f 2e 32-00 57 69 6e 33 32 20 41  ial no.2.Win32 A
00403020  73 73 65 6d 62 6c 79 20-69 73 20 47 72 65 61 74  ssembly is Great
00403030  21 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  !...............
00403040  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00403050  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00403060  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
00403070  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
printing PDINDEX[00000000]
#11800480 387a9001
printing PDEINDEX[00000002]
#387a9000 297b9067
printing PTEINDEX[00000003]
#1b6b7000 3dcb8025
printing Offset[00000000]
#1bb2e000 49 63 7a 65 6c 69 6f 6e-27 73 20 74 75 74 6f 72 Iczelion's tutor
#1bb2e010 69 61 6c 20 6e 6f 2e 32-00 57 69 6e 33 32 20 41 ial no.2.Win32 A
#1bb2e020 73 73 65 6d 62 6c 79 20-69 73 20 47 72 65 61 74 ssembly is Great
#1bb2e030 21 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 !...............
#1bb2e040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#1bb2e050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#1bb2e060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#1bb2e070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
1
  • Thanks for !vtop and that script. It's a bit weird that !pte displays all the information on x64, but on x86 PAE it ignores the first paging structure and goes directly to the Page Directory. Oct 10, 2014 at 13:48
2

To answer your other question, maxphyaddr and the AMD counterpart are found via cpuid leaves, but it's important to note that the bus interface to the MCH (which is typically integrated on the cpu these days) probably only uses 33-36 of those lines on the address bus.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.