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?
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.