看一个实际的例子:
kd> u nt!InitBootProcessor+0x3df: 81b3a6de fec8 dec al 81b3a6e0 f6d8 neg al 81b3a6e2 bfe0df8f81 mov edi,offset nt!ExpBootEnvironmentInformation (818fdfe0) 81b3a6e7 1bc0 sbb eax,eax 81b3a6e9 40 inc eax 81b3a6ea 40 inc eax 81b3a6eb a3f0df8f81 mov dword ptr [nt!ExpBootEnvironmentInformation+0x10 (818fdff0)],eax 81b3a6f0 8b7358 mov esi,dword ptr [ebx+58h] |
上面是 windbg 调试 vista 内核中摘录的一段代码。
现在看一看 81b3a6de 这个 linear address 对应的物理地址是什么?
kd> r cr3 cr3=00122000 kd> r cr4 |
CR4.PAE = 1、CR4.PSE = 0
PAE 开启,是 2M page 还是 4K page,由 PDE 来决定
由 CR3 寄存器得出:PDPT 的基址是 0x00122000
kd> .formats 0x81b3a6de Evaluate expression: Hex: 81b3a6de Decimal: -2118932770 Octal: 20154723336 Binary: 10000001 10110011 10100110 11011110 kd> !dq 0x122000+0x2*8 |
PDT 的基地址是 0x125000,未使用 2M page,它是 4K pages
kd> !dq 0x125000+0xd*8 # 125068 00000000`00141063 00000000`00142063 # 125078 00000000`00143063 00000000`00144063 # 125088 00000000`00145063 00000000`03400963 # 125098 00000000`03401963 00000000`03402963 # 1250a8 00000000`03403963 00000000`03404963 |
PT 的基址是 0x00141000
kd> !dq 0x141000+0x13a*8 # 1419d0 00000000`01b3a163 00000000`01b3b163 # 1419e0 00000000`01b3c163 00000000`01b3d163 # 1419f0 00000000`01b3e163 00000000`01b3f163 # 141a00 00000000`01b40163 00000000`01b41163 |
page 的基址是 0x01b3a000,所以,最终 physical address 是:0x01b3a6de
kd> !db 0x01b3a6de # 1b3a6de fe c8 f6 d8 bf e0 df 8f-81 1b c0 40 40 a3 f0 df [email protected]@... # 1b3a6ee 8f 81 8b 73 58 83 c6 6c-a5 a5 a5 33 c0 40 a5 e8 [email protected] # 1b3a6fe dd 7f cc ff 8b 43 58 83-38 7c 72 06 53 e8 b5 41 .....CX.8|r.S..A # 1b3a70e ff ff 53 e8 ca 3e ff ff-a1 a8 15 93 81 a3 b4 02 ..S..>.......... kd> db 0x81b3a6de |
使用 0x01b3a6de 这个物理地址查看内容,和使用 0x81b3a6de 这个线性地址查看内容是完全一样的。
使用 windbg 的这种方式有助于理解 paging 过程