这两天看了下x86内存分页机制,调试之后大概弄懂了,发出来做个笔记。
0.测试代码
KdPrint(("VirtualAddress: %X\nPhysicalAddress: %X", &TestVar, PhyAddress)); // in DriverEntry
WINDBG输出如下
00000003 35.10139084 VirtualAddress: F889B000
00000004 35.10139084 PhysicalAddress: 338A000
1.物理内存定位
DirBase=CR3,保存着当前进程的页目录表基址
lkd> dd F889B000
f889b000 0001e240 f8891597 0776ea68 00000000
f889b010 00000000 00000000 00000000 00000000
f889b020 00000000 00000000 00000000 00000000
f889b030 00000000 00000000 00000000 00000000
f889b040 00000000 00000000 00000000 00000000
f889b050 00000000 00000000 00000000 00000000
f889b060 00000000 00000000 00000000 00000000
f889b070 00000000 00000000 00000000 00000000
lkd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****
PROCESS 823b77b8 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 027c0000 ObjectTable: e1001d68 HandleCount: 270.
Image: System
lkd> !dd (027C0000+4*3E2)
# 27c0f88 01019963 0101a963 0101b963 0101c963
# 27c0f98 0101d963 0101e963 0101f963 01020963
# 27c0fa8 01021963 01022963 01023963 01024963
# 27c0fb8 01025963 01026963 01027963 01028963
# 27c0fc8 01029963 0102a963 0102b963 0102c963
# 27c0fd8 0102d963 0102e963 0102f963 01030963
# 27c0fe8 01031963 01032963 01033963 01034963
# 27c0ff8 01035963 0003a163 0c060400 656c5252
lkd> !dd (01019000+4*9B)
# 101926c 0338a963 00000000 00000000 00000000
# 101927c 00000000 03e88963 03e89121 03e8a121
# 101928c 03e8b963 03e8c963 00000000 00000000
# 101929c 00000000 00000000 00000000 00000000
# 10192ac 00000000 00000000 00000000 00000000
# 10192bc 00000000 03e71963 03e32121 03e33121
# 10192cc 03df4963 00000000 00000000 00000000
# 10192dc 00000000 00000000 00000000 00000000
lkd> !dd (0338a000+000)
# 338a000 0001e240 f8891597 0776ea68 00000000
# 338a010 00000000 00000000 00000000 00000000
# 338a020 00000000 00000000 00000000 00000000
# 338a030 00000000 00000000 00000000 00000000
# 338a040 00000000 00000000 00000000 00000000
# 338a050 00000000 00000000 00000000 00000000
# 338a060 00000000 00000000 00000000 00000000
# 338a070 00000000 00000000 00000000 00000000
2.虚存映射定位
页目录被线性地映射到0xC0300000
页表被线性地映射到0xC0000000
非PAE分页模式.PDE,PTE的计算公式为:
PDE = ((VA >> 22) << 2 ) & 0xFFC + 0xC0300000;
PTE = ((VA >> 12) << 2 ) & 0x3FFFFC + 0xC0000000;
lkd> dd F889B000
f889b000 0001e240 f8891597 0776ea68 00000000
f889b010 00000000 00000000 00000000 00000000
f889b020 00000000 00000000 00000000 00000000
f889b030 00000000 00000000 00000000 00000000
f889b040 00000000 00000000 00000000 00000000
f889b050 00000000 00000000 00000000 00000000
f889b060 00000000 00000000 00000000 00000000
f889b070 00000000 00000000 00000000 00000000
lkd> dd (C0000000+3E2*400*4+9B*4)
c03e226c 0338a963 00000000 00000000 00000000
c03e227c 00000000 03e88963 03e89121 03e8a121
c03e228c 03e8b963 03e8c963 00000000 00000000
c03e229c 00000000 00000000 00000000 00000000
c03e22ac 00000000 00000000 00000000 00000000
c03e22bc 00000000 03e71963 03e32121 03e33121
c03e22cc 03df4963 00000000 00000000 00000000
c03e22dc 00000000 00000000 00000000 00000000
lkd> !dd 0338a000
# 338a000 0001e240 f8891597 0776ea68 00000000
# 338a010 00000000 00000000 00000000 00000000
# 338a020 00000000 00000000 00000000 00000000
# 338a030 00000000 00000000 00000000 00000000
# 338a040 00000000 00000000 00000000 00000000
# 338a050 00000000 00000000 00000000 00000000
# 338a060 00000000 00000000 00000000 00000000
# 338a070 00000000 00000000 00000000 00000000