Windows Native API:何时以及为何使用 Zw 与 Nt 前缀 API 调用?

发布于 2024-10-13 09:49:24 字数 287 浏览 6 评论 0原文

在本机 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泪冰清 2024-10-20 09:49:24

除了 Larry Osterman 的回答(您一定应该阅读),我还应该提到另一件事:

由于 NtXxx 变体执行检查,就好像调用来自用户模式一样,这意味着 < strong>传递给 NtXxs 函数的任何缓冲区都必须驻留在用户模式地址空间中,而不是内核模式。因此,如果您在驱动程序中调用像 NtCreateFile 这样的函数并将其指针传递给内核模式缓冲区,您将因此得到 STATUS_ACCESS_VIOLATION


请参阅使用 Nt 和 Zw 版本的本机系统服务例程

内核模式驱动程序调用本机系统服务例程的 Zw 版本,以通知例程参数来自受信任的内核模式源。在这种情况下,例程假设它可以安全地使用这些参数,而无需首先验证它们。但是,如果参数可能来自用户模式源或内核模式源,则驱动程序将调用 Nt 版本的例程,该例程根据调用线程的历史记录确定参数是否源自用户模式。模式或内核模式。

本机系统服务例程对它们接收的参数做出额外的假设。如果例程接收到指向由内核模式驱动程序分配的缓冲区的指针,则例程假定该缓冲区是在系统内存中分配的,而不是在用户模式内存中分配的。如果例程接收到由用户模式应用程序打开的句柄,则例程会在用户模式句柄表中查找该句柄,而不是在内核模式句柄表中查找。

另外,Zw 不代表任何东西。请参阅Zw 前缀是什么意思?

Windows 本机系统服务例程的名称以前缀 Nt 和 Zw 开头。 Nt前缀是Windows NT的缩写,而Zw前缀没有任何意义。选择 Zw 部分是为了避免与其他 API 潜在的命名冲突,部分是为了避免使用将来可能需要的任何潜在有用的两字母前缀。

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 a STATUS_ACCESS_VIOLATION because of this.


See Using Nt and Zw Versions of the Native System Services Routines.

A kernel-mode driver calls the Zw version of a native system services routine to inform the routine that the parameters come from a trusted, kernel-mode source. In this case, the routine assumes that it can safely use the parameters without first validating them. However, if the parameters might be from either a user-mode source or a kernel-mode source, the driver instead calls the Nt version of the routine, which determines, based on the history of the calling thread, whether the parameters originated in user mode or kernel mode.

Native system services routines make additional assumptions about the parameters that they receive. If a routine receives a pointer to a buffer that was allocated by a kernel-mode driver, the routine assumes that the buffer was allocated in system memory, not in user-mode memory. If the routine receives a handle that was opened by a user-mode application, the routine looks for the handle in the user-mode handle table, not in the kernel-mode handle table.

Also, Zw doesn't stand for anything. See What Does the Zw Prefix Mean?:

The Windows native system services routines have names that begin with the prefixes Nt and Zw. The Nt prefix is an abbreviation of Windows NT, but the Zw prefix has no meaning. Zw was selected partly to avoid potential naming conflicts with other APIs, and partly to avoid using any potentially useful two-letter prefixes that might be needed in the future.

凯凯我们等你回来 2024-10-20 09:49:24

我打算将此作为评论 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...

菩提树下叶撕阳。 2024-10-20 09:49:24

Zw 代表零等待(不浪费时间进行参数验证)。

Zw stands for Zero Wait (no time waste for parameters validation).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文