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

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

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

有帮助吗?

解决方案

更新:

除了拉里·奥斯特曼(Larry Osterman)的回答(您应该 确实 阅读),我应该提到另一件事:

由于NTXXX变体执行检查,好像调用来自用户模式,这意味着 传递给NTXXS函数的任何缓冲区都必须位于用户模式地址空间中,而不是内核模式. 。因此,如果您调用一个函数 NtCreateFile 在您的驾驶员中并将其指针传递给内核模式缓冲区,您将获得一个 STATUS_ACCESS_VIOLATION 因为这。


使用本机系统服务例程的NT和ZW版本.

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

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

还, Zw 什么都不代表。看 ZW前缀是什么意思?:

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

其他提示

我本来打算将此作为对 Merhdad 答案的评论,但它太长了......

Mehrdad 的回答是 100% 准确的。这也有点误导。这 ”上一个模式”链接到的文章“使用 Nt 和 Zw...”文章 Mehrdad 对此进行了更详细的介绍。释义: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,因此假定驱动程序有权访问该文件。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top