PAE分页下的PDT-PTT基址

2018-3-27 流沙 保护模式学习总结

PDE 和 PTE 地址计算公式

为了先入为主,这里直接给出访问一个线性地址的 PDE 和 PTT 的计算公式。PAE分页,把线性地址分成了四段,即PDPTI-PDI-PTI-OFFSET. 如果要找出这个线性地址对应的 PDE 和 PTE 的位置,可以使用下面的计算公式。

  • 公式一不过,我们可以采用更简洁的方式来计算PDE和PTE的位置,这种方式不需要事先计算 PDPTI、PDI 和 PTI。
  • 公式二
// addr 存放的是线性地址 pPDE = (int*)(0xc0600000 + ((addr >> 18) & 0x3ff8));
pPTE = (int*)(0xc0000000 + ((addr >> 9) & 0x7ffff8));  
  • 1
  • 2
  • 3

知道了 PDE 和 PTE,我们自然就可以随心所欲的修改物理页属性,从而获得一些权限来访问用户模式下不可访问的地址,甚至可以自己挂载物理页了。

分析实例

这里,采用地址 0x50401020为例,分别用前面两种不同的公式进行计算该线性地址的 PDE 和 PTE 的线性地址。

  • 使用公式一

0x50401020 拆分成四段式是 ‭01-01 0000 010-0 0000 0001-‬020,即1-82-1-020

故有 PDPTI = 0x1, PDI= 0x82, PTI = 0x1, OFFSET = 0x020. (注意这些数字都是16进制)。

根据公式一可以得到:

pPDE = 0xc0600000 + (PDPTI<<12) + (PDI<<3) = 0xc0600000+0x1000+0x410 = c0601410 pPTE = 0xc0000000 + (PDPTI<<21) + (PDI<<12) + (PTI<<3) = 0xc0000000+0x200000+0x82000+0x8 = 0xc0282008

  • 1
  • 2
  • 使用公式二

pPDE = c0600000 + ((addr >> 18) & 0x3ff8) = c0600000 + ((0x50401020>>18) & 0x3ff8) = 0xc0601410

pPTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8) = 0xc0000000 + ((0x50401020>> 9) & 0x7ffff8) = 0xc0282008



  • 2

可以发现,使用公式二比使用公式一计算量要小很多。在实际使用中,也会经常使用公式二。

总结

本篇结束后,你可能要提一个小小的疑问,为什么使用 0xc0600000 和 0xc0000000 这样的基址。这一点,其实是和操作系统有关的。这个地址,实际是通过分析 Windows Xp 内核的一个名为 MmIsAddressValid 的内核函数得到的。如果你的汇编掌握熟练的话,可以自己在 WinDbg 中使用下面的命令查看它的反汇编代码,并作分析。记住这并不作要求,你需要的仅仅是记住上面的计算公式。

kd> u MmIsAddressValid L50

发表评论:

Powered by 流沙团

备案号:鄂ICP备15017378号-1