上一篇,我们分析了PDT的基址是 0xc0300000。这个地址拆分成三段式就是300-300-000
. 用大白话说就是页目录表的第0x300号PDE指向的页表PTT768中的第0x300号PTE指向的物理页。
图1 PTT768
C0300000分析
0xc0300000
拆成三段式300-300-000
。所以我们可以在 WinDbg 中查找页目录表的第 0x300 号PDE指向的物理页到底是谁。这里随便选一个进程的的页目录基址来做实验。
图2 惊奇的发现0x300号索引指向的PTT还是页目录基址,也PDT
如果再接着分析下去,就是把这个页目录当成PTT来分析,这是第二重身份了。该PTT的第 0x300 号PTE 的值,依然是 0x18caa063
。
结论就是,0xc0300000
就是页目录表的基址。只要知道了这个地址,以后访问页目录表的内容还不是轻而易举。
C0000000 分析
0xc0000000
拆成三段式300-000-000
。我们已经知道一级索引指向的还是页目录。重点看二级索引,索引号是 0,它指向的普通物理页是谁。
图2 二级索引指向的是“普通物理页”
我们知道的一个事实是,二级索查的是 PTT 表,然而我们查的这个 PTT 表却又是 PDT 表。所以,最终的这个普通物理页其实并不普通,它可是一张 PTT。如果你觉得有点混乱,请仔细看图1中的PTT0.
总结
知道了PDT和PTT的基址,那么PDE和PTE的基址就很容易得到,只要加上偏移就行了。
如果一个线性地址被拆分成三段式PDI-PTI-OFFSET
,则有:
- PDE 的基址
// 第 PDI 个 PDE 的基址
PDT[PDI] = 0xc0300000 + PDI * 4
- PTE 的基址
// 第 PDI 个 PDE 指向的 PTT 中的第 PTI 个 PTE 的基址
PTE[PTI] = 0xc0000000 + PDI * 4096 + PTI*4