18

在 Native API 中,Microsoft 导出每个 api 调用的两个版本,一个以 Zw 为前缀,一个以 Nt 为前缀,例如。ZwCreateThread 和 NtCreateThread。

我的问题是这两个版本的调用有什么区别,何时以及为什么应该专门使用 Zw 或 Nt?据我了解,Zw 版本确保调用者驻留在内核模式,而 Nt 则不然。

我还想知道 Zw 和 Nt 前缀/缩写的具体含义?可以猜测 Nt 可能是指 NT(New Technology) Windows 系列还是 Native(可能不是)?至于Zw,它代表什么吗?

4

2 回答 2

16

更新:

除了拉里奥斯特曼的回答(你绝对应该阅读)之外,我还应该提到另一件事:

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


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

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

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

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

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

于 2011-01-22T21:06:48.820 回答
13

我打算将此作为对 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,因此假定驱动程序可以访问该文件。

驱动程序作者了解两者之间的区别很重要,因为它可能对安全性产生深远的影响......

于 2011-01-23T16:55:12.237 回答