写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

  看此教程之前,问几个问题,


🔒 华丽的分割线 🔒


练习及参考

1️⃣ 拆两个进程的4GB物理页。

2️⃣ 定义一个只读类型的变量,再另一个线性地址指向相同的物理页,通过修改PDE/PTE属性,实现可写。

3️⃣ 分析0x8043F00C线性地址的PDE属性。

4️⃣ 修改一个高2G线性地址的PDE/PTE属性,实现Ring3可读。

5️⃣在0线性地址挂上物理页并执行shellcode调用MessageBox

6️⃣ 逆向分析MmIsAddressValid函数。

PAE 分页

  PAE分页是啥,其实他就是2-9-9-12分页的英文缩写。为什么要有2-9-9-12分页,其实还是物理页不够用了,需要扩展。但想要足够的物理页,位数在那里,你想大也大不了。那么我就需要扩展物理页地址的位数,于是乎2-9-9-12分页诞生了,它整体分页的结构如下:

保护模式篇——PAE分页-LMLPHP

  与10-10-12分页不同的地方就是,多了一层名为页目录指针表的东西,英文缩写为PDPTT。每个PDEPTE被扩展为8个字节,物理地址描述的位数扩展为24位,故可以描述更多的物理页,但个数减半,变成了512个。下面详细查看它们的结构。
  首先看PDPTT的结构。由2-9-9-122可知第一部分由两位二进制组成,那么最多有4种结果。也就是为什么有五个成员,它的结构如下图所示:

保护模式篇——PAE分页-LMLPHP

  然后是PDE,既然学过了10-10-12分页,直接看下面的结构示意图吧:

保护模式篇——PAE分页-LMLPHP

非大页

保护模式篇——PAE分页-LMLPHP

大页

  然后是PTE,同理不多说了:

保护模式篇——PAE分页-LMLPHP

  我们之前做一道作业题目知道,我写的shellcode写到一个页上,它并没有执行权限,但它不是代码,仍然可以被我执行。为了弥补这个漏洞,Intel给我们补了一个硬件层面上的漏洞,它是一个位,处于PDEPTE的最高位,如下图所示:

保护模式篇——PAE分页-LMLPHP

  如果最高位是1,说明被保护。如果这个是数据,且这个X位被置为1,则会被报出异常不能执行。反之,和正常的10-10-12分页没什么两样。
  一个进程的线性地址仍是4GB的线性空间,有再多的物理页有啥用呢?在10-10-12分页下,假设进程一启动,就把所有的物理页都挂上,且没有任何交换。那么只能启动一个;如果在2-9-9-12分页下,同样的情况,它可以启动4个进程。这个就是2-9-9-12分页的意义。
  Windows也提供了基于硬件层面X位的保护,如下图所示:

保护模式篇——PAE分页-LMLPHP

  可以看出你自己写的普通程序压根和这个位无缘,但是还以启用的。但是有些打开之后发现提出不支持基于硬件的保护,那是因为虚拟机没开这个选项,如下图所示,转中如下图选项即可:

保护模式篇——PAE分页-LMLPHP

练习

  俗话说得好,光说不练假把式,如下是本节相关的练习。如果练习没做好,就不要看下一节教程了,越到后面,不做练习的话容易夹生了,开始还明白,后来就真的一点都不明白了。本节练习比较多,请保质保量的完成。

1️⃣ 定义一个只读类型的变量,再另一个线性地址指向相同的物理页,通过修改PDE/PTE属性,实现可写。
2️⃣ 自己实验有和没有DEP保护的程序,看看效果。(本题将在下一篇提供参考)
3️⃣ 修改一个高2G线性地址的PDE/PTE属性,实现Ring3可读。
4️⃣ 在0线性地址挂上物理页并执行shellcode调用MessageBox
5️⃣ 逆向分析MmIsAddressValid函数。

下一篇

  保护模式篇——TLB与CPU缓存

10-22 20:02