今天在看Undocumented Windows 2000 Secrets的时候, 一段对于Nt*与Zw*的区别,看了很久,看得不是很明白,后来通过网上查阅,现在比较清楚了.
以下为原文:
"一组与执行体的系统服务(executive's system services)平行的入口点.从内核模式的代码()中调用一个ZwXxx入口点将获得相应的系统服务,只是在使用Zw*()函数时,不会检查调用者的访问权限和参数的有效性,而且调用不会将先前模式(previous mode)切换到用户模式"
"尽管任意一组函数都可以从内核模式调用,但如果用Zw*()函数来代替Nt*()函数,则可将先前模式(这里的先前模式指的是发出请求的模式)切换到内核模式"
借助于LiveKd,我们来看一下Nt*()和Zw*()的区别:
1.在Ntdll.dll中的Nt*()与Zw*()
kd> u Ntdll!NtCreateFile L4
ntdll!NtCreateFile:
7c92d682 b825000000 mov eax,25h
7c92d687 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0
300)
7c92d68c ff12 call dword ptr [edx]
7c92d68e c22c00 ret 2Ch
--------------------------------------------------------------------------------
kd> u Ntdll!ZwCreateFile L4
ntdll!NtCreateFile:
7c92d682 b825000000 mov eax,25h
7c92d687 ba0003fe7f mov edx,offset SharedUserData!SystemCallStub (7ffe0
300)
7c92d68c ff12 call dword ptr [edx]
7c92d68e c22c00 ret 2Ch
通过上面的代码,我们不难发现,实际上在Ntdll中Nt*()与Zw*()是完全一样的.
2.在ntoskrnl.exe中的Nt*()与Zw*()
kd> u nt!ZwCreateFile L14
nt!ZwCreateFile:
808059a0 b825000000 mov eax,25h
808059a5 8d542404 lea edx,[esp+4]
808059a9 9c pushfd
808059aa 6a08 push 8
808059ac e8801c0000 call nt!KiSystemService (80807631)
808059b1 c22c00 ret 2Ch
-------------------------------------------------------------------------------
kd> u nt!NtCreateFile L16
nt!NtCreateFile:
80898bf8 8bff mov edi,edi
80898bfa 55 push ebp
80898bfb 8bec mov ebp,esp
80898bfd 33c0 xor eax,eax
80898bff 50 push eax
80898c00 50 push eax
80898c01 50 push eax
80898c02 ff7530 push dword ptr [ebp+30h]
80898c05 ff752c push dword ptr [ebp+2Ch]
80898c08 ff7528 push dword ptr [ebp+28h]
80898c0b ff7524 push dword ptr [ebp+24h]
80898c0e ff7520 push dword ptr [ebp+20h]
80898c11 ff751c push dword ptr [ebp+1Ch]
80898c14 ff7518 push dword ptr [ebp+18h]
80898c17 ff7514 push dword ptr [ebp+14h]
80898c1a ff7510 push dword ptr [ebp+10h]
80898c1d ff750c push dword ptr [ebp+0Ch]
80898c20 ff7508 push dword ptr [ebp+8]
80898c23 e87bfeffff call nt!IoCreateFile (80898aa3)
80898c28 5d pop ebp
80898c29 c22c00 ret 2Ch
当我们看到上面代码的时候,就会发现在ntoskrnl.exe中Nt*()与Zw*()的区别了