流沙团
PAE分页下的PDT-PTT基址
2018-3-27 流沙团


PDE 和 PTE 地址计算公式



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




// 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
发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容