【发布时间】:2019-08-23 03:40:34
【问题描述】:
我读到有一些寄存器在 x86 CPU 处于用户模式时无法修改(我相信这些寄存器被称为“特权寄存器”)。
但是 x86 CPU 可以在用户模式下读取这些寄存器的值,还是不允许读取?
【问题讨论】:
标签: assembly x86 cpu-registers elevated-privileges instruction-set
我读到有一些寄存器在 x86 CPU 处于用户模式时无法修改(我相信这些寄存器被称为“特权寄存器”)。
但是 x86 CPU 可以在用户模式下读取这些寄存器的值,还是不允许读取?
【问题讨论】:
标签: assembly x86 cpu-registers elevated-privileges instruction-set
可用的寄存器在当前Intel x64-x32-Architectures.Software.Developer.Manual的Section 3.2和Section 3.4中描述。
一般来说,不是所有的寄存器都可以从用户模式读取,甚至更少可以从用户模式写入。
例如,EFLAGS 寄存器可以从 User Mode 完全读取,但所有 System Flags 和 IOPL Field(s) 从 Section 3.4.3.3 无法从用户模式写入。
【讨论】:
您通常用于计算的所有寄存器都可以在任何模式下读取/写入(GP 整数、x87/MMX、XMM/YMM/ZMM 和 AVX512 k0-7 掩码寄存器),但是有许多寄存器是基本上是模式/控制设置。一些“特殊”寄存器可以写入用户空间,如段寄存器、MPX bnd 寄存器。
在用户模式(权限级别> 0)下无法读取或写入以下寄存器:
WRMSR/RDMSR 以外的指令访问某些寄存器。这样的寄存器可以在用户模式下访问。例如,内核可能允许用户代码使用 WRPMC 和 RDPMC 指令访问 PMC 寄存器。CR4.UMIP = 0,则可以使用 SMSW 读取 CR0。在 AMD 处理器上,CR4.UMIP 不可用,SMSW 可以在任何特权级别无条件地执行。EFLAGS 寄存器允许的修改有点复杂,如英特尔手册第 2 卷所述:
在受保护、兼容或 64 位模式下运行时 权限级别大于 0,但小于等于 IOPL,所有 除了 IOPL 字段和 RF、IF、VIP、VIF 和 虚拟机;这些不受影响。 AC 和 ID 标志只能修改 如果操作数大小属性为 32。中断标志 (IF) 为 只有在至少与 IOPL。如果执行 POPF/POPFD 指令时没有足够的 特权,不会发生异常,但特权位不会 改变。
在虚拟 8086 模式 (EFLAGS.VM = 1) 下运行时 虚拟 8086 模式扩展 (CR4.VME = 0),POPF/POPFD 指令只能在 IOPL = 3 时使用;否则,一个 发生一般保护异常 (#GP)。如果虚拟 8086 模式 启用扩展(CR4.VME = 1),POPF(但不是 POPFD)可以 在 IOPL
【讨论】:
cr0 的下半部分可以使用rmsw 从用户空间读取。