Nt* 与 Zw* 区别

以ReadFile为例   

ntdll.dll导出了ZwReadFile和NtReadFile  

在用户态 

不管你调用ZwReadFile还是NtReadFile都是一样的

因为他们是同一个函数的两个不同名称而已....  

而且他们最终都会调用到ntoskrnl中的NtReadFile中去

在内核态

ntoskrnl.exe导出了ZwReadFile和NtReadFile

Ntoskrnl导出的NtReadFile是真正的执行函数,ZwReadFile是一个stub函数

内核态调用ZwReadFile,会将Previous Mode设置为Kernel Mode,然后再调用NtReadFile

而在内核态直接调用NtReadFile,不会改变Previous Mode。

NtReadFile中会检测当前调用来自用户态还是内核态

如果是来自内核态,不会检测参数;而如果是来自用户态,就会做一系列的参数检测。

我们知道,内核组件可能运行在任意进程的上下文中,当它调用NtReadFile时,因为Previous Mode很可能是User Mode,

而我们的参数请求的内核态的地址,这时通常就会产 STATUS_ACCESS_VIOLATION 错误 

所以内核态一般用Zw*系列的函数

关于Nt*与Zw*更为详细的介绍,请参考 Nt vs. Zw - Clearing Confusion On The Native API 

原文地址:https://www.cnblogs.com/luzhiyuan/p/4472807.html