"all"windows版本的新1位漏洞利用在处理滚动条的内核代码中使用了一个错误。这让我思考。为什么windows在内核中处理滚动条,而不是用户模式?历史原因?其他操作系统能做到这一点吗?
TL;灾难恢复:微软为了性能牺牲了安全性。
滚动条在Windows上有点特别。大多数滚动条不是真正的窗口,而是作为"父"窗口上的装饰来实现的。这就引出了一个更为普遍的问题;为什么windows在windows上以内核模式实现?
让我们看看替代方案:
- 用户模式下的每个进程
- 用户模式下的单个"主"进程
备选方案1在处理您自己的窗口时具有很大优势;没有上下文切换/内核转换。当然,问题是来自不同进程的窗口位于同一屏幕上,必须有人负责决定哪个窗口是活动的,并在用户切换到不同窗口时协调更改。这个人必须是一个特殊的系统进程或内核,因为这些信息不能是每个进程的,它必须存储在全局的某个地方。这种双重信息设计将很复杂,因为全局窗口管理器无法信任每个进程的信息。我相信这个理论设计还有很多其他的缺点,但我不会在这里花更多的时间。
Windows NT 3实现了备选方案2的变体。窗口管理器在NT4中被移到内核模式主要是出于性能原因:
窗口管理器(USER)和图形设备接口(GDI)已从Win32子系统移动到Windows NT Executive。Win32用户模式设备驱动程序,包括图形显示器和打印机司机,也已调到行政部门。这些变化是设计用于简化图形处理、减少存储器需求,并提高性能。
在同一份文件中,还有更多的技术细节和理由:
在最初设计Windows NT时,Win32环境子系统被设计为环境子系统的对等支持MS-DOS、POSIX和OS/2中的应用程序。然而,应用程序和使用图形、窗口和消息传递所需的其他子系统Win32子系统中的函数。为了避免重复这些函数,Win32子系统被用作图形服务器所有子系统的功能。
此设计在Windows NT 3.5和3.51上运行良好,但低估了图形调用的数量和频率。拥有功能与单独的中的消息传递和窗口控制一样基本进程从客户端/服务器产生了大量内存开销消息传递、数据收集和管理多个线程。它还需要多个上下文开关,这些开关将CPU周期消耗为以及内存。每秒图形支持调用的数量降低了系统的性能。很明显,重新设计Windows NT 4.0中的这一方面可以回收这些浪费的系统资源并提高性能。
如今,其他子系统并不那么相关,但性能问题仍然存在。
如果我们看一个像IsWindowVisible这样的简单函数,那么当窗口管理器处于内核模式时,就不会有太多开销:该函数将在用户模式下执行几条指令,然后将CPU切换到环0,在那里整个操作(验证传入的窗口句柄,如果有效,则检索可见属性)都是在内核模式下执行的。然后它切换回用户模式,仅此而已
如果窗口管理器位于另一个进程中,那么内核转换的数量将至少增加一倍,并且必须以某种方式将函数输入和输出传递给窗口管理器进程和从窗口管理器过程传递函数输出,并且必须在等待结果时以某种方式使窗口管理器流程执行。NT3通过使用共享内存、LPC和一种称为配对线程的模糊功能的组合来实现这一点。