KPTI - 内核页表隔离
简介:wiki - Kernel page-table isolation
在内核空间和用户空间使用了两套页表,目的是为了缓解熔断幽灵硬件漏洞,目前实验结果来看,在Win10 2004版本上好像没有启用(或许有其他补丁)
参考KiBreakpointTrapShadow
函数如下,在其中可以看到切换CR3的痕迹
另外,还在IDT表末尾一段空间中暂存了ss
、rsp
、rflags
、cs
、rip
的值,之后将其push到另一个栈上
可以修改前几次的代码,加上之前的交换gs、切换CR3,切换内核栈等操作,就可以拥有一个正确的内核环境,在此基础上就能调用内核中的功能了,比如
Message proc
; 读取CR3
mov rax, cr3
mov user_cr3, rax
; 交换gs,切换cr3
swapgs
mov rsp, gs:[9000h]
mov cr3, rsp
; 换栈
mov rsp, gs:[9008h]
mov gs:[10h],rsi
mov rsi, gs:[38h]
add rsi, 4200h
push qword ptr [rsi-8] ; ss
push qword ptr [rsi-10h] ; rsp
push qword ptr [rsi-18h] ; rflags
push qword ptr [rsi-20h] ; cs
push qword ptr [rsi-28h] ; rip
mov rsi, gs:[10h]
and qword ptr gs:[10h], 0
; 开中断
sti
int 3 ; 在此就可以调用一些内核功能
@L:
; jmp @L
; 交换gs,退出
swapgs
iretq
Message endp
CFG防御机制
有篇很好的文章介绍了这种机制:
针对于64位的情况如下: