16 PDE PTE

80x86映射表分二级:
第一级为页目录表:PDT
第二级为页表:PTT
如下图:
在这里插入图片描述
CR3存储了一个物理地址,这个物理地址指向了一个页,这个页的大小时4096个字节,这里面每个成员有四个字节,能存放1024个成员,这个物理页就是我们的PDT(页目录表),里面的成员称为页目录表项(PDE),页目录表项又指向一个PTT(页表),这个页表里每个元素叫做PTE(页表表项),PTE指向的是真正的物理页。PDE PTE是四个字节,其中低12位是属性。PTE可以指向物理页,页可以没有物理页,多个PTE可以指向同一个物理页,一个PTE只能指向一个物理页。
接下来我们来看一下平常我们C编程中经常说的不能读写0地址是怎么回事,我们用如下代码来测试,然后用windbg查看0地址对应的物理地址

#include <stdio.h>

int main()
{
	int x = 1;
	printf("x的地址:%x\n", &x);
	getchar();
	return 0;
}

运行程序后在windbg中执行!process 0 0,找到我们的00.exe
在这里插入图片描述
然后查看从PDT中查看0地址对应的PDE
在这里插入图片描述
再从PTT中查看0地址对应的PTE
在这里插入图片描述
从这里我们可以看到这里并没有挂物理页,这时我们清楚了0地址之所以不能读写,其原因就是没有挂物理页。那挂上物理页是不是就可以读写了,接下来我们在上面的代码中加两行代码做实验,代码如下:

#include <stdio.h>

int main()
{
	int x = 1;
	printf("x的地址:%x\n", &x);
	getchar();
	//向0地址写如数据
	*(int*)0 = x;
	//读0地址
	printf("0地址数据为:%d\n", *(int*)0);
	return 0;
}

我们先不挂物理页直接运行程序并回车执行会报如下错误:
在这里插入图片描述
查看反汇编发现其报错原因如下:
在这里插入图片描述
那么下面我们准备将x变量所在物理地页挂到0上

首先,我们运行程序打印出x变量的地址:
在这里插入图片描述
接下来我们将x地址按10-10-12拆分如下:
0000 0000 00
01 0010 1111
f7c
我们用!process 0 0找到我们运行的.exe的dirbase

查看x的在PDT中对应的PDE,这里x变量的地址高10位为0,和0地址一样,所以我们这里不用修改:
在这里插入图片描述
查看x变量在PTT表中对应的PTE,中间10位值为12f,乘以4位4bc,3558067去掉属性位再+4bc
在这里插入图片描述
将该物理页挂到0上
在这里插入图片描述
查看是否成功挂上
在这里插入图片描述
g命令运行虚拟机,再控制台输入回车,这时我们即可看到0地址被写入和读出了。
在这里插入图片描述
至此,成功写入读出0地址。

猜你喜欢

转载自blog.csdn.net/lifeshave/article/details/86654713
今日推荐