在白皮书的第三卷2.5章对控制寄存器有详细的介绍,下面是白皮书中CR寄存器的结构图(这里要说明一下cr4的第12位是由被使用的这个位在2.5章的后半部分有介绍是控制是否开启5级分页的位否则是四级分页)
首先是smep和smap两个位,这部分因为之前的实验会用到所以已经在段机制的部分介绍过了,这里就不再赘述
其余一些位置的功能后面用到了会继续介绍,这边有个结构的概念就可以了
下面我们来梳理一下64位cpu中分页机制的变化过程:
简单的讲一下上面这张图
图里的第一行是CR3的描述
第二行PML5E是五级分页才会用到的这里不多赘述五级分页因为我还没有碰到五级分页的操作系统
第三行的PML4E是一级页表项当p=1时说明当前页表项有效否则是无效
第四行的PDPTE是二级页表项,当p=1时有效而且ps位=1的时候是1G的大页(第7位)1G的话大家可以拆分一下看看1G需要的页内寻址偏移为30位,我们的虚拟地址到拆分到二级的时候使用掉了18位正好剩下30位意味着我们的分页变为了9-9-30,如果ps=0的话就还按照9-9-9-9-12分页
第五行的PDE是三级页表项,当p=1时有效而且ps位=1的时候是2MB的大页(第7位)2MB的话大家可以拆分一下看看2MB需要的页内寻址偏移为21位,我们的虚拟地址到拆分到三级的时候使用掉了27位正好剩下30位意味着我们的分页变为了9-9-9-21,如果ps=0的话就还按照9-9-9-9-12分页
第六行的PTE是二级页表项目当p=1时有效
图中在4级以及以上的位置使用了PMLXE的描述方式,后面的则跟2-9-9-12时候的命名一样我觉得可能记起来比较麻烦所以就按照页表的级别来描述几级就是几级页表里面的项就是X级页表项这种叫法
各个位的介绍如下:
下面我们来拆分一个虚拟地址看一下
然后我们就可以做几个实验来熟悉一下这个拆分过程
实验1:编写驱动,用代码拆分获取idt表的物理地址(复现我们刚刚手工的拆分过程)并手工拆分验证
实验代码:
x64Common.h
main.c
打印结果如下
手工拆分
做个实验回顾一下之前的页机制,以达到熟悉页机制的目的
实验1:编写驱动读取某个进程的某个虚拟地址内容并打印出物理地址,然后手工修改这个物理地址里的内容来验证找到的是否正确(驱动代码共享内存然后修改内存的方式后面再讲现在只手工实验),这边我默认大家都学过x32的内核知识,不过会在代码注释中将页之外的动作加上对应的说明
实验代码:
测试应用程序:
根据pid和addr编写我们的驱动代码
驱动:
x64Common.h
x64Common.c
main.c
得到打印出的物理地址:
手动修改地址内容为123
查看测试程序的输出
fffff803`
45299fc0
00209b00
`
00000000
00409300
`
00000000
0
: kd> r cr3
cr3
=
00000000001aa000
这是我环境中的GDT表中的一项,我的cr3是
=
00000000001aa000
,下面让我门来拆一下
11111111
11111111
11111000
00000011
01000101
00101001
10011111
10110000
上面是拆成二进制的形式
高
16
位不关注:fffff
1
级页表偏移:
11111000
0
-
-
1f0
2
级页表偏移:
0000011
01
-
-
0d
3
级页表偏移:
000101
001
-
-
29
4
级页表偏移:
01001
1001
-
-
99
页内偏移:fc0
kd> !dq
00000000001aa000
+
1f0
*
8
0
: kd> !dq
00000000
`
05209000
+
d
*
8
0
: kd> !dq
00000000
`
05215000
+
29
*
8
0
: kd> !dq
00000000
`
05122000
+
99
*
8
0
: kd> !dq
6499000
+
fc0
可以看到我们手工拆分查出来的跟虚拟地址里存的是一样的,我们还可以通过!pte命令来验证
0
: kd> !pte fffff803`
45299fc0
VA fffff80345299fc0
PXE at FFFFEEF77BBDDF80 PPE at FFFFEEF77BBF0068 PDE at FFFFEEF77E00D148 PTE at FFFFEEFC01A294C8
contains
0000000005209063
contains
0000000005215063
contains
0000000005122063
contains
8900000006499963
pfn
5209
-
-
-
DA
-
-
KWEV pfn
5215
-
-
-
DA
-
-
KWEV pfn
5122
-
-
-
DA
-
-
KWEV pfn
6499
-
G
-
DA
-
-
KW
-
V
fffff803`
45299fc0
00209b00
`
00000000
00409300
`
00000000
0
: kd> r cr3
cr3
=
00000000001aa000
这是我环境中的GDT表中的一项,我的cr3是
=
00000000001aa000
,下面让我门来拆一下
11111111
11111111
11111000
00000011
01000101
00101001
10011111
10110000
上面是拆成二进制的形式
高
16
位不关注:fffff
1
级页表偏移:
11111000
0
-
-
1f0
2
级页表偏移:
0000011
01
-
-
0d
3
级页表偏移:
000101
001
-
-
29
4
级页表偏移:
01001
1001
-
-
99
页内偏移:fc0
kd> !dq
00000000001aa000
+
1f0
*
8
0
: kd> !dq
00000000
`
05209000
+
d
*
8
0
: kd> !dq
00000000
`
05215000
+
29
*
8
0
: kd> !dq
00000000
`
05122000
+
99
*
8
0
: kd> !dq
6499000
+
fc0
可以看到我们手工拆分查出来的跟虚拟地址里存的是一样的,我们还可以通过!pte命令来验证
0
: kd> !pte fffff803`
45299fc0
VA fffff80345299fc0
PXE at FFFFEEF77BBDDF80 PPE at FFFFEEF77BBF0068 PDE at FFFFEEF77E00D148 PTE at FFFFEEFC01A294C8
contains
0000000005209063
contains
0000000005215063
contains
0000000005122063
contains
8900000006499963
pfn
5209
-
-
-
DA
-
-
KWEV pfn
5215
-
-
-
DA
-
-
KWEV pfn
5122
-
-
-
DA
-
-
KWEV pfn
6499
-
G
-
DA
-
-
KW
-
V
struct Attribute
{
UINT64 offset1 :
16
;
UINT64 p :
1
;
UINT64 dpl :
2
;
UINT64 s :
1
;
UINT64
type
:
4
;
UINT64 unuse :
6
;
UINT64 ist :
2
;
UINT64 selector :
16
;
UINT64 offset2 :
16
;
};
typedef struct _IDT_ENTRY64 {
union hightStruct
{
UINT64 lower;
struct Attribute attribute;
};
UINT64 hight;
}IDT_ENTRY64,
*
PIDT_ENTRY64;
typedef struct _IDTR
{
UINT16 limit;
UINT64 base;
}IDTR,
*
PIDTR;
/
/
/
<summary>
/
/
/
cr4结构体
/
/
/
<
/
summary>
typedef union _CR4 {
UINT64 value;
struct
{
UINT64 VME :
1
;
UINT64 PVI :
1
;
UINT64 TSD :
1
;
UINT64 DE :
1
;
UINT64 PSE :
1
;
UINT64 PAE :
1
;
UINT64 MCE :
1
;
UINT64 PGE :
1
;
UINT64 PCE :
1
;
UINT64 OSFXSR :
1
;
UINT64 OSXMMEXCPT :
1
;
UINT64 UMIP :
1
;
UINT64 LA57 :
1
;
UINT64 VMXE :
1
;
UINT64 SMXE :
1
;
UINT64 unuse1 :
1
;
UINT64 FSGSBASE :
1
;
UINT64 PCIDE :
1
;
UINT64 OSXSAVE :
1
;
UINT64 KL :
1
;
UINT64 SMEP :
1
;
UINT64 SMAP :
1
;
UINT64 PKE :
1
;
UINT64 CET :
1
;
UINT64 PKS :
1
;
UINT64 Ressrved :
63
-
24
;
}Fields;
}CR4,
*
PCR4;
static_assert(sizeof(CR4)
=
=
8
,
"sizeof CR4"
);
/
/
/
<summary>
/
/
/
cr3结构体
/
/
/
<
/
summary>
typedef union _CR3 {
UINT64 value;
struct
{
UINT64 ignore1 :
3
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 ignore2 :
7
;
UINT64 PPN :
40
;
UINT64 Reserved1 :
12
;
}Fields;
}CR3,
*
PCR3;
static_assert(sizeof(CR3)
=
=
8
,
"sizeof CR3"
);
/
/
/
<summary>
/
/
/
各页表项结构体
/
/
/
<
/
summary>
typedef union _PA {
UINT64 vaule;
LARGE_INTEGER AsLargeInteger;
struct
{
UINT64 PPO :
12
;
UINT64 PPN :
40
;
UINT64 UnUse1 :
12
;
}Fileds4KB;
struct
{
UINT64 PPO :
21
;
UINT64 PPN :
31
;
UINT64 UnUse1 :
12
;
}Fileds2MB;
struct
{
UINT64 PPO :
30
;
UINT64 PPN :
22
;
UINT64 UnUse1 :
12
;
}Fileds1GB;
}PA,
*
P_PA;
static_assert(sizeof(PA)
=
=
8
,
"sizeof PA"
);
/
/
/
<summary>
/
/
/
虚拟地址结构体
/
/
/
<
/
summary>
typedef union _VA {
UINT64 vaule;
LARGE_INTEGER AsLargeInteger;
struct
{
UINT64 VPO :
12
;
UINT64 VPN4 :
9
;
UINT64 VPN3 :
9
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds4KB;
struct
{
UINT64 VPO :
21
;
UINT64 VPN3 :
9
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds2MB;
struct
{
UINT64 VPO :
30
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds1GB;
}VA,
*
P_VA;
static_assert(sizeof(VA)
=
=
8
,
"sizeof VA"
);
typedef union _PML4E {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
5
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign2 :
15
;
UINT64 XD :
1
;
}Fields4K;
}PML4E,
*
PPML4E, L1PTE,
*
PL1PTE;
static_assert(sizeof(PML4E)
=
=
8
,
"sizeof PML4E"
);
typedef union _PDPTE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 Reserved :
18
;
UINT64 PPN :
18
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields1G;
}PDPTE,
*
PPDPTE, L2PTE,
*
PL2PTE;
static_assert(sizeof(PDPTE)
=
=
8
,
"sizeof PDPTE"
);
typedef union _PDE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 Reserved :
9
;
UINT64 PPN :
27
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields2MB;
}PDE,
*
PPDE, L3PTE,
*
PL3PTE;
static_assert(sizeof(PDE)
=
=
8
,
"sizeof PDE"
);
typedef union _PTE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
}PTE,
*
PPTE, L4PTE,
*
PL4PTE;
static_assert(sizeof(PDE)
=
=
8
,
"sizeof PTE"
);
/
/
各个页表存储了
512
个页表项
/
/
-
-
-
-
-
-
内核导出函数声明:begin
-
-
-
-
-
-
/
/
extern PVOID __stdcall MmGetVirtualForPhysical(LARGE_INTEGER AsLargeInteger);
extern NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS
*
Process);
/
/
-
-
-
-
-
-
内核导出函数声明: end
-
-
-
-
-
-
/
/
struct Attribute
{
UINT64 offset1 :
16
;
UINT64 p :
1
;
UINT64 dpl :
2
;
UINT64 s :
1
;
UINT64
type
:
4
;
UINT64 unuse :
6
;
UINT64 ist :
2
;
UINT64 selector :
16
;
UINT64 offset2 :
16
;
};
typedef struct _IDT_ENTRY64 {
union hightStruct
{
UINT64 lower;
struct Attribute attribute;
};
UINT64 hight;
}IDT_ENTRY64,
*
PIDT_ENTRY64;
typedef struct _IDTR
{
UINT16 limit;
UINT64 base;
}IDTR,
*
PIDTR;
/
/
/
<summary>
/
/
/
cr4结构体
/
/
/
<
/
summary>
typedef union _CR4 {
UINT64 value;
struct
{
UINT64 VME :
1
;
UINT64 PVI :
1
;
UINT64 TSD :
1
;
UINT64 DE :
1
;
UINT64 PSE :
1
;
UINT64 PAE :
1
;
UINT64 MCE :
1
;
UINT64 PGE :
1
;
UINT64 PCE :
1
;
UINT64 OSFXSR :
1
;
UINT64 OSXMMEXCPT :
1
;
UINT64 UMIP :
1
;
UINT64 LA57 :
1
;
UINT64 VMXE :
1
;
UINT64 SMXE :
1
;
UINT64 unuse1 :
1
;
UINT64 FSGSBASE :
1
;
UINT64 PCIDE :
1
;
UINT64 OSXSAVE :
1
;
UINT64 KL :
1
;
UINT64 SMEP :
1
;
UINT64 SMAP :
1
;
UINT64 PKE :
1
;
UINT64 CET :
1
;
UINT64 PKS :
1
;
UINT64 Ressrved :
63
-
24
;
}Fields;
}CR4,
*
PCR4;
static_assert(sizeof(CR4)
=
=
8
,
"sizeof CR4"
);
/
/
/
<summary>
/
/
/
cr3结构体
/
/
/
<
/
summary>
typedef union _CR3 {
UINT64 value;
struct
{
UINT64 ignore1 :
3
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 ignore2 :
7
;
UINT64 PPN :
40
;
UINT64 Reserved1 :
12
;
}Fields;
}CR3,
*
PCR3;
static_assert(sizeof(CR3)
=
=
8
,
"sizeof CR3"
);
/
/
/
<summary>
/
/
/
各页表项结构体
/
/
/
<
/
summary>
typedef union _PA {
UINT64 vaule;
LARGE_INTEGER AsLargeInteger;
struct
{
UINT64 PPO :
12
;
UINT64 PPN :
40
;
UINT64 UnUse1 :
12
;
}Fileds4KB;
struct
{
UINT64 PPO :
21
;
UINT64 PPN :
31
;
UINT64 UnUse1 :
12
;
}Fileds2MB;
struct
{
UINT64 PPO :
30
;
UINT64 PPN :
22
;
UINT64 UnUse1 :
12
;
}Fileds1GB;
}PA,
*
P_PA;
static_assert(sizeof(PA)
=
=
8
,
"sizeof PA"
);
/
/
/
<summary>
/
/
/
虚拟地址结构体
/
/
/
<
/
summary>
typedef union _VA {
UINT64 vaule;
LARGE_INTEGER AsLargeInteger;
struct
{
UINT64 VPO :
12
;
UINT64 VPN4 :
9
;
UINT64 VPN3 :
9
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds4KB;
struct
{
UINT64 VPO :
21
;
UINT64 VPN3 :
9
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds2MB;
struct
{
UINT64 VPO :
30
;
UINT64 VPN2 :
9
;
UINT64 VPN1 :
9
;
UINT64 UnUse1 :
16
;
}Fileds1GB;
}VA,
*
P_VA;
static_assert(sizeof(VA)
=
=
8
,
"sizeof VA"
);
typedef union _PML4E {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
5
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign2 :
15
;
UINT64 XD :
1
;
}Fields4K;
}PML4E,
*
PPML4E, L1PTE,
*
PL1PTE;
static_assert(sizeof(PML4E)
=
=
8
,
"sizeof PML4E"
);
typedef union _PDPTE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 Reserved :
18
;
UINT64 PPN :
18
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields1G;
}PDPTE,
*
PPDPTE, L2PTE,
*
PL2PTE;
static_assert(sizeof(PDPTE)
=
=
8
,
"sizeof PDPTE"
);
typedef union _PDE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 Reserved :
9
;
UINT64 PPN :
27
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields2MB;
}PDE,
*
PPDE, L3PTE,
*
PL3PTE;
static_assert(sizeof(PDE)
=
=
8
,
"sizeof PDE"
);
typedef union _PTE {
UINT64 value;
struct
{
UINT64 P :
1
;
UINT64 R_W :
1
;
UINT64 US :
1
;
UINT64 PWT :
1
;
UINT64 PCD :
1
;
UINT64 A :
1
;
UINT64 ign :
1
;
UINT64 PS :
1
;
UINT64 ign2 :
3
;
UINT64 R :
1
;
UINT64 PPN :
36
;
UINT64 ign3 :
15
;
UINT64 XD :
1
;
}Fields4K;
}PTE,
*
PPTE, L4PTE,
*
PL4PTE;
static_assert(sizeof(PDE)
=
=
8
,
"sizeof PTE"
);
/
/
各个页表存储了
512
个页表项
/
/
-
-
-
-
-
-
内核导出函数声明:begin
-
-
-
-
-
-
/
/
extern PVOID __stdcall MmGetVirtualForPhysical(LARGE_INTEGER AsLargeInteger);
extern NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS
*
Process);
/
/
-
-
-
-
-
-
内核导出函数声明: end
-
-
-
-
-
-
/
/
/
/
VOID Unload(PDRIVER_OBJECT pDriver) {
KdPrint((
"unload\r\n"
));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {
NTSTATUS status
=
STATUS_SUCCESS;
pDriver
-
>DriverUnload
=
Unload;
KdPrint((
"start\r\n"
));
CR4 cr4
=
{ .value
=
__readcr4() };
cr4.Fields.SMAP
=
0
;
cr4.Fields.SMEP
=
0
;
__writecr4(cr4.value);
IDTR idtr
=
{
0
};
__sidt(&idtr);
VA idtVa
=
{ .vaule
=
idtr.base };
CR3 cr3
=
{ .value
=
__readcr3() };
PA pa
=
{
0
};
pa.Fileds4KB.PPN
=
cr3.Fields.PPN;
/
/
PL1PTE L1
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt1级页表对应的虚拟地址地址0x%p\r\n"
, L1));
pa.Fileds4KB.PPN
=
L1[idtVa.Fileds4KB.VPN1].Fields4K.PPN;
KdPrint((
"当前idt1级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL2PTE L2
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt2级页表对应的虚拟地址地址0x%p\r\n"
, L2));
pa.Fileds4KB.PPN
=
L2[idtVa.Fileds4KB.VPN2].Fields4K.PPN;
KdPrint((
"当前idt2级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL3PTE L3
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt3级页表对应的虚拟地址地址0x%p\r\n"
, L3));
pa.Fileds4KB.PPN
=
L3[idtVa.Fileds4KB.VPN3].Fields4K.PPN;
KdPrint((
"当前idt3级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL4PTE L4
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt4级页表对应的虚拟地址地址0x%p\r\n"
, L4));
pa.Fileds4KB.PPN
=
L4[idtVa.Fileds4KB.VPN4].Fields4K.PPN;
pa.Fileds4KB.PPO
=
idtVa.Fileds4KB.VPO;
KdPrint((
"当前idt对应的物理地址地址0x%llx\r\n"
, pa.vaule));
KdPrint((
"end\r\n"
));
return
status;
}
/
/
VOID Unload(PDRIVER_OBJECT pDriver) {
KdPrint((
"unload\r\n"
));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {
NTSTATUS status
=
STATUS_SUCCESS;
pDriver
-
>DriverUnload
=
Unload;
KdPrint((
"start\r\n"
));
CR4 cr4
=
{ .value
=
__readcr4() };
cr4.Fields.SMAP
=
0
;
cr4.Fields.SMEP
=
0
;
__writecr4(cr4.value);
IDTR idtr
=
{
0
};
__sidt(&idtr);
VA idtVa
=
{ .vaule
=
idtr.base };
CR3 cr3
=
{ .value
=
__readcr3() };
PA pa
=
{
0
};
pa.Fileds4KB.PPN
=
cr3.Fields.PPN;
/
/
PL1PTE L1
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt1级页表对应的虚拟地址地址0x%p\r\n"
, L1));
pa.Fileds4KB.PPN
=
L1[idtVa.Fileds4KB.VPN1].Fields4K.PPN;
KdPrint((
"当前idt1级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL2PTE L2
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt2级页表对应的虚拟地址地址0x%p\r\n"
, L2));
pa.Fileds4KB.PPN
=
L2[idtVa.Fileds4KB.VPN2].Fields4K.PPN;
KdPrint((
"当前idt2级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL3PTE L3
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt3级页表对应的虚拟地址地址0x%p\r\n"
, L3));
pa.Fileds4KB.PPN
=
L3[idtVa.Fileds4KB.VPN3].Fields4K.PPN;
KdPrint((
"当前idt3级页表项对应的物理地址地址0x%llx\r\n"
, pa.vaule));
PL4PTE L4
=
MmGetVirtualForPhysical(pa.AsLargeInteger);
KdPrint((
"当前idt4级页表对应的虚拟地址地址0x%p\r\n"
, L4));
pa.Fileds4KB.PPN
=
L4[idtVa.Fileds4KB.VPN4].Fields4K.PPN;
pa.Fileds4KB.PPO
=
idtVa.Fileds4KB.VPO;
KdPrint((
"当前idt对应的物理地址地址0x%llx\r\n"
, pa.vaule));
KdPrint((
"end\r\n"
));
return
status;
}
start
当前idt1级页表对应的虚拟地址地址
0xFFFFC06030180000
当前idt1级页表项对应的物理地址地址
0x4f2e000
当前idt2级页表对应的虚拟地址地址
0xFFFFC06030190000
当前idt2级页表项对应的物理地址地址
0x4f2f000
当前idt3级页表对应的虚拟地址地址
0xFFFFC06032001000
当前idt3级页表项对应的物理地址地址
0x11cc6f000
当前idt4级页表对应的虚拟地址地址
0xFFFFC06400206000
当前idt对应的物理地址地址
0x2851000
end
start
当前idt1级页表对应的虚拟地址地址
0xFFFFC06030180000
当前idt1级页表项对应的物理地址地址
0x4f2e000
当前idt2级页表对应的虚拟地址地址
0xFFFFC06030190000
当前idt2级页表项对应的物理地址地址
0x4f2f000
当前idt3级页表对应的虚拟地址地址
0xFFFFC06032001000
当前idt3级页表项对应的物理地址地址
0x11cc6f000
当前idt4级页表对应的虚拟地址地址
0xFFFFC06400206000
当前idt对应的物理地址地址
0x2851000
end
1
: kd> r idtr
idtr
=
ffffc80040dd5000
Binary:
11111111
11111111
11001000
00000000
01000000
11011101
01010000
00000000
高
16
位不关注:fffff
1
级页表偏移:
11001000
0
-
-
190
2
级页表偏移:
0000000
01
-
-
01
3
级页表偏移:
000000
110
-
-
06
4
级页表偏移:
11101
0101
-
-
1d5
页内偏移:
000
kd> r cr3
cr3
=
00000000001aa000
1
: kd> !dq
00000000001aa000
+
190
*
8
1
: kd> !dq
4f2e000
+
8
1
: kd> !dq
4f2f000
+
6
*
8
1
: kd> !dq
1
`
1cc6f000
+
1d5
*
8
1
: kd> !dq
2851000
1
: kd> dq idtr
ffffc800`
40dd5000
48e08e00
`
00106300
00000000
`fffff805
ffffc800`
40dd5010
48e08e04
`
00106640
00000000
`fffff805
ffffc800`
40dd5020
48e08e03
`
00106b00
00000000
`fffff805
ffffc800`
40dd5030
48e0ee00
`
00106fc0
00000000
`fffff805
ffffc800`
40dd5040
48e0ee00
`
00107300
00000000
`fffff805
ffffc800`
40dd5050
48e08e00
`
00107640
00000000
`fffff805
ffffc800`
40dd5060
48e08e00
`
00107c80
00000000
`fffff805
ffffc800`
40dd5070
48e08e00
`
00108280
00000000
`fffff805
1
: kd> r idtr
idtr
=
ffffc80040dd5000
Binary:
11111111
11111111
11001000
00000000
01000000
11011101
01010000
00000000
高
16
位不关注:fffff
1
级页表偏移:
11001000
0
-
-
190
2
级页表偏移:
0000000
01
-
-
01
3
级页表偏移:
000000
110
-
-
06
4
级页表偏移:
11101
0101
-
-
1d5
页内偏移:
000
kd> r cr3
cr3
=
00000000001aa000
1
: kd> !dq
00000000001aa000
+
190
*
8
1
: kd> !dq
4f2e000
+
8
1
: kd> !dq
4f2f000
+
6
*
8
1
: kd> !dq
1
`
1cc6f000
+
1d5
*
8
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-10-6 16:53
被幺幺满地乱爬编辑
,原因: