用户模式下Nt和Zw没有区别。(指user mode下面调用ntdll.dll的导出函数,nt和zw系列函数没有区别)
内核模式下(例如NtOsKrnl.exe里面的函数),Nt有参数检验,Zw没有;PreviousMode是内核Thread对象的一个字段,意思是线程的之前的状态(内核模式or用户模式)
函数的具体实现在Nt里边,Zw是桩。Zw会设置线程PreviousMode为KernelMode,然后Call Nt函数。由于PreivousMode是KernelMode, Nt函数不会进行参数校验。Zw在返回时恢复原PreviousMode.
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/previousmode
Title:PreviousMode
A kernel-mode driver can run in the context of an arbitrary thread, and the PreviousMode field of this thread might be set to UserMode. In this situation, a kernel-mode driver can call the Zw version of a native system services routine to inform the routine that the parameter values are from a trusted, kernel-mode source. The Zw call goes to a thin wrapper function that overrides the PreviousMode value in the current thread object. The wrapper function sets PreviousMode to KernelMode and calls the Nt version of the routine. On return from the Nt version of the routine, the wrapper function restores the original PreviousMode value of the thread object and returns.
https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-nt-and-zw-versions-of-the-native-system-services-routines
Title: 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. For more information about how the routine distinguishes user-mode parameters from kernel-mode parameters, see PreviousMode.
When a user-mode application calls the Nt or Zw version of a native system services routine, the routine always treats the parameters that it receives as values that come from a user-mode source that is not trusted. The routine thoroughly validates the parameter values before it uses the parameters. In particular, the routine probes any caller-supplied buffers to verify that the buffers are located in valid user-mode memory and are aligned properly.
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.