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

问题描述:

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

我了解这些东西都是真实的:

  1. 用户模式线程实际上已转移到内核模式时,系统调用是通过NTDLL制成。
  2. 向内核模式的转换是通过特定于处理器的指令完成的。

那么通过NTDLL这些系统调用有什么特别之处呢?为什么用户模式线程不能伪造它并执行特定于处理器的指令以转换到内核模式?我知道我在这里错过了一些关键的Windows体系结构......它是什么?

+0

用户模式线程可以伪造它,但是与仅使用ntdll.dll有什么不同?在问题中加入更多关于为什么这会涉及到你的信息。 – 2009-06-29 16:13:54

+2

我认为OP是担心转换到环0,然后在环0中运行任意非O/S代码。 – ChrisW 2009-06-29 16:18:58

+1

Windows对它暴露(对用户模式)参数执行验证。如果不知道,你就无法传递无效数据。是的,有被忽视的角落案件。只是,查找本地特权升级漏洞。有一大堆 – unixman83 2011-09-24 19:57:03

您可能认为以用户模式运行的线程正在调用Ring 0,但这不是实际发生的事情。用户模式线程正在引发由Ring 0代码捕获的异常。用户模式线程暂停,CPU切换到内核/环0线程,然后可以检查用户模式线程的上下文(例如,调用堆栈和寄存器)以找出要执行的操作。在系统调用之前,它确实是一个异常,而不是调用环0代码的特殊例外。

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

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

其中有4个,编号从0到3.在ring 0中运行的代码具有最高权限;它可以(几乎)根据您的计算机进行任何操作。另一方面,第3环中的代码始终处于紧绷的状态;它只有有限的权力来影响事物。而环1和环2目前根本不用于任何目的。

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

自然地,您的用户模式代码(应用程序和所有)在环3中运行,而OS的代码在环0中运行。这确保用户模式线程不会混淆操作系统的数据结构和其他关键资源。请参阅this文章。另外,您可能还需要阅读英特尔手册,特别是第1卷和第3A卷,您可以下载here

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

我认为(我可能是错的),那它使用过渡的机制很简单:

  • 用户模式代码执行软件中断
  • 这个(中断)使转移到一个位置在中断描述符表(IDT)

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

用户模式(Ring 3)中运行的代码不能任意更改为内核模式(Ring 0)。只能使用特殊路由 - 跳闸,中断和sysenter向量,这些路由受到高度保护,输入被清理,以至于不好的数据不能(不应该)导致不良行为。

所有这些由内核设置,通常在启动时设置,只能在内核模式下配置,因此User-Mo de代码不能修改它。

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

查看Linux如何执行它的优点是,您可以在没有Windows源许可证的情况下执行此操作。

userspace source part is here here在LXR和 kernel space bit - 看entry_32.S和entry_64.S

在x86上的Linux有三种不同的机制,INT 0x80的,系统调用和SYSENTER。

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