我正在检查Windows 64位上的Wow 64子系统。据我所知,在x86_64处理器上,为了运行32位应用程序,它利用长模式兼容子模式。任何来自32位兼容模式的系统调用都是通过从当前模式到64位模式的切换模式来处理的(将CS
寄存器从0x23
选择器切换到0x33
选择器)。
我有两个问题。
第一个是在x32dbg下,我看不到ntdll 64位版本加载到进程的地址空间中。
第二个是关于CPU的方式更一般(或者实际上是CPU核心)对加载到段寄存器中的段选择器执行特权检查。(如Wow 64转换的情况)CPU隐式地需要将新的段代码选择器0x33
加载到CS
寄存器中。从Intel SDM,它根据当前加载在CS
中的代码段选择器和新代码段选择器的RPL
被加载在CS
(0x33
)中,对照来自内存中GDT表的相关代码段描述符的DPL
。
我的问题是:CPU/核心在(隐式或显式)访问这些段中的内存的操作期间执行哪些其他类型的检查?谢谢。
1条答案
按热度按时间kse8i1jr1#
在现代的x86(-64)操作系统上,段只在伊萨要求的情况下使用。对于CS,段用于设置当前模式和特权级别。而不是用于内存保护。
对于平面内存模型,CS和DS base = 0,limit = unlimited,因此每个“段”覆盖所有虚拟地址空间,即分段不用于内存保护,仅用于用户与内核模式。
唯一相关的检查是在重新加载段寄存器时(例如,在远跳转期间,或在
mov ds, eax
上)。在64位模式下,每次加载或存储期间的访问检查只是分页。在64位模式下,硬件需要平面内存模型; CS/DS/ES/SS的基数和限制被忽略。在32位传统模式下,主流操作系统在AMD 64之前的几年里都是这样做的。在compat模式下,我认为非零的DS / CS / ES / SS基数是可能的,但主流操作系统并不使用它们。(CPU硬件特殊情况base=0以简化加载/存储单元中的AGU中的地址计算。它们可能仍然进行极限检查,但当limit=-1且单位为4K时,它总是通过。)
FS和GS段在长模式下仍然可以有一个非零的段基,用于线程本地存储(TLS)。我忘记了它们是否可以有限制。(https://wiki.osdev.org/Segmentation)。您可以通过
wrmsr
将其基数设置为大于32位的值,而较新的CPU有wrfsbase
/wrgsbase
,操作系统可以让用户空间使用它们来更改基础,而无需系统调用。(不幸的是,这些指令只能在64位模式下工作,而不能在长模式的compat子模式下工作。