WIndows内核学习笔记:分页机制——PAE分页模式
目录
- 前言
- Chapter 4 Paging
- 4.1 分页模式和控制位
- 4.1.1 四种分页模式
- 4.1.2 启用和切换分页模式
- 4.1.3 分页属性控制
- 4.1.4 Enumeration of Paging Features by CPUID
- 4.2 分层页表结构概览
- 4.4 PAE 分页模式
- 4.4.1 PDPTE寄存器
- 4.4.2 线性地址转物理地址
- 实验题:实现页表浏览工具
- 0. 查看源码
- 1. 环境设置
- 2. MFC浏览工具的代码实现
- 3. 驱动代码的实现
前言
物理地址扩展 Physical Address Extension(缩写PAE)。
解释:正常情况32位CPU可以存取4G的物理内存,但在现实中,实际情况是内存的发展速度大于CPU的发展速度,所以才有了让32位CPU存取超过4G内存的需求。实现方式就是给CPU增加了4根地址线,达到36根,于是可寻址64G大小的内存。
Intel到目前为止设计了4种分页模式,分别是:32位、PAE、4-level、5-level这四种模式。本文主要讲了Intel是如何设计PAE模式的页表相关数据结构。
- “Chapter 4 Paging”部分,是笔者在阅读Intel手册时做的翻译笔记,对应原文的 Volume3: Chapter 4 Paging。翻译有不准确的地方,以原文为准。可以在这里下载手册。Intel® 64 and IA-32 Architectures Software Developer Manuals
- “实验题”部分,实现了一个可以浏览进程页表的小工具,可以在这里查看源码。github源码
Chapter 4 Paging
4.1 分页模式和控制位
分页控制有关的寄存器
- CR0 标志位:WP(bit 16)、PG(bit 31)
- CR4 标志位:PSE(bit 4)、PAE(bit 5)、PGE(bit 7)、PCIDE(bit 17)、SMEP(bit 20)、SMAP(bit 21)、PKE(bit 22)、CET(bit 23)、PKS(bit 24)
- IA32_EFER MSR 标志位:LEM(bit 8)、NXE(bit 11)
- EFLAGS 标志位:AC(bit 18)
软件(应该指操作系统)如何启用分页功能:确保CR3中是分页结构表的物理内存地址,然后使用MOV指令置CR0.PG位。
4.1.1 四种分页模式
本节内容:根据 CR0.PG、CR4.PAE、CR4.LA57和IA32_EFER.LME,判断是否启用分页,以及是开启的什么分页模式。
CR0.PG = 0 表示未启用分页模式,此时会把线性地址直接当作物理地址使用。
CR0.PG = 1 表示启用分页模式。 Paging can be enabled only if protection is enabled (CR0.PE = 1)。此时由CR4.PAE、CR4.LA57、和IA32_EFER.LME决定启用哪种分页模式。
- 32-bit paging 模式 CR4.PAE = 0 (详见4.3节)
- PAE paging 模式 CR4.PAE = 1 and IA32_EFER.LME = 0 (详见4.4节)
- 4-level paging 模式 CR4.PAE = 1, IA32_EFER.LME = 1, and CR4.LA57 = 0 (4表示4层表寻找Pages页,详见4.5节)
- 5-level paging 模式 CR4.PAE = 1, IA32_EFER.LME = 1, and CR4.LA57 = 1 (5表示5层表寻找Pages页,详见4.5节)
32-bit 和PAG模式用于保护模式32位模式,IA32_EFER.LME = 0
4-level和5-level模式用于64位模式(IA-32e表示64位模式),IA32_EFER.LME = 1
四种模式的区别:
- 线性地址宽度
- 物理地址宽度
- 分页大小:4K、2M、4M、1G
- 支持execute-disable,数据执行保护
- 支持PCIDs,操作系统可以启用缓存线性地址的功能,不是很懂,先放放
- 支持 protection keys,不知道干嘛的
4-level 和 5-level模式还有两个子模式: - 兼容模式:兼容32位的模式
- 64位模式:虽然是64位线性地址,但是实际上4-level只使用了低48位做线性地址,而5-level页只使用低57位,物理地址线都只有52根。
4.1.2 启用和切换分页模式
本节内容:根据 CR0.PG、CR4.PAE、CR4.LA57和IA32_EFER.LME,如何启用并且切换不同的分页模式
讲解在不同模式之间切换的规则,这部分不感兴趣,略过。
4.1.3 分页属性控制
本节内容:通过CR0.WP、CR4.PSE、CR4.PGE、CR4.PCIDE、CR4.SMEP、CR4.SMAP、CR4.PKE、CR4.CET、CR4.PKS和IA32_EFER.NXE控制在不同分页模式下Pages的属性
CR0.WP
写入数据保护标志位:
等于0, supervisor-mode(应该指0环应用程序)可以向具有只读属性的页写数据;等于1,则不可以操作。
这个标志位对User-mode(应该时3环应用程序)没有影响,因为只要是只读属性的页,3环程序都不能写。
(4.6节有更详细的介绍)CR4.PSE
是否启用4M分页:
只对32-bit paging 模式作用,等于0,表示分页大小只能是4K;等于1,可以选择4K或4M分页。其它三种模式的分页大小可以自由选择,不受该位的控制。(4.3节有更详细的介绍)CR4.PGE
是否启用全局共享页:
等于0,不同进程间不会共享物理内存;等于1,进程间可以共享物理内存。(可能翻译的不对,帖上原文)
CR4.PGE enables global pages. If CR4.PGE = 0, no translations are shared across address spaces; if CR4.PGE = 1,
specified translations may be shared across address spaces.(4.10.2.4节有更详细的介绍)CR4.PCIDE
启用process-context identifiers,对4-level 和 5-level模式作用。
PCIDs逻辑处理器缓存多个线性地址。(4.10.1节有更详细的介绍)CR4.SMEP
If CR4.SMEP = 1, software operating in supervisor mode cannot fetch instructions from linear addresses that are accessible in user mode.(4.6节有更详细的介绍)CR4.SMAP
If CR4.SMAP = 1, software operating in supervisor mode cannot access data at linear addresses that are accessible in user mode. Software can override this protection by setting EFLAGS.AC.CR4.PKE and CR4.PKS
4-level和5-level模式将每一个线性地址与保护key相关联。
CR4.PKE=1时,PKRU寄存器表示,user-mode的线性地址所关联的保护key,是否可读或可写。
CR4.PKS=1时, the IA32_PKRS MSR does the same for supervisor-mode linear addresses.CR4.CET
这个好难理解。
If CR4.CET = 1, certain memory accesses are identified as shadow-stack accesses and certain linear addresses translate to
shadow-stack pages.IA32_EFER.NXE
执行保护,对4-level 和 5-level模式作用。如果设为1,则不能执行指令,但是可以读指令。
4.1.4 Enumeration of Paging Features by CPUID
这部分保护标志位的意义和用法。
PSE: page-size extensions for 32-bit paging.
PAE: physical-address extension.
PGE: global-page support.
PAT: page-attribute table.
PSE-36: page-size extensions with 40-bit physical-address extension.
PCID: process-context identifiers.
SMEP: supervisor-mode execution prevention.
SMAP: supervisor-mode access prevention.
PKU: protection keys for user-mode pages.
OSPKE: enabling of protection keys for user-mode pages.
CET: control-flow enforcement technology.
LA57: 57-bit linear addresses and 5-level paging.
PKS: protection keys for supervisor-mode pages.
NX: execute disable.
Page1GB: 1-GByte pages.
LM: IA-32e mode support.
CPUID.80000008H:EAX[7:0] reports the physical-address width supported by the processor.
CPUID.80000008H:EAX[15:8] reports the linear-address width supported by the processor.
4.2 分层页表结构概览
不同模式使用的页表结构是不一样的,有的只是用2张表,有的则更多。
每张表的大小都是4096字节,对于32-bit模式,每一项是4字节,共1024项;对于其它三种模式,每一项是8字节,每张表512项。PAE模式是个特例,它的第一张表只有4项。
不同模式对线性地址的处理是不一样的,详细章节会讲。
这里提出了两个名词:page frame 线性地址中用来寻址的部分;page offset 线性地址中用作偏移的部分。
每一项中的地址部分都是物理内存地址。
第一张表总是保存在CR3寄存器中。
四种模式解析线性地址(4K分页举例):
- 32-bit模式:32:22(10位)表1下标,21:12(10位)表2下标,11:0(12位)用作分页内的偏移量。
- PAE模式:31:30(2位)表1下标,29:21(9位)表2下标,20:12(9位)表3下标,11:0(12位)分页内的偏移量。
- 4-level模式:每张表都是512项,总共4张表,所以47:39、38:30、29:21、20:12对应4张表的下标,11:0(12位)分页内的偏移量。
- 5-level模式:使用5张表,56:48是第一张表下标,其余的根4-level模式的一样。
总结上面的解析线性地址过程,其实就是查表,查表,再查表。有些情况查表过程可能会中断,比如说遇到缺页异常时。
还有两种特殊的情况:
- 查表过程中,剩余没有解析的线性地址宽度超过12位,如果当前表项的属性位bit 7(PS位—page size)等于1,当前项就是最后的页
- 查表过程中,剩余没有解析的线性地址宽度等于12位,bit 7不再是PS位,另有它用,当前项则指向另一个表
对上述的第一种情况举例:
32-bit模式,如果分页大小是4M(CR4.PSE=1),那么表1就是存储的页,总共1024项,1024*4M=4G,正好寻址4G空间,表2就不存在了。再比如,PAE模式下,如果分页大小是2M,查到第2张表就时页了,此时没有了表3。
不同的表结构都有名字,参考下图:
对于上面的缩写,通常我们有下面的叫法:
PTE 页表,存放的每一项是最终的Pages物理地址,32位的分页大小有4K、2M、4M,64位则能扩展到1G大小
PDE 页目录表,存放的每一项是PTE
PDPTE页目录指针表,PAE模式只有4项,4-level和5-level模式都是填满的512项,每一项指向一个页目录表。
PML4E和PML5E暂时也不知道,实际上用法类似,各增加一层表的
4.4 PAE 分页模式
寄存器标志位:
CR0.PG = 1
CR4.PAE = 1
IA32_EFER.LME = 0
4.4.1 PDPTE寄存器
CR3指向 page-directory-pointer表。其中:
4:0 没有用
31:5 存放指向表的物理地址
63:52 没有用
page-dirctory-pointer表中由4个8字节的大小的PDPTEs组成,每个可寻址1-GByte大小的线性地址空间。
对应这4个PDPTE,逻辑处理器内部维护着与之对应的四个non-architectural寄存器,分别是PDPTE0、PDPTE1、PDPTE2、PDPTE3。出现下面几种情况时,逻辑处理器会重新加载内存中的PDPTEs到4个寄存器:
- 如果使用MOV to CR0或MOV to CR4指令修改了这些寄存器中的标志位(CR0.CD, CR0.NW, CR0.PG, CR4.PAE, CR4.PGE, CR4.PSE, or CR4.SMEP),PDPTESs会从CR3中执行的地址重新加载
- 在PAE分页模式,如果下执行MOV to CR3指令,PDPTESs会从CR3中执行的地址重新加载
- 在PAE分页模式,如果CR3中的值被task switch修改,会从新的CR3中加载PDPTEs
下表中说明了PDPTE的结构:
位 | 用途 |
---|---|
0(P) | Present,等于1表示此项指向一个页目录表,等于0则此项不包含页目录表 |
2:1 | 保留位,必须填0 |
3(PWT) | Page-level write-through,用来间接确定访问页目录表所需要的内存属性(详见4.9节) |
4(PCD) | Page-level cache disable,用来间接确定访问页目录表所需要的内存属性(详见4.9节) |
8:5 | 保留位,必须填0 |
11:9 | 忽略 |
(M-1):12 | 指向页目录表的4K对齐的物理地址 |
63:M | 保留位,必须填0 |
注:M表示MAXPHYADDR,最大物理地址宽度,该手册中是52根地址线。
4.4.2 线性地址转物理地址
PAE模式下,可以使用4K或2M分页。
如何确定是4K分页还是2M分页:
- 线性地址的31:30(2位)用来选择4个PDPTE寄存器中一个,称为PDPTEi,i等于这两位的值。每个PDPTEi可以对应1G大小的线性地址空间。如果PDPTEi的P位是0,那么这一项就是无效的,就是说该项不包含对应的页目录表,同时会产生一个page-fault异常(详见4.7节)。
- 如果PDPTEi的P位是1,那么其51:12(40位)指向了页目录表的物理地址。每个页目录表由512项8字节的PDEs组成。
意思就是线性地址的前两位用于确定页目录指针表(PDPTE)的下标,找到4个中的一个页目录表。
页目录表,每个页面录表含有512个表项,每个表项8字节大小,指向一个页表或者指向一个2M的页,这要根据下面介绍的PS标志位来确定。
- 如果PDE’s页目录表项的PS位等于1,说明这一项指向的就是一个最终的2M的分页,物理地址由该项的51:21(31位)和20:0(21位)确定。物理地址线最大52根,有的CPU是36根,那么高位就是35:21(15位),有的CPU有52根的,高位才是51:21。
- 如果PDE’s页目录表项的PS位等于0,说明这一项指向的是页表。页表的物理地址跟上面的情况一样也分为36根物理地址线和52根物理地址线。
如果是2M分页,那么线性地址后30位中,29:21(9位)用来作为表2(页目录表)的下标索引,来确定最终的页地址;20:0(21位)作为2M页内的偏移量。
如果是4K分页,那么线性地址后30位中,29:21(9位)作为表2(页目录表)的下标索引,20:12(9位)作为表3(页表)的下标索引,11:0(12位)作为4K页内的偏移量。
如果页目录表项(PDE)或者页表项(PTE)的P位(bit 0)等于0,或者置位它们的任意一位保留位,这个表项将会失效,并且会引起page-fault异常(详见4.7节)。
PAE模式中的保留位有下面几个:
- If the P flag (bit 0) of a PDE or a PTE is 1, bits 62:MAXPHYADDR are reserved.
- If the P flag and the PS flag (bit 7) of a PDE are both 1, bits 20:13 are reserved.
- If IA32_EFER.NXE = 0 and the P flag of a PDE or a PTE is 1, the XD flag (bit 63) is reserved
- If the PAT is not supported:
— If the P flag of a PTE is 1, bit 7 is reserved.
— If the P flag and the PS flag of a PDE are both 1, bit 12 is reserved.
下图是4K分页的线性地址转物理地址的过程示意图。
下图是2M分页的线性地址转物理地址的过程示意图。
下图是PDPTE、PDE-2M、PDE-4K、PTE各表项结构的示意图:
手册中给出了PDE-2M、PDE、PTE结构的详细解释,是下面三个表:
首先是PDE-2M表项结构解析:Table 4-9. Format of a PAE Page-Directory Entry that Maps a 2-MByte Page
位 | 用途 |
---|---|
0(P) | Present,必须等于1,表示该项指向一个2M分页 |
1(R/W) | Read/Write,如果为0,不允许向2M的分页写数据 |
2(U/S) | User/supervisor,权限标志位,等于0则3环程序不能访问2M的分页 |
3(PWT) | Page-level write-through,用来间接确定访问2M分页所需要的内存属性 |
4(PCD) | Page-level cache disable,用来间接确定访问2M分页所需要的内存属性 |
5(A) | Accessed,标志这个2M分页是否已经被访问过 |
6(D) | Dirty,标志这个2M分页是否已经被写入过数据 |
7(PS) | Page size,分页大小标志位,必须等于1(否则这项的意义变为指向4K分页的页表) |
8(G) | Gloabe,如果CR4.PGE等于1,该位用来确定这个页是否是全局共享的页 |
11:9 | Ignored |
12(PAT) | 如果支持PAT,则用来间接确定访问2M分页所需要的内存属性 |
20:13 | Reserved,保留位,必须是0 |
(M-1):21 | 2M分页的物理地址,36根物理线是35:21(15位),有的CPU有52根线的,是51:21 |
62:M | Reserved,保留位,必须是0 |
63(XD) | 如果 IA32_EFER.NXE标志位等于1,则该页中的数据不可执行(从该页中获取指令将被禁止); IA32_EFER.NXE等于0,该位位保留位,必须填0 |
PDE表项结构解析:Table 4-10. Format of a PAE Page-Directory Entry that References a Page Table
位 | 用途 |
---|---|
0(P) | Present,必须等于1,表示该项指向一个页表 |
1(R/W) | Read/Write,如果为0,不允许向其包含的1024个页(共2M)写数据 |
2(U/S) | User/supervisor,权限标志位,等于0则3环程序不能访问其包含的1024个页(共2M) |
3(PWT) | Page-level write-through,用来间接确定访问页表所需要的内存属性 |
4(PCD) | Page-level cache disable,用来间接确定访问页表所需要的内存属性 |
5(A) | Accessed,标志这个表项已经被访问了(被线性地址翻译器访问了) |
6(D) | Ignored |
7(PS) | Page size,分页大小标志位,必须等于0 |
11:8 | Ignored |
(M-1):12 | 页表的物理地址,36根物理线的CPU是25:12(24位),有的CPU有52根线的,是51:12(40位) |
62:M | Reserved,保留位,必须是0 |
63(XD) | 如果 IA32_EFER.NXE标志位等于1,则该项指向的页表中的所有页(1024个页)中的数据不可执行; IA32_EFER.NXE等于0,该位位保留位,必须填0 |
PTE表项结构解析:Table 4-11. Format of a PAE Page-Table Entry that Maps a 4-KByte Page
位 | 用途 |
---|---|
0(P) | Present,必须等于1,表示该项指向一个4K分页 |
1(R/W) | Read/Write,如果为0,不允许向4K的分页写数据 |
2(U/S) | User/supervisor,权限标志位,等于0则3环程序不能访问4K的分页 |
3(PWT) | Page-level write-through,用来间接确定访问4K分页所需要的内存属性 |
4(PCD) | Page-level cache disable,用来间接确定访问4K分页所需要的内存属性 |
5(A) | Accessed,标志这个4K分页是否已经被访问过 |
6(D) | Dirty,标志这个4K分页是否已经被写入过数据 |
7(PAT) | 如果支持PAT,则用来间接确定访问4K分页所需要的内存属性 |
8(G) | Gloabe,如果CR4.PGE等于1,该位用来确定这个页是否是全局共享的页 |
11:9 | Ignored |
(M-1):12 | 4K分页的物理地址,36根物理线的CPU是25:12(24位),有的CPU有52根线的,是51:12(40位) |
62:M | Reserved,保留位,必须是0 |
63(XD) | 如果 IA32_EFER.NXE标志位等于1,则该页中的数据不可执行(从该页中获取指令将被禁止); IA32_EFER.NXE等于0,该位位保留位,必须填0 |
实验题:实现页表浏览工具
0. 查看源码
github源码
1. 环境设置
测试操作系统:winxp sp3
开发环境配置:
VS2015 实现MFC对话框工程
WDK 7.1.0开发winxp驱动
如何启用PAE模式?
读者可以检索关键字“winxp pae”,会搜索到很多关于winxp系统启用PAE模式的教程。
2. MFC浏览工具的代码实现
工具的使用效果如下图:
第一栏,显示系统中的所有进程,通过调用CreateToolhelp32Snapshot 实现遍历进程。
第二栏,展示页目录指针表的表项(PDPTE),选中上级目录的某个进程后,MFC程序调用驱动程序接口,加载该进程的PDPTE,最后展示有效表项。
第三栏,展示页目录表的表项(PDE),选中上级目录的某个PDPTE表项后,与上述类似流程。
第四栏,展示页表项(PTE),流程与上述类似。
关于加载进程页表速度慢的问题:
对于PAE模式,进程的页表项数量总共有:4 PDPTE x 512 PDE x 512 PTE
在最初版本的工具设计中,使用3层循环来遍历页表项,一次性加载某个进程的所有页表。但是出现加载速度慢的问题。所以改进了加载方式,变成根据索引加载一个PDPTE表项下的512项PDE,或者加载一个PDE表项下的512个PTE,这样改进之后,加载速度明显改善。
代码:定义保存页表数据的结构体
namespace PAEPaging
{struct PDE_T{PDE val;PTE PTEs[512];BOOL LoadedFlag;};struct PDPTE_T{PDPTE val;PDE_T PDEs[512];BOOL LoadedFlag;};struct PDPTE_TT{ULONG cr3Val;PDPTE_T PDPTEs[4];};
}
代码:调用驱动接口,加载页表的实现
BOOL COperateKernel::LoadPages(DWORD dwPID, __in DWORD dwPDPTEIdx, __in DWORD dwPDEIdx, PAEPaging::PDPTE_TT* tt)
{...if (DeviceIoControl(hFile, IOCTL_GET_PAGES_PAE, inBuff, sizeof(inBuff), outBuff, sizeof(outBuff),&dwBytesRead, NULL)){DWORD dwOutBuffOffset = 0;// 加载 PDPTE 表if (dwPDPTEIdx == -1 && dwPDEIdx == -1){for (int i = 0; i < 4; i++){PAEPaging::PDPTE *pPDPTE = (PAEPaging::PDPTE*)((DWORD)outBuff + dwOutBuffOffset);tt->PDPTEs[i].val = *pPDPTE;dwOutBuffOffset += sizeof(PAEPaging::PDPTE);}}// 加载 PDE 表else if (dwPDPTEIdx != -1 && dwPDEIdx == -1){for (int i = 0; i < 512; i++){PAEPaging::PDE *pPDE = (PAEPaging::PDE*)((DWORD)outBuff + dwOutBuffOffset);tt->PDPTEs[dwPDPTEIdx].PDEs[i].val.uint64 = pPDE->uint64;dwOutBuffOffset += sizeof(PAEPaging::PDE);}}// 加载 PTE 表else if (dwPDPTEIdx != -1 && dwPDEIdx != -1){for (int i = 0; i < 512; i++){PAEPaging::PTE *pPTE = (PAEPaging::PTE*)((DWORD)outBuff + dwOutBuffOffset);tt->PDPTEs[dwPDPTEIdx].PDEs[dwPDEIdx].PTEs[i] = *pPTE;dwOutBuffOffset += sizeof(PAEPaging::PTE);}}bRet = TRUE;}...
}
3. 驱动代码的实现
NTSTATUS GetProcessPages(PVOID pInBuff, PVOID pOutBuff, ULONG nOutLength, ULONG* nBytes)
{...// 加载 PDPTE 表if (nPDPTEIdx == -1 && nPDEIdx == -1){for (int i = 0; i < 4; i++){ULONG64 paPDPTE = paCR3 + 8 * i;ULONG64 PDPTE = GetQuadByPA(paPDPTE);*(ULONG64*)((ULONG)pOutBuff + nWriteOffset) = PDPTE;nWriteOffset += sizeof(ULONG64);}}// 加载 PDE 表else if (nPDPTEIdx != -1 && nPDEIdx == -1){ULONG64 paPDPTE = paCR3 + 8 * nPDPTEIdx;ULONG64 PDPTE = GetQuadByPA(paPDPTE) & 0xFFFFFF000;for (int i = 0; i < 512; i++){ULONG64 paPDE = PDPTE + 8 * i;ULONG64 PDE = GetQuadByPA(paPDE);*(ULONG64*)((ULONG)pOutBuff + nWriteOffset) = PDE;nWriteOffset += sizeof(ULONG64);}}// 加载 PTE 表else if (nPDPTEIdx != -1 && nPDEIdx != -1){ULONG64 paPDPTE = paCR3 + 8 * nPDPTEIdx;ULONG64 PDPTE = GetQuadByPA(paPDPTE) & 0xFFFFFF000;ULONG64 paPDE = PDPTE + 8 * nPDEIdx;ULONG64 PDE = GetQuadByPA(paPDE) & 0xFFFFFF000;for (int i = 0; i < 512; i++){ULONG64 paPTE = PDE + 8 * i;ULONG64 PTE = GetQuadByPA(paPTE);*(ULONG64*)((ULONG)pOutBuff + nWriteOffset) = PTE;nWriteOffset += sizeof(ULONG64);}}...
}
WIndows内核学习笔记:分页机制——PAE分页模式相关推荐
- Windows x64内核学习笔记(二)—— IA-32e模式
Windows x64内核学习笔记(二)-- IA-32e模式 IA-32e模式 模式检测 强制平坦段 任务切换 中断门描述符 FS / GS 模式切换 32位程序进内核 64位程序进内核 实验:模式 ...
- Linux内核学习笔记 - RCU机制总结
目录 一.什么是RCU机制 1.历史背景 -- 原始的RCU思想 2.基础架构 -- RCU算法设计 3.实现思路-- 读写回收实现思路 4.实现思路 -- 实例说明 宽限期 订阅--发布机制 数据读 ...
- Windows x64内核学习笔记(四)—— 9-9-9-9-12分页
Windows x64内核学习笔记(四)-- 9-9-9-9-12分页 前言 9-9-9-9-12分页 实验一:线性地址转物理地址 页表基址 定位基址 PTE to PXE 实验二:通过页表基址定位各 ...
- 【OS学习笔记】三十三 保护模式九:分页机制对应的汇编代码之---用户程序代码
本片文章是以下两篇文章: [OS学习笔记]三十 保护模式九:段页式内存管理机制概述 [OS学习笔记]三十一 保护模式九:页目录.页表和页三者的关系详解 对应的用户程序汇编代码. ;代码清单16-2;文 ...
- Windows x64内核学习笔记(五)—— KPTI(未完待续)
Windows x64内核学习笔记(五)-- KPTI(未完待续) KPTI 实验一:构造IDT后门并读取Cr3 参考资料 KPTI 描述:KPTI(Kernel page-table isolati ...
- Windows x64内核学习笔记(三)—— SMEP SMAP
Windows x64内核学习笔记(三)-- SMEP & SMAP SMEP & SMAP 实验:构造IDT后门 第一步:编译以下代码 第二步:构造IDT后门 第三步:运行程序 第四 ...
- Windows x64内核学习笔记(一)—— 环境与配置
Windows x64内核学习笔记(一)-- 环境与配置 前言 新特性 基础要求 实验环境 Guest Win10配置 问题解决 参考资料 前言 之前,跟着海哥学习了windows内核的一些机制,包括 ...
- Windows异常学习笔记(二)—— 内核异常处理流程用户异常的分发
Windows异常学习笔记(二)-- 内核异常处理流程&用户异常分发 用户层与内核层异常 内核异常 分析 KiDispatchException 分析 RtlDispatchException ...
- 《寒江独钓》内核学习笔记
<寒江独钓>内核学习笔记(1)-- IRP - .Little Hann 时间 2013-11-30 15:40:00 博客园_.Little Hann原文 http://www.cn ...
最新文章
- 每秒改变一次背景颜色以及由此引发的一些有趣的小事情(.net方向)
- 遇到问题:push的时候出现fatal: Authentication failed for
- 从马克思哲学客观原理角度——反思大学生创业2017-12-15
- Codeforces 1065 E. Side Transmutations
- strcpy ,strncpy ,strlcpy地用法
- 优化基于ExtJS 4.1的应用
- 按顺序插入图片_MysqlInnodb特性之插入缓存
- JAVA :RESTLET开发实例(一)基于JAX-RS的REST服务
- Java使用swagger时显示实体类注解问题
- AI+大数据顶级技术盛会倒计时10天,6.6折票限时特惠!
- java关闭通道_调用map方法后,Java 7文件通道未正确关闭
- MATLAB中ones()函数的用法
- Codeforces 208A:Dubstep(字符串)
- Win7系统屏保也可以当桌面壁纸
- android emoji 开源库,Emoji开源库推荐_支持emoji表情的js的开源项目总汇
- 蛋白组+代谢组联合分析
- 针对OpenSSL吐嘈的吐嘈-如此唱反调
- Java 获取Word批注所标记的文本和图片
- VSCode入门(一)怎样新建项目
- 艾永亮:盘点产品创新的三种颠覆方式