[原创]保护模式-分页管理机制
如何启用或者禁止分页管理机制
在windows下面可以通过修改系统启动配置文件来实现启用或者禁止分页机制.

在配置文件中加上/nopage的选项,就实现了不启用分页机制.

控制寄存器CR0

PG(Page): 0 : 禁用分页管理机制 1:启用分页管理机制
PE(Protect Mode): 0 : CPU运行实模式 1:CPU运行于保护模式.
分段机制和分页机制
分段机制:实现虚拟地址(由段和偏移构成的逻辑地址)到线性地址的转换
分页机制:分页管理机制实现线性地址到物理地址的转换
要点:80386中,页的大小固定为4K字节,每一页的边界地址必须是4K的倍数
页码
因为分页起始地址是模4K,所以分页的开始地址都是 “XXXXX000H”的形式, XXXXX
就是页码.
线性地址到物理地址的转换
80386把页映射表分为两级。
第一级页表:页目录表(Page Directory Table),缩写:PDT. 大小:4K ,每项4字节,包含二级页表所在物理地址空间页的页码.存在:物理内存中(不能是虚拟机内存,如果是虚拟内存中,那么就递归查找了,不符合逻辑,所以存在于物理地址中)
第二级页表:页表(Page Table Table),缩写:PTT,大小:4K ,每项4字节,包含对应物理空间页的页码.
页目录表=>页表=>物理内存页的对应关系图

页目录表表项(Page Directory Table Entry),缩写:PDE
页表表项(Page Table Entry),缩写:PTE
采用统一的页表格式

物理页码是我们所关心的.
线性地址到物理地址的转换规则
CR3寄存器高20位保存了PDT的物理页码

这样就可以定位到了PDT的起始物理地址了,还缺少页表的索引吧?,对!
?线性地址(windows下面虚拟地址等价于线性地址例如: ss:0x1012475,0x1012475就相当于是线性地址了),0x1012475转化为二进制0000000100 0000010010 010001110101,高10为就是PDT的索引,0000000100 <=> 4就是PDT中索引了,这样就可以定位到页表了.
PTT页表的下标在哪里呢?别急,线性地址的中间10位就是页表的索引,这样就可以定位到物理内存页的起始地址了,但是偏移存放在哪里呢?线性地址的低12位就是物理内存页的偏移。
示意图:

这样就完成了一个线性地址到物理地址的转化。
查看虚拟地址对应的PDE和PTE

效果:

进程的页目录如何定位?
我们知道CR3里面保存了当前进程页目录表的物理内存页的页号.但是我们如果想编码实现获取页目录的话,不可能整天背个windbg吧,其实微软提供一个KPROCESS的结构来记录每个进程都有一个单独的页目录,用来映射进程所有页表的位置。
KPROCESS.DirectoryTableBase[0];

进程切换时,操作系统通过CR3来通知硬件设备新进程页目录所在地址。

定位KPROCESS
KPROCESS被保存在进程环境块的结构中了


可以通过ObReferenceObjectByHandle获得进程对应的EPROCESS。

也可以通过PsGetCurrentProcess来获取当前线程的EPROCESS指针

windbg查看进程的页目录表

这里尝试一下手工定位计算器的入口地址所对应的物理地址

线性地址解01012475 0000000100 0000010010 010001110101
PDT索引4 PTT索引18 物理页面偏移0x475
首先通过!process获取计算器进程的页目录表

DirBase(Directory Base)就是页目录表所在物理页面的起始地址0x5e8d7000
!dd 0x5e8d7000查看PDT

!dd 0x18a07000查看PTT

!db 51b18475查看计算器进程的入口点的物理地址处内容

和OD里面显示的一致

修改物理内容的内容,看OD里面显示的虚拟地址处内容跟不跟着改变?

OD里面的第一个字节也变成了0x70,表明转化物理地址正确

文章中箭头不好弄,带箭头和着色更加完整的请参看附件.
分页管理机制.zip
