要点回顾
前文中已经讲解了10-10-12分页形式,在这种分页方式下,物理地址最多可以达到4GB。
但是随着硬件发展,4GB的物理地址范围已经无法满足要求,Intel在1996年就已经意识到这个问题了,所以设计了全新的分页方式。
也就是接下来将要讲解的2-9-9-12分页形式,又称为PAE(物理地址扩展)分页。
为什么是10-10-12
- 先确定了页的大小 4KB,所以后面的12位的功能就确定了。
- 当初的物理内存比较小,所以4个字节的PTE就够了,加上页的尺寸是4KB,所以一个页能储存1024个 PTE,也就是2的10次方,第二个10也就确定了。
- 剩下的10位PDI 10+10+12刚好32位。
为什么是2-9-9-12
- 页的大小是确定的,4KB不能随便更改,所以12确定了。
- 如果想要增大物理内存的访问范围,就需要增大PTE,增大了多少呢?考虑对齐的因素,增加到8个字节。
- PTE的结构由32位变为64位,物理地址部分变长了,它能查找到的物理地址范围也变大了。
- 不管是10-10-12还是2-9-9-12,它的页大小都是4KB。PTT这张表仍然是4KB,原来4个字节一个成员,就可以存储1024个成员。现在一个成员变成了8个字节,页的大小没有变,仍然是4KB,所以能存储的成员数量就少了,变成了512个,2的9次方就能找到这512个成员中任意一个。
- PDE也由原来的4个字节变成了8个字节,PDT表也由1024个成员变成了512个成员,也就是9个位就能索引到了。
- 12+9+9=30,刚好是30个位,那么剩下2位怎么办呢?这剩下的2位就是扩展出来的。
2-9-9-12分页结构(PAE:物理地址扩展)
- 以往在10-10-12分页形式下CR3中存储的是物理地址,这个物理地址直接指向PDT。现在不是了。
- 现在CR3不指向PDT,它指向另外一个表。这个表只有4个成员。为什么是4个成员呢?原因很简单,因为只剩下2位了。2位有几种情况?00、01、10、11,也就是说二进制位只剩下2位,2位能查找到的成员最多能查到4个。
- 所以,第一张表有了一个新的名字:PDPT,页目录指针表。它里面的成员叫做:PDPTE,根据其名字也能猜测出来其中储存的是指针,每个指针指向的都是PDT表。
- 10-10-12分页与2-9-9-12分页是有很大差异的,差异从CR3就开始了。
如何开启PAE(物理地址扩展)模式
将C:\boot.ini文件中的execute修改为noexecute,并重启。重启以后,计算机的分页模式就会变成2-9-9-12分页形式。
Page-Directory-Point-Table Entry
- PDPTE共有四项(第一个2)。
- 35-12储存的是页目录表的基址,低12位补0,共36位,即页目录基址。
PDE结构(2-9-9-12分页)
与之前差不多,只不过由4字节变为了8字节。
- 当PS=1时是大页,35-21位是大页的物理地址。这样,36位的物理地址的低21位为0,这就意味着页的大小为2MB,且都是2MB对齐。
- 当PS=1时,多了一个PAT位(页属性表),也就是下标为12的位。该位与CPU相关,但不是所有CPU都支持该位,如果不支持,该位会填0。
- 当PS=0时,35-12位是页表基址,低12位补0,共36位。
- Avail是给操作系统使用的。
PTE结构
- PTE中,35-12位是物理页基址,24位。低12位补0。
- 物理页基址+12位的页内偏移指向具体数据。
XD标志位(AMD中称为NX,即No Excetion)-仅存在于2-9-9-12分页中
XD标志位仅存在于2-9-9-12分页中,处于PDE/PTE结构的最高位。
将这个位置1了以后,即使被恶意的将EIP指向数据区也无法执行。
段的属性有可读、可写和可执行。
页的属性有可读、可写。
当RET执行返回的时候,如果我修改堆栈里面的数据指向一个我提前准备好的数据(把数据当作代码来执行,漏洞都是依赖这一点,比如SQL注入)
所以,Intel就做了硬件保护,做了一个不可执行位。XD=1时,那么你的软件溢出了也没有关系,即使你的EIP蹦到了危险的"数据区",也是不可执行的。