保护模式之页相关的笔记
如下指令:
MOV eax,dword ptr ds:[0x12345678]
其中,0x12345678 是有效地址
ds.Base + 0x12345678 是线性地址
CR3寄存器是所有寄存器里面,唯一一个存储物理地址的寄存器,其他都是线性地址。
每个进程都有一个CR3,(准确的说是都一个CR3的值,CR3本身是个寄存器,一个核,只有一套寄存器),CR3指向一个物理页,一共4096字节(4KB),如图:
31到22 | 21到12 | 11到0 |
---|---|---|
10 | 10 | 12 |
目录 | 目录 | 当前这个物理页的哪个位置 |
设置分页方式
boot里的noexecute 改成 execute
因为每个单元4字节,后3位是属性,倒着来看,比如12的原因,2的12次方是4K,所以12才能寻找所有的物理页,第二个10,每个PTE成员4字节,整个表4kB,所以有2的10次方个单元,所以有10位,第一个10位也是相同原因。
线性地址0 为什么不能访问呢?
没有指定物理页,指定物理页就一定能访问吗?
先看PDE与PTE的P位 P=1 才是有效的物理页
R/W = 0 只读
R/W = 1 可读可写
U/S = 0 特权用户
U/S = 1 普通用户
对PDE有意义,PS == PageSize的意思 当PS==1的时候 PDE直接指向物理页无PTE,低22位全是页内偏移。因为后面的偏移,线性地址只能拆成2段:大小为4MB,俗称“大页”
是否被访问(读或者写)过访问过置1,即使只访问一个字节也会导致PDE PTE置1
脏位,是否被写过,0没有被写过,1被写过
在上一节课课后题中我们提到过,如果系统要保证某个线性地址是有效的,那么必须为其填充正确的PDE与PTE,如果我们想填充PDE与PTE那么必须能够访问PDT与PTT,那么存在2个问题:
1、一定已经有“人”为我们访问PDT与PTT挂好了PDE与PTE,我们只有找到这个线性地址就可以了。
2、这个为我们挂好PDE与PTE的“人”是谁?
拆分C0300000
结论:C0300000存储的值就是PDT
如果我们要访问第N个PDE,那么有如下公式:
0xC0300000 + N*4
PDT总结:
1、通过0xC0300000找到的物理页就是页目录表
2、这个物理页即是页目录表本身也是页表
3、页目录表是一张特殊的页表,每一项PTE指向的不是普通的物理页,而是指向其他的页表.
4、如果我们要访问第N个PDE,那么有如下公式:
0xC0300000 + N*4
PTT总结:
1、页表被映射到了从0xC0000000到0xC03FFFFF的4M地址空间(一个页表是4KB,一共1024)
2、在这1024个表中有一张特殊的表:页目录表
3、页目录被映射到了0xC0300000开始处的4K地址空间
有了0xC0300000和0xC0000000能做什么?
掌握了这两个地址,就掌握了一个进程所有的物理内存读写权限。
公式总结:
1、什么是PDI与PTI
10-10-12
2、访问页目录表的公式:
0xC0300000 + PDI*4
3、访问页表的公式
0xC0000000 + PDI*4096 + PTI*4
10-10-12分页方式,在这种分页方式下物理地址最多可达4GB。但随着硬件发展,4GB的物理地址范围已经无法满足要求,Intel在1996年就已经意识到这个问题了,所以设计了新的分页方式.也就是我们本节课要讲的2-9-9-12分页,又称为PAE(物理地址扩展)分页.
将C:\boot.ini文件中的execute改为noexecute 重启
特别说明:
- 当PS=1时(第7位)是大页,35-21位是大页的物理地址,这样36位的物理地址的低21位为0,这就意味着页的大小为2MB,且都是2MB对齐。
- 当PS=0时,35-12位是页表基址,低12位补0,共36位。
特别说明
PDE/PTE结构
X | 保留 | 35-12 物理地址 | 低12位(属性) |
---|
段的属性有可读、可写和可执行
页的属性有可读、可写
当RET执行返回的时候,如果我修改堆栈里面的数据指向一个我提前准备好的数据(把数据当作代码来执行,漏洞都是依赖这点,比如SQL注入也是)
所以,Intel就做了硬件保护,做了一个不可执行位,XD=1时。那么你的软件溢出了也没有关系,即使你的EIP蹦到了危险的“数据区”,也是不可以执行的!
在PAE分页模式下,PDE与PTE的最高位为XD/NX位.
为了提高效率,只能做记录。
CPU内部做了一个表,来记录这些东西,这个表格是CPU内部的,和寄存器一样快,这个表格:TLB(Translation Lookaside Buffer)。
LA(线性地址) | PA(物理地址) | ATTR(属性) | LRU(统计) |
---|
说明:
1. ATTR(属性):属性是PDPE,PDE,PTE三个属性AND起来的. 如果是10-10-12,就是PDE and PTE
2. 不同的CPU 这个表的大小不一样.
3. 只要Cr3变了,TLB立马刷新,一核一套TLB.
操作系统的高2G映射基本不变,如果Cr3改了,TLB刷新 重建高2G以上很浪费。所以PDE和PTE中有个G标志位(PDE是大页时有效),如果G位为1刷新TLB时将不会刷新PDE/PTE的G位为1的页,当TLB满了,根据统计信息将不常用的地址废弃,最近最常用的保留.
TLB在X86体系的CPU里的实际应用最早是从Intel的486CPU开始的,在X86体系的CPU里边,一般都设有如下4组TLB:
第一组:缓存一般页表(4K字节页面)的指令页表缓存(Instruction-TLB);
第二组:缓存一般页表(4K字节页面)的数据页表缓存(Data-TLB);
第三组:缓存大尺寸页表(2M/4M字节页面)的指令页表缓存(Instruction-TLB);
第四组:缓存大尺寸页表(2M/4M字节页面)的数据页表缓存(Data-TLB)
(固定IDT第二个门)
(IDT表)中断号 | NMI | 说明 |
---|---|---|
0x2 | 不可屏蔽中断 | 80x86中固定为0x2 |
特别说明:
当非可屏蔽中断产生时,CPU在执行完当前指令后会里面进入中断处理程序
非可屏蔽中断不受EFLAG寄存器中IF位的影响,一旦发生,CPU必须处理
非可屏蔽中断处理程序位于IDT表中的2号位置
在硬件级,可屏蔽中断是由一块专门的芯片来管理的,通常称为中断控制器.它负责分配中断资源和管理各个中断源发出的中断请求.为了便于标识各个中断请求,中断管理器通常用IRQ(Interrupt Request)后面加上数字来表示不同的中断.
比如:在Windows中时钟中断的IRQ编号为0,也就是:IRQ0
中断的实质是改变程序执行流程
(IDT表)中断号 | IRQ | 说明 |
---|---|---|
0x30 | IRQ0 | 时钟中断 |
0x31-0x3F | IRQ1-IRQ15 | 其他硬件设备的中断 |
特别说明:
1. 如果自己的程序执行时不希望CPU去处理这些中断,可以
用CLI指令清空EFLAG寄存器中的IF位
用STI指令设置EFLAG寄存器中的IF位
2. 硬件中断与IDT表中的对应关系并非固定不变的,
参见:APIC(高级可编程中断控制器)
异常通常是CPU在执行指令时检测到的某些错误,比如除0、访问无效页面等。
无论是由硬件设备触发的中断请求还是由CPU产生的异常,处理程序都在IDT表。
错误类型 | (IDT表)中断号 |
---|---|
页错误 | 0xE |
段错误 | 0xD |
除0错误 | 0x0 |
双重 | 0x8 |
缺页异常的产生:
1、当PDE/PTE的P=0时
2、当PDE/PTE的属性为只读但程序试图写入的时
一旦发生缺页异常,CPU会执行IDT表中的0xE号中断处理程序,由操作系统来接管。
控制寄存器用于控制和确定CPU的操作模式。
Cr0 Cr1 Cr2 Cr3 Cr4
Cr1 保留
Cr3 页目录表基址
说明:
PE:CR0的位0是启用保护(Protection Enable)标志。
PE=1保护模式,PE=0实地址模式,这个标志仅开启段级保护,而并没有启用分页机制。若要启用分页机制,那么PE和PG标志都要置位。
PG:当设置该位时即开启了分页机制。在开启这个标志之前必须已经或者同时开启PE标志。
PG=0且PE=0,处理器工作在实地址模式下
PG=0且PE=1,处理器工作在没有开启分页机制的保护模式下
PG=1且PE=0,在PE没有开启的情况下,无法开启PG
PG=1且PE=1,处理器工作在开启了分页机制的保护模式下
WP:对于Intel 80486或以上的CPU,CR0的位16是写保护(Write Proctect)标志当设置该标志时,处理器会禁止超级用户程序(例如特权级0的程序)向用户级只读页
面执行写操作;
当CPL<3的时候:
如果 WP=0 可以读写任意用户级物理页,只要线性地址有效.
如果 WP=1 可以读取任意用户级物理页,但对于只读的物理页,则不能写.
当CPU访问某个无效页面时,会产生缺页异常,此时,CPU会将引起异常的线性地址存放在CR2中。
1) CPU缓存是位于CPU与物理内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。
2) CPU缓存可以做的很大,有几K、几十K、几百K甚至上M的也有。
CPU缓存与TLB的区别:
TLB:
线性地址 <—–> 物理地址
CPU缓存:
物理地址 <—–> 内容
PWT:Page Write Through
PWT = 1 时 写Cache的时候也要将数据写入内存中。
PCD:Page Cache Disable
PCD = 1时,禁止某个页写入缓存,直接写内存。
比如,做页表用的页,已经存储在TLB中了,可能不需要再缓存了。
[1]:滴水视频