Windows Native API:何时以及为何使用 Zw 与 Nt 前缀 API 调用?
在本机 API 中,Microsoft 导出每个 API 调用的两个版本,例如,一种以 Zw 为前缀,另一种以 Nt 为前缀。 ZwCreateThread 和 NtCreateThread。
这两个版本的调用有什么区别?何时以及为什么应该专门使用 Zw 或 Nt?
据我了解,Zw 版本确保调用者驻留在内核模式,而 Nt 则不然。
Zw 和 Nt 前缀/缩写的具体含义是什么?
人们可以猜测 Nt 可能指的是 NT(新技术)Windows 系列或 Native(可能不是)? 至于Zw,它代表什么吗?
In Native API, Microsoft exports two versions of each API call, one prefixed with Zw and one with Nt, for example. ZwCreateThread and NtCreateThread.
What is the difference between those two versions of the calls and when and why should one use Zw or Nt exclusively?
To my understanding, the Zw version ensures that the caller resides in kernel mode, whereas Nt doesn't.
What is the specific meaning for Zw and Nt prefixes/abbreviations?
One can guess Nt probably refers to NT (New Technology) Windows family or Native (probably not)?
As for Zw, does it stand for something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除了 Larry Osterman 的回答(您一定应该阅读),我还应该提到另一件事:
由于 NtXxx 变体执行检查,就好像调用来自用户模式一样,这意味着 < strong>传递给 NtXxs 函数的任何缓冲区都必须驻留在用户模式地址空间中,而不是内核模式。因此,如果您在驱动程序中调用像
NtCreateFile
这样的函数并将其指针传递给内核模式缓冲区,您将因此得到STATUS_ACCESS_VIOLATION
。请参阅使用 Nt 和 Zw 版本的本机系统服务例程。
另外,
Zw
不代表任何东西。请参阅Zw 前缀是什么意思?:Aside from Larry Osterman's answer (which you should definitely read), there's another thing I should mention:
Since the NtXxx variants perform checks as though the call is coming from user-mode, this means that any buffers passed to the NtXxs function must reside in user-mode address spaces, not kernel-mode. So if you call a function like
NtCreateFile
in your driver and pass it pointers to kernel-mode buffers, you will get back aSTATUS_ACCESS_VIOLATION
because of this.See Using Nt and Zw Versions of the Native System Services Routines.
Also,
Zw
doesn't stand for anything. See What Does the Zw Prefix Mean?:我打算将此作为评论 user541686 的答案,但太长了...
user541686 的答案 100% 准确。这也有点误导。由“使用 Nt 和 Zw...”文章 user541686 对此进行了更详细的介绍。释义:
Nt 和 Zw API 调用之间的主要区别在于,Zw 调用通过系统调用调度程序,但对于驱动程序,Nt 调用是对 API 的直接调用。
当驱动程序调用 Zw API 时,通过系统调用调度程序运行的唯一实际效果是它将 KeGetPreviousMode() 设置为 KernelMode 而不是 UserMode(显然对于用户模式代码,Zw 和 Nt 形式是相同的)。当各种系统调用看到 ExGetPreviousMode 是 KernelMode 时,它们会绕过访问检查(因为驱动程序可以执行任何操作)。
如果驱动程序调用 NT 形式的 API,则可能会因访问检查而失败。
一个具体的例子:如果驱动程序调用NtCreateFile,NtCreateFile将调用SeAccessCheck()来查看调用驱动程序的应用程序是否有创建文件的权限。如果同一驱动程序调用 ZwCreateFile,则 NtCreateFile API 调用将不会调用 SeAccessCheck,因为 ExGetPreviousMode 返回 KernelMode,因此假定驱动程序有权访问该文件。
对于驱动程序作者来说,了解两者之间的区别非常重要,因为它可能对安全性产生深远的影响......
I was going to leave this as a comment on user541686's answer, but it got too long...
user541686's answer is 100% accurate. It is also slightly misleading. The "PreviousMode" article linked to by the "Using Nt and Zw..." article user541686 goes into it in more detail. Paraphrasing:
The primary difference between the Nt and Zw API calls is that the Zw calls go through the system call dispatcher, but for drivers, Nt calls are direct calls to the API.
When a driver calls a Zw API, the only real effect of running through the system call dispatcher is that it sets KeGetPreviousMode() to KernelMode instead of UserMode (obviously to user mode code, the Zw and Nt forms are identical). When the various system calls see that ExGetPreviousMode is KernelMode, they bypass access checking (since drivers can do anything).
If a driver calls the NT form of the APIs, it's possible that it will fail because of the access checks.
A concrete example: if a driver calls NtCreateFile, the NtCreateFile will call SeAccessCheck() to see if the application which called into the driver has permissions to create the file. If that same driver called ZwCreateFile, the NtCreateFile API call won't call SeAccessCheck because ExGetPreviousMode returned KernelMode and thus the driver is assumed to have access to the file.
It's important for driver authors to understand the difference between the two since it can have profound implications for security...
Zw 代表零等待(不浪费时间进行参数验证)。
Zw stands for Zero Wait (no time waste for parameters validation).