Windows如何保护转换到内核模式?

时间:2009-06-29 16:01:18

标签: windows winapi kernel

Windows如何防止用户模式线程任意将CPU转换为内核模式?

我理解这些事情是真的:

  1. 当通过NTDLL进行系统调用时,用户模式线程实际上转换到内核模式。
  2. 转换到内核模式是通过特定于处理器的指令完成的。
  3. 那么通过NTDLL对这些系统调用有什么特别之处?为什么用户模式线程不能伪造它并执行特定于处理器的指令转换到内核模式?我知道我在这里错过了一些关键的Windows架构......它是什么?

5 个答案:

答案 0 :(得分:17)

你可能认为在用户模式下运行的线程正在调用Ring 0,但这并不是实际发生的事情。用户模式线程导致Ring 0代码捕获的异常。停止用户模式线程并且CPU切换到内核/环0线程,该线程然后可以检查用户模式线程的上下文(例如,调用堆栈和寄存器)以找出要做什么。在系统调用之前,它实际上是一个异常,而不是特别用于调用ring 0代码的特殊异常。

如果您接受其他回复的建议并阅读the Intel manuals,您将看到syscall / sysenter不接受任何参数 - 操作系统决定会发生什么。你不能调用任意代码。 WinNT使用的函数编号映射到用户模式代码将执行的内核模式函数(例如,我的Windows XP机器上的NtOpenFile是fnc 75h(数字一直在变化; NTDll的作业之一是映射函数)调用fnc编号,将其放入EAX,将EDX指向传入参数,然后调用sysenter)。

答案 1 :(得分:9)

英特尔CPU使用所谓的“保护环”强制执行安全性。

其中有4个,从0到3编号。在0环上运行的代码具有最高权限;它(实际上)可以用你的电脑随心所欲。另一方面,环3中的代码总是紧密牵引;它只有有限的力量来影响事物。环1和环2目前根本不用于任何目的。

在较高特权环(例如环0)中运行的线程可以随意转换到较低特权环(例如环1,2或3)。但是,相反的过渡受到严格监管。这就是如何维护高特权资源(例如内存)等的安全性。

当然,您的用户模式代码(应用程序和所有代码)在环3中运行,而操作系统的代码在环0中运行。这可确保用户模式线程不会弄乱操作系统的数据结构和其他关键资源。

有关如何实际实施所有内容的详细信息,请阅读this文章。此外,您可能还需要阅读英特尔手册,尤其是第1卷和第3A卷,您可以下载here

这是英特尔处理器的故事。我确信其他架构也会发生类似情况。

答案 2 :(得分:7)

我认为(我可能错了)它用于转换的机制很简单:

  • 用户模式代码执行软件中断
  • 此(中断)导致分支到中断描述符表(IDT)
  • 中指定的位置

阻止用户模式代码篡改的事情如下:你需要被授权写入IDT;所以只有内核能够指定执行中断时会发生什么。

答案 3 :(得分:4)

在用户模式(Ring 3)下运行的代码不能随意更改为内核模式(Ring 0)。它只能使用特殊路径 - 跳转门,中断和sysenter向量。这些路由受到高度保护,并且擦除了输入,因此不良数据不会(不应该)导致不良行为。

所有这些都是由内核设置的,通常是在启动时。它只能在内核模式下配置,因此用户模式代码无法修改它。

答案 4 :(得分:3)

可以公平地说它以与Linux相似的方式(以相对)方式进行。在这两种情况下,它都是特定于CPU的,但在x86上可能是带有INT指令的软件中断,或者是通过SYSENTER指令。

查看Linux如何做到这一点的优势在于,您可以在没有Windows源许可证的情况下这样做。

LXR的userspace source part is here here和。{ kernel space bit - 查看entry_32.S和entry_64.S

在x86上的Linux下,有三种不同的机制,int 0x80,syscall和sysenter。

由内核在运行时构建的一个名为vdso的库由C库调用以实现syscall函数,该函数根据CPU和系统调用使用不同的机制。然后内核具有这些机制的处理程序(如果它们存在于特定的CPU变体上)。