Home > front end >  Question about Nt and Zw functions API from User Mode
Question about Nt and Zw functions API from User Mode

Time:09-08

Im not working for any specific project, i just would like to know more about Nt and Zw functions, so here are my questions:

NOTE: Im always referring to User-Mode space, and not Kernel-Mode.

  1. Whats the difference between Nt and Zw functions ? (so like, for example NtTerminateProcess and ZwTerminateProcess)
  2. Is the same thing calling NtTerminateProcess and ZwTerminateProcess from user mode?
  3. From researching on the internet is saw that Zw function are mostly used by Kernel Drivers, but i tested few and all seems to be working perfectly in usermode too, so why should they be called in kernel mode only/mostly (?) if they works perfectly like Nt ones in usermode?
  4. I saw just by disassembly ntdll.dll that Nt functions are just a proxy for Zw ones, so actually why Nt ones exists?

NtTerminateProcess dissembled from ntdll with IDA PRO

CodePudding user response:

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 stup, 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. andfor 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

  • Related