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

Windows 本机操作系统服务 API 作为一组在内核模式下运行的例程实现。 这些例程的名称以 前缀 NtZw 开头。 内核模式驱动程序可以直接调用这些例程。 用户模式应用程序可以使用系统调用来访问这些例程。

除了一些例外情况,每个本机系统服务例程都有两个略有不同的版本,这些版本的名称类似,但前缀不同。 例如,对 NtCreateFileZwCreateFile 的调用执行类似的作,实际上由同一内核模式系统例程提供服务。 对于来自用户模式的系统调用,例程的 NtZw 版本的行为方式相同。 对于内核模式驱动程序的调用,例程的 NtZw 版本在处理调用方传递给例程的参数值的方式上有所不同。

内核模式驱动程序调用本机系统服务例程的 Zw 版本,以通知例程参数来自受信任的内核模式源。 在这种情况下,例程假定它可以安全地使用参数,而无需首先验证参数。 但是,如果参数可能来自用户模式源或内核模式源,驱动程序会调用例程的 Nt 版本,该版本根据调用线程的历史记录来确定参数是源自用户模式还是内核模式。 有关例程如何区分用户模式参数与内核模式参数的详细信息,请参阅 PreviousMode

当用户模式应用程序调用本机系统服务例程的 NtZw 版本时,该例程始终将接收的参数视为来自不受信任的用户模式源的值。 例程在使用参数之前会彻底验证参数值。 具体而言,例程探测任何调用方提供的缓冲区,以验证缓冲区是否位于有效的用户模式内存中并正确对齐。

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

在几个实例中,参数值的含义在用户模式和内核模式的调用之间差异更大。 例如, ZwNotifyChangeKey 例程(或其 NtNotifyChangeKey 对应项)具有一对输入参数 ApcRoutineApcContext,这意味着不同的内容,具体取决于参数是来自用户模式还是内核模式源。 对于用户模式的调用, ApcRoutine 指向 APC 例程, ApcContext 指向作系统在调用 APC 例程时提供的上下文值。 对于内核模式的调用, ApcRoutine 指向 WORK_QUEUE_ITEM 结构, ApcContext 指定 WORK_QUEUE_ITEM 结构描述的工作队列项的类型。

本部分包含以下文章:

PreviousMode

库和标头

Zw 前缀的含义是什么?

指定访问权限

NtXxx 例程