前面的课程中,我们学习了P位和R/W位,P决定物理页是否有效,RW决定了物理页的读写权限。 本节,将依次介绍U/S、PS、A、D位的含义。
U/S=0 表示特权用户可访问; U/S=1 表示普通用户可访问。
回想一下之前学习段的时候,我们可以通过调用门,中断门,任务门等方式将CPL提升到0,从而可以读写高2G内存。学习了U/S位后,我们可以不提权也能访问高2G,只需要将想访问的物理页对应的PDE PTE的U/S位改写为1即可。
下面是一个小实验:
// PDE_PTE_US.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> int _tmain(int argc, _TCHAR* argv[]) { PDWORD p = (PDWORD)0x8003f00c; DWORD addr = (DWORD)p; printf("线性地址:0xx, 4*0x%x 4*0x%x 0x%x\n", addr, addr>>22,(addr>>12)&0x000002FF,addr&0x00000FFF); getchar(); printf("读高2G内存地址:%x\n", *p); return 0; }我在程序中已经把线性地址拆分好了,接下来只需要找到PDE PTE,将U/S改成1即可。
修改U/S位:
继续执行程序:
总结:
1、2G以上是内核才能访问的原因是U/S位的设置问题,如果将内核的某个页 设置为1 就可以在R3访问了
2、0 1 2是系统环 可以访问系统页和用户页 0环是特权级环 1、2环虽然不 是特权级环 但是是系统环 3环是用户环 可以访问用户页
PS是PDE的第8位,PS是PAGE SIZE 的意思。我们之前遇到的PDE PS位大部分都是0;当PS=1,则PDE直接指向物理页,以 0x8043f00c 为例,分析PS=1的情况。
拆分 8043f00c 10 0000 0001 0x201 00 0011 1111 0x3f 00000000 1100 0xc
随便找一个进程的CR3,notepad.exe CR3=0ddb5000
查得PDE=004001e3
看看 8043f00c 的拆分结果,前10位是PDT的下标,通过它找到了PDE,后22位是物理页偏移。 10 0000 0001 0x201 00 0011 1111 0x3f 0000 0000 1100 0xc
PDE指向大小为4MB的物理页,即物理页地址是 0x00400000,页内偏移22位来自 0x8043f00c 的低22位,即 00 0011 1111 0000 0000 1100 ,十六进制是 0x3f00c
所以 0x8043f00c 物理地址是 0x0043f00c,验证如下:
是否被访问(读或者写)过 ,访问过置1,即使只访问一个字节也会导致PDE PTE置1。
脏位 是否被写过 0没有被写过 1被写过
学完控制寄存器域TLB才能讲,此处略过。
有效位在发生缺页时(PTE的P=0)使用。关于这部分知识,等以后学习了内存管理的缺页异常就知道了,这里简单介绍一下。