Whats the difference between Nt and Zw functions ?
in user mode both 2 names point to the same address (function). so no difference which name use. and in user mode this functions is stub, which call to kernel. the ntdll.dll export all names - all Nt and all Zw. however if use definitions from ntifs/ntddk/wdm - not all functions declared. for instance in case registry functions - ZwCreateKey
, ZwOpenKey
, ZwQueryValueKey
,.. only with Zw prefix api declared. no declaration of Nt. so you need add it by self if want use NtOpenKey
for instance (possible include ntifs.h with windows.h)
in kernel mode - exist big difference between Zw and Nt. at first here it always point to different functions. the Nt - this is real implementation of function. when Zw - stub, which reenter kernel and call Nt.
so (in kernel!) call Nt always faster that Zw.
call Nt use less stack space (this is important for kernel)
from another side -if call Zw - previous mode always will be kernel at Nt point. if direct call Nt - previous mode will be the same as at call point (this is base on context from where call, usually will be user mode as previous mode)
and finally ntoskrnl.exe export far not all Zw and Nt functions. for some api only Zw exported. for some only Nt. so we have no choise which variant call. for some both or not export at all. for select which variant call in kernel - need have knowledge (what is previous mode), from where we call api, etc.
Is the same thing calling NtTerminateProcess and ZwTerminateProcess
from user mode?
yes. absolute the same. because, both names (Zw and Nt) point to the same address and both is exported
From researching on the internet is saw that Zw function are mostly used by Kernel Drivers...
this is mistake. for call it in kernel need have deep knowledge, what we doing. and for call it from user mode - no difference, which prefix is use
I saw just by disassembly ntdll.dll that Nt functions are just a proxy for Zw ones, so actually why Nt ones exists?
you mistake. in user mode, how i already say, the Nt==Zw. and it point to proxy (stub ?) which call kernel. in native process. in wow64 process - this is also proxy (or stub) but not to kernel, instead to 64bit gate. here we go not direct to kernel, but to 64 bit code first, which fix parameters and call kernel.
in kernel mode Zw always proxy (stub) to Nt. but not visa versa