Windows保护模式学习笔记(七)—— PDE&PTE

Cr3

描述:

在所有的寄存器中,只有Cr3存储的是物理地址,其它寄存器存的都是线性地址
Cr3所存储的物理地址指向了一个页目录表(PDT)
在Windows中,一个页的大小通常为4KB,即一个页可以存储1024个页目录表项(PDE)

物理页结构图:
物理页结构图

PDE(页目录表项)

描述:

页目录表(PDT)的每一项元素称为页目录表项(PDE)
每个页目录表项指向一个页表(PTT)
每个页表的大小为4KB,即一个页表可以存储1024个页表项(PTE)

PTE(页表项)

描述:

页表(PTT)的每一个元素称为页表项(PTE)
页表项(PTE)所指向的才是真正的物理页

特征:

  1. PTE可以指向一个物理页,也可以不指向物理页
  2. 多个PTE可以指向同一个物理页
  3. 一个PTE只能指向一个物理页

物理页的属性

物理页的属性=PDE属性& PTE属性
PDE属性
PTE属性
P位:是否有效位
注意:当PDE或PTE中有一个的属性P=0时,物理页就是无效的

R/W位:读写位
R/W=0:只读
R/W=1:可读可写

U/S位:权限位
U/S=0:特权用户
U/S=1:普通用户

PS位PDE特有
PS == PageSize
PS=1:PDE直接指向物理页,低22位=页内偏移,偏移最大值为4MB,俗称"大页"
PS=0:PDE指向PTE

A位:访问位
A=1:该PDE/PTE被访问过
A=0:该PDE/PTE未被访问过

D位:脏位
D=1:该PDE/PTE被写过
D=0:该PDE/PTE未被写过

注:其他位等学完控制寄存器与TLB才能讲,本篇不讲

10-10-12分页的补充

为什么要按10-10-12分页:

  1. 一个物理页的大小为4096字节,即2的12次方,若要遍历整个物理页,则需要12个比特位
  2. 一个页表有1024个页表项,1024等于2的十次方,即需要10个比特位
  3. 页目录表项同理,也需要10个比特位

注:以下实验的分页方式都为10-10-12分页

实验1:证明PTE的特征1

第一步:选择一个进程的Cr3

我这里启动了一个记事本:notepad.exe
记事本Cr3

第二步:查看页表

查看当线性地址为0时,进程的页表
线性地址0的页表
可以发现有许多页表项都为0,没有指向任何物理页

实验2:通过修改页表使C语言能在0地址处读写

第一步:得到一个变量的地址

运行代码如下:

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

int main(int argc, char *argv[])
{
	int x = 1;

	printf("x的地址:%x\n", &x);

	getchar();

	// 向0地址写入数据
	*(int*)0 = 123;
	// 从0地址读出数据
	printf("0地址的数据:", *(int*)0);

	getchar();
	return 0;
}

程序运行后,首先会输出x的地址
x的地址

第二步:挂载PTE为0的物理页

使用WinDbg将虚拟机中断,将变量x所在的物理页挂载到线性地址0的PTE
挂载物理页

第三步:继续运行程序

运行结果:
运行结果
成功对0地址进行了读写,实验成功!

实验3:通过修改物理页属性使字符串常量可修改

第一步:运行程序

代码如下:

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

int main(int argc, char *argv[])
{
	char *str = "Hello World";

	printf("线性地址:%x", str);

	getchar();						// 让程序执行到这里

	//修改只读变量
	str[0] = 'M';

	printf("修改后的值:%s\n",str);

	return 0;
}

这时候得到了str的地址:
str的地址

第二步:修改对应PTE的属性

修改PTE属性

第三步:继续运行程序

运行结果:
运行结果
修改成功!

实验4:通过修改物理页属性使普通用户读取高2G内存

第一步:运行如下代码

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

int main(int argc, char *argv[])
{
	PDWORD p = (PDWORD)0x8003F00C;

	getchar();			// 让程序运行到这里

	printf("读取高2G内存:%x \n", *p);

	return 0;
}

第二步:修改PDE与PTE的U/S位

修改U/S位

第三步:继续运行程序

运行结果如下:
运行结果
成功读取了高2G的内存!

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
数值分析是一门研究数值计算方法及其应用的学科。Matlab作为一个强大的数值计算工具,可以帮助我们更好地学习和理解数值分析。下面是一些Matlab数值分析学习笔记,供您参考: 1. 数值计算基础 - Matlab的数值计算基础包括基本的数学函数、变量定义、矩阵运算等。 - 常用的数学函数包括sin、cos、exp、log等。 - 变量定义和赋值可以使用等号“=”,例如a=2。 - 矩阵运算可以使用“*”表示矩阵乘法,使用“\”表示矩阵求解线性方程组。 2. 数值解法 - 数值解法包括数值积分、数值微分、插值法、最小二乘法等。 - Matlab中的数值积分函数包括quad、quadl、quadgk等。 - Matlab中的数值微分函数包括diff、gradient、jacobian等。 - 插值法可以使用interp1函数实现。 - 最小二乘法可以使用polyfit函数实现。 3. 常微分方程(ODE) - 常微分方程是数值分析中的重要内容之一,Matlab提供了ode45、ode23等函数实现常微分方程的数值解法。 - ode45函数是最常用的常微分方程数值解法之一,可以处理刚性和非刚性方程。 4. 偏微分方程(PDE) - 偏微分方程是数值分析中的另一个重要内容,Matlab提供了pdepe、pde23等函数实现偏微分方程的数值解法。 - pdepe函数可以处理二阶线性偏微分方程,pde23函数可以处理一般的偏微分方程。 5. 数值优化 - 数值优化是数值分析中的一个重要分支,Matlab提供了fminsearch、fmincon等函数实现数值优化。 - fminsearch函数可以用于无约束优化问题,fmincon函数可以用于有约束优化问题。 以上是一些Matlab数值分析学习笔记,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值