(10) [保护模式] 2-9-9-12分页

  • Post author:
  • Post category:其他


海哥说过:做出来的东西才懂,没做出来就是没懂



认识2-9-9-12分页

首先要思考,为什么会有2-9-9-12分页?

2-9-9-12分页到底拓展了什么?

计算:2+9+9+12 = 32

依旧是32位,所以我们能表示的虚拟地址的极限依旧是:2

32

= 4GB (0x0000 0000 – 0xFFFF FFFF)

假设我有一张8GB的内存条(物理地址能取到8G(0x1 FFFF FFFF))

如何将 进程地址 映射到 物理地址 0x1 0000 0001 上

如何和10-10-12那样,PTE(页表项,视频里称作PTI)是32位的,那么最大的寻址就是

PTE & 0xFFFF F000 + offset。所以想要突破这个点,那么就必须让PTE的长度突破32位。

所以只要

0x1 0000 0

000 + 1 就能实现

实际上,操作系统允许我们使用到36位,这样一来,就能映射到64G的物理地址上了

所以2-9-9-12分页拓展了

物理地址的寻址范围

那么问题来了,如果PT(页表)在地址 0x1 0000 0001 怎么办,原来的32位PDE可就找不到PT了。所以PDE也变成36位好了。


那为什么不把PD 和 PT都放在0-4GB里?我也不知道

在这里插入图片描述

通过之前学的,最后指针指向那个物理页还得是PTE说了算。所以PTE怎么指都行

PDPT (page directory pointer table) : 页目录指针表

PDPTE (page directory pointer talble entry) : 页目录指针表中的 一项 (条目)



给0地址挂物理页

还是用上次的代码

#include <stdio.h>

int main(){
	int i = 0;
	printf("%p\n", &i); // %p打印 十六进制 指针

	*(int*)0 = 0x123;
	printf("%d", *(int*)0);

	return 0;
}

在修改之前断下来

在这里插入图片描述

我们把

i

的物理页挂到0的线性地址上

稍微拆分一下:0 | 0 | 12F | F7C

在这里插入图片描述

左边是

i

,右边是

0


没有

!eq

,只能写成

!ed

,记得最后面的两个的DWORD要交换一下位置

在这里插入图片描述

(忘了是%d了) 291 = 0x123




修改高2G页属性

简单的代码

#include <stdio.h>

int main(){
	printf("%x", *(int*)0x8003f00c);
	return 0;
}

简单地拆分一下:2 | 0 | 3F | C

我们将

U/S置1



G位置0


G为什么要置0,后面再解释,如果没懂,那么先记住,看下一集视频后会通透的

在这里插入图片描述

修改后运行程序打印结果

在这里插入图片描述

说一下上一次没讲到的G位:全局页 位 (这将在下一个视频有讲解)

试想一下,程序每读一个地址,就要拆分一次PDPTE,PDE,PTE效率十分低下,有些地址是同一个页内的,根本没有必要每次都进行检测,所以有一块离CPU很近,速度很快的地方,存放了拆分过的页,以及页的各种属性,这么一来就不用一直拆分了。我们暂且把这个地方称为

快表

快表中的页属性:当G == 1时,快表中的项(entry)不会被换出,当 G == 0 时代表快表项会被换出

请注意:当我们修改了PDE,PTE时,若物理页是全局页,则那个快表中的那个页属性并没有改变,所以我们的修改无效,必须让快表中的那一项重新加载,才能读取修改后的属性。



代码挂物理页

PDE = 0xc0600000 + ((addr >> 18) & 0x3ff8);
PTE = 0xc0000000 + ((addr >> 9) & 0x7ffff8);


对应关系图:


在这里插入图片描述

代码:

#include <windows.h>
#include <stdio.h>

PDWORD pde, pte, pde0, pte0;

void __declspec(naked) func(){ 
	_asm{
		pushad
		pushf
		
		//if (*pde != 0)  *pde0 = *pde;
		mov eax, pde
		mov eax, [eax] //eax = *pde
		cmp eax, 0
		jnz editPte0 //如果PDE存在,不要去动他
		mov ebx, pde0 
		mov[ebx], eax //复制给0xC030 0000 ( (void*)0的PDE )
	editPte0:
		//*pte0 = *pte;
		mov eax, pte
		mov eax, [eax]
		mov ebx, pte0
		mov[ebx], eax

		popf
		popad
		retf 
	}
}

int x = 0x12345678;//主要是想让 变量x的PDE != 0,如果是0那将少踩很多坑

int main(){
	BYTE addrs[6] = {0x00, 0x00, 0x00, 0x00, 0x48, 0x00 };
	int selector = 0x0008;

	DWORD xaddr = (DWORD)&x; //方便下面的计算
	printf("x addr: %X\n", &x);
	// PDI (page directory index) ; PTI (page table index) (就是拆分后的那10个二进制位)
	// pde = (xaddr >> 22) * 4  + 0xC0300000 = PTI * 4 + 0xC0600000
	pde = (DWORD*)(((xaddr >> 18) & 0x3FF8)+ 0xC0600000); //x的pde
	// pte = (xaddr >> 12) * 4  + 0xC0000000 = PDI * 4MB + PTI * 4 + 0xC0000000
	pte = (DWORD*)(((xaddr >> 9) & 0x7FFFF8) + 0xC0000000);//x的pte
	pde0 = (DWORD*)0xC0600000; //0的pde
	pte0 = (DWORD*)0xC0000000; //0的pte

	printf("windbg input:\t eq 8003f048  %04xEC00`%04x%04x\n", 
	  (((DWORD)&func)>>16), selector, (DWORD)&func & 0xFFFF);
	
	_asm{
		push fs
		call fword ptr[addrs]
		pop fs
	}
	
	*((int*)0) = 0x11112222;
	printf("%x\n", *((int*)0)); //打印 指针0 的值
	printf("%x\n", *((int*)(0 + ( ((DWORD)&x) & 0xFFF) )));//print x
	return 0;
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

结果:

在这里插入图片描述



版权声明:本文为qq_50332504原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。