ntdll.dll和ntoskrnl.exe中的NT*和ZW*函数区别
以NtOpenProcess和ZwOpenProcess為例,結(jié)合Windbg的lkd調(diào)試來(lái)說(shuō)明
1、Q:ntdll.dll中的Nt*和Zw*區(qū)別?
lkd> u ntdll!zwopenprocess l4
ntdll!ZwOpenProcess:
7c92d5fe b87a000000????? mov???? eax,7Ah?????????? //函數(shù)服務(wù)號(hào)
7c92d603 ba0003fe7f?????? mov???? edx,offset SharedUserData!SystemCallStub (7ffe0300)???? //函數(shù)地址
7c92d608 ff12???????????????????? call??? dword ptr [edx]
7c92d60a c21000????????????? ret???? 10h
lkd> u ntdll!ntopenprocess l4
ntdll!ZwOpenProcess:
7c92d5fe b87a000000????? mov???? eax,7Ah
7c92d603 ba0003fe7f?????? mov???? edx,offset SharedUserData!SystemCallStub (7ffe0300)
7c92d608 ff12??????????????????? call??? dword ptr [edx]
7c92d60a c21000????????????? ret???? 10h
A:從反匯編代碼來(lái)看,兩者別無(wú)區(qū)別,都是通過(guò)SSDT服務(wù)表,通過(guò)系統(tǒng)服務(wù)調(diào)度程序KiSystemService調(diào)用ntoskrnl.exe中的中斷處理程序Nt*函數(shù)。
2、Q:ntoskrnl.exe中的Nt*和Zw*有什么區(qū)別?
lkd> u nt!zwopenprocess l6
nt!ZwOpenProcess:
804e4c0a b87a000000????? mov???? eax,7Ah
804e4c0f 8d542404??????????? lea???? edx,[esp+4]
804e4c13 9c??????????????????????? pushfd
804e4c14 6a08??????????????????? push??? 8
804e4c16 e8b69bffff?????????? call??? nt!KiSystemService (804de7d1)
804e4c1b c21000?????????????? ret???? 10h
lkd> u nt!ntopenprocess l20
nt!NtOpenProcess:
80582702 68c4000000????? push??? 0C4h
80582707 68e8524f80????? push??? offset nt!ObWatchHandles+0x25c (804f52e8)
8058270c e87217f6ff????? call??? nt!_SEH_prolog (804e3e83)
80582711 33f6??????????? xor???? esi,esi
80582713 8975d4????????? mov???? dword ptr [ebp-2Ch],esi
80582716 33c0??????????? xor???? eax,eax
80582718 8d7dd8????????? lea???? edi,[ebp-28h]
8058271b ab????????????? stos??? dword ptr es:[edi]
8058271c 64a124010000??? mov???? eax,dword ptr fs:[00000124h]
80582722 8a8040010000??? mov???? al,byte ptr [eax+140h]
80582728 8845cc????????? mov???? byte ptr [ebp-34h],al
8058272b 84c0??????????? test??? al,al
8058272d 0f840e7b0100??? je????? nt!NtOpenProcess+0xc0 (8059a241)
80582733 8975fc????????? mov???? dword ptr [ebp-4],esi
80582736 a1d48e5680????? mov???? eax,dword ptr [nt!MmUserProbeAddress (80568ed4)]
8058273b 8b4d08????????? mov???? ecx,dword ptr [ebp+8]
8058273e 3bc8??????????? cmp???? ecx,eax
80582740 0f8315170800??? jae???? nt!NtOpenProcess+0x40 (80603e5b)
80582746 8b01??????????? mov???? eax,dword ptr [ecx]
80582748 8901??????????? mov???? dword ptr [ecx],eax
8058274a 8b5d10????????? mov???? ebx,dword ptr [ebp+10h]
8058274d f6c303????????? test??? bl,3
80582750 0f850c170800??? jne???? nt!NtOpenProcess+0x4e (80603e62)
80582756 a1d48e5680????? mov???? eax,dword ptr [nt!MmUserProbeAddress (80568ed4)]
8058275b 3bd8??????????? cmp???? ebx,eax
8058275d 0f8309170800??? jae???? nt!NtOpenProcess+0x5c (80603e6c)
80582763 397308????????????? cmp???? dword ptr [ebx+8],esi
80582766 0f9545e6??????? setne?? byte ptr [ebp-1Ah]
8058276a 8b4b0c????????? mov???? ecx,dword ptr [ebx+0Ch]
8058276d 894dc8????????? mov???? dword ptr [ebp-38h],ecx
80582770 8b4d14????????? mov???? ecx,dword ptr [ebp+14h]
80582773 3bce??????????? cmp???? ecx,esi
A:從反匯編代碼可知NT*是實(shí)現(xiàn)函數(shù)具體過(guò)程,而ZW*函數(shù)是在ring 0下通過(guò)SSDT服務(wù)表,KiSystemService調(diào)用ntoskrnl.exe中的中斷處理程序Nt*函數(shù)。
3、Q:ntdll.dll中的ZW*和ntoskrnl.exe中的ZW*有什么區(qū)別呢?
A:
從發(fā)匯編代碼來(lái)看:ntdll.dll:傳入服務(wù)號(hào)到eax——>調(diào)用SharedUserData!SystemCallStub (7ffe0300)函數(shù)->KiSystemService---->Nt*(ntoskrnl)
ntoskrnl.exe:傳入服務(wù)號(hào)eax——>KiSystemService--->Nt*(ntoshrnl)
S:從用戶模式調(diào)用Nt和Zw API,如NtReadFile和ZwReadFile,連接ntdll.lib:
二者沒有任何區(qū)別,通過(guò)設(shè)置系統(tǒng)服務(wù)表中的索引和在堆棧中設(shè)置參數(shù),經(jīng)由SYSENTER指令進(jìn)入內(nèi)核態(tài)(而不是象w2k中通過(guò)int 0x2e中斷),并最終由KiSystemService跳轉(zhuǎn)到KiServiceTable對(duì)應(yīng)的系統(tǒng)服務(wù)例程中。由于是從用戶模式進(jìn)入內(nèi)核模式,因此代碼會(huì)嚴(yán)格檢查用戶空間傳入的參數(shù)。
從內(nèi)核模式調(diào)用Nt和Zw API,連接nooskrnl.lib:
Nt系列API將直接調(diào)用對(duì)應(yīng)的函數(shù)代碼,而Zw系列API則通過(guò)KiSystemService,最終跳轉(zhuǎn)到對(duì)應(yīng)的函數(shù)代碼。
重要的是兩種不同的調(diào)用對(duì)內(nèi)核中previous mode的改變,如果是從用戶模式調(diào)用Native API則previous mode是用戶態(tài),如果從內(nèi)核模式調(diào)用Native API則previous mode是內(nèi)核態(tài)。previous為用戶態(tài)時(shí)Native API將對(duì)傳遞的參數(shù)進(jìn)行嚴(yán)格的檢查,而為內(nèi)核態(tài)時(shí)則不會(huì)。
調(diào)用用戶模式Nt API時(shí)不會(huì)改變previous mode的狀態(tài),調(diào)用Zw API時(shí)會(huì)將previous mode改為內(nèi)核態(tài),因此在進(jìn)行Kernel Mode Driver開發(fā)時(shí)可以使用Zw系列API可以避免額外的參數(shù)列表檢查,提高效率。
總結(jié)
以上是生活随笔為你收集整理的ntdll.dll和ntoskrnl.exe中的NT*和ZW*函数区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 字符数据类型转换代码
- 下一篇: MFC 获取命令行参数