Skip to content

Commit

Permalink
add intel-mpk
Browse files Browse the repository at this point in the history
  • Loading branch information
kanren3 committed Feb 2, 2024
1 parent 0a685a1 commit 4622e2c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions _posts/2024-02-02-intel-mpk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
title: 简述Intel MPK
date: 2024-02-02
categories:
- "Intel"
tags:
- "Intel"
- "AMD"
comments: true
image:
path: /assets/img/2024-02-02-intel-mpk/forest.jpg
---

## 引言

Intel MPK(Memory Protection Keys) 是Intel推出的一种内存保护机制,可以在不修改页表的情况下,来控制线性地址所关联物理页的访问权限,本篇将说明一些基本用法和用途,在阅读本篇内容前,需要读者对x86/x64架构有基本的了解。

## 说明

* CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4])
* 判断系统是否支持PKE

* CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4])
* 判断系统是否支持PKS

* CR4.PKE
* 控制是否启用User-Mode(用户模式)页面的Protection Keys

* CR4.PKS
* 控制是否启用Supervisor-Mode(管理模式)页面的Protection Keys

* PKRU
* 一个32位的内部寄存器,控制User-Mode Protection Keys所关联的页面权限

* IA32_PKRS
* 一个32位的MSR,控制Supervisor-Mode Protection Keys所关联的页面权限

* RDPKRU
* 读取PKRU内部寄存器

* WRPKRU
* 写入PKRU内部寄存器

## Protection Key

在禁用CR4.PKE的情况下,用户模式页表中的 `Bit 59 ~ Bit62` 是保留位

在启用CR4.PKE的情况下,用户模式页表中的 `Bit 59 ~ Bit62` 是Protection Key

在禁用CR4.PKS的情况下,管理模式页表中的 `Bit 59 ~ Bit62` 是保留位

在启用CR4.PKS的情况下,管理模式页表中的 `Bit 59 ~ Bit62` 是Protection Key

这4位的Protection Key范围是0~15,相当于是一个索引,被关联到PKRU或PKRS

## PKRU

这个寄存器类似于一个位图,存放着16对ADi与WDi,用于控制与User-Mode Protection Key关联的页面权限,这个寄存器需要通过`RDPKRU` `WRPKRU` `XSAVE` `XRSTOR` 进行控制。

* ADi = 1,不允许任何数据访问
* WDi = 1,不允许用户模式数据写入(在CR0.WP复位的情况下管理模式可以写入)
* **取指操作不受PKRU影响**

## IA32_PKRS

这个寄存器结构与PKRU极其相似,区别在于它所控制的是Supervisor-Mode Protection Keys,并且此寄存器是一个MSR寄存器,高32位为保留位,需要通过`RDMSR` `WRMSR` 进行控制。

* ADi = 1,不允许任何数据访问
* WDi = 1,不允许用户模式数据写入(在CR0.WP复位的情况下管理模式可以写入)
* **取指操作不受PKRS影响**

## PageFault

如果是由Protection Keys引发的#PF,那么PFEC的 `Bit 5` 则置位。

## 流程

* 首先,判断处理器是否支持PKE或PKS
* 如果支持,则置位CR4.PKE或PKS
* 通过 `WRPKRU` 将权限写入到PKRU,或者通过 `WRMSR` 将权限写入到PKRS
* 例子:如果Protection Key设置为 `0Fh(1111b)` ,那么所对应的掩码就是 `0C0000000h `
* 然后修改页表条目中的Protection Key,将它与PKRU或PKRS关联

## 结尾

聪明的挂哥,可能已经看到加粗的几个字了,取指操作不受Protection Key影响,意味着可以分离读写与执行,可以分离读写就意味着,在使用所谓的 `无痕HOOK`的时候,性能可以大幅度提高。

聪明的挂哥都知道,Intel VT-x提供的EPT可以轻松的完成这项任务,但是AMD-V提供的NPT并没有这样的功能,那么结合Protection Key是否可以间接的为AMD-V提供这样的功能来平替EPT,来完成所谓的 `无痕HOOK` 呢?

答案就在下面,诸位细品。

```c
nt!_HARDWARE_PTE
+0x000 Valid : Pos 0, 1 Bit
+0x000 Write : Pos 1, 1 Bit
+0x000 Owner : Pos 2, 1 Bit
+0x000 WriteThrough : Pos 3, 1 Bit
+0x000 CacheDisable : Pos 4, 1 Bit
+0x000 Accessed : Pos 5, 1 Bit
+0x000 Dirty : Pos 6, 1 Bit
+0x000 LargePage : Pos 7, 1 Bit
+0x000 Global : Pos 8, 1 Bit
+0x000 CopyOnWrite : Pos 9, 1 Bit
+0x000 Prototype : Pos 10, 1 Bit
+0x000 reserved0 : Pos 11, 1 Bit
+0x000 PageFrameNumber : Pos 12, 40 Bits
+0x000 SoftwareWsIndex : Pos 52, 11 Bits
+0x000 NoExecute : Pos 63, 1 Bit
```
Binary file added assets/img/2024-02-02-intel-mpk/forest.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 4622e2c

Please sign in to comment.