我打算将此作为对 Merhdad 答案的评论,但它太长了......
Mehrdad 的回答是 100% 准确的。这也有点误导。“使用 Nt 和 Zw...”文章 Mehrdad 链接到的“ PreviousMode ”文章更详细地介绍了它。释义: Nt 和 Zw API 调用之间的主要区别在于 Zw 调用通过系统调用调度程序,但对于驱动程序,Nt 调用是对 API 的直接调用。
当驱动程序调用 Zw API 时,通过系统调用调度程序运行的唯一真正效果是它将 KeGetPreviousMode() 设置为 KernelMode 而不是 UserMode(显然对于用户模式代码,Zw 和 Nt 形式是相同的)。当各种系统调用看到 ExGetPreviousMode 是 KernelMode 时,它们会绕过访问检查(因为驱动程序可以做任何事情)。
如果驱动程序调用 API 的 NT 形式,它可能会因为访问检查而失败。
一个具体的例子:如果驱动调用NtCreateFile,NtCreateFile会调用SeAccessCheck()来查看调用驱动的应用程序是否有创建文件的权限。如果同一个驱动程序调用了 ZwCreateFile,则 NtCreateFile API 调用将不会调用 SeAccessCheck,因为 ExGetPreviousMode 返回了 KernelMode,因此假定驱动程序可以访问该文件。
驱动程序作者了解两者之间的区别很重要,因为它可能对安全性产生深远的影响......