核心解惑:zw函式和nt函式的區別
lkd> u zwopenprocess
nt!zwopenprocess:
804de044 b87a000000 mov eax,7ah
804de049 8d542404 lea edx,[esp+4]
804de04d 9c pushfd
804de04e 6a08 push 8
804de050 e8dc150000 call nt!kisystemservice (804df631)
804de055 c21000 ret 10h
lkd> u ntopenprocess
nt!ntopenprocess:
80573d06 68c4000000 push 0c4h
80573d0b 6810b44e80 push offset nt!obwatchhandles+0x25c (804eb410)
80573d10 e826f7f6ff call nt!_seh_prolog (804e343b)
80573d15 33f6 xor esi,esi
80573d17 8975d4 mov dword ptr [ebp-2ch],esi
80573d1a 33c0 xor eax,eax
80573d1c 8d7dd8 lea edi,[ebp-28h]
80573d1f ab stos dword ptr es:[edi]
這是看雪上某人反的兩個函式。
從使用者模式呼叫nt和zw api,如ntreadfile和zwreadfile,二者沒有任何區別,通過設定系統服務表中的索引和在堆疊中設定引數,經由sysenter指令進入核心態(而不是象w2k中通過int 0x2e中斷),並最終由kisystemservice跳轉到kiservicetable對應的系統服務例程中。由於是從使用者模式進入核心模式,因此**會嚴格檢查使用者空間傳入的引數。
從核心模式呼叫nt和zw api,連線nooskrnl.lib:
nt系列api將直接呼叫對應的函式**,而zw系列api則通過kisystemservice,最終跳轉到對應的函式**。
重要的是兩種不同的呼叫對核心中previous mode的改變,如果是從使用者模式呼叫native api則previous mode是使用者態,如果從核心模式呼叫native api則previous mode是核心態。previous為使用者態時native api將對傳遞的引數進行嚴格的檢查,而為核心態時則不會。
呼叫nt api時不會改變previous mode的狀態,呼叫zw api時會將previous mode改為核心態,因此在進行kernel mode driver開發時可以使用zw系列api可以避免額外的引數列表檢查,提高效率。
Zw 與Nt 的區別
某些zw和nt函式既在ntdll.dll中匯出又在ntoskrnl.exe中匯出,他們有什麼區別呢?我們分三部分比較 step 1 ntdll.dll中的zw和nt有什麼區別?step 2 ntoskrnl.exe中的zw和nt有什麼區別?step 3 ntdll.dll中的zw與ntoskrnl....
Zw 與Nt 的區別
某些zw 和nt 函式既在ntdll.dll中匯出又在ntoskrnl.exe中匯出,他們有什麼區別呢?我們分三部分比較 step 1 ntdll.dll中的zw 和nt 有什麼區別?step 2 ntoskrnl.exe中的zw 和nt 有什麼區別?step 3 ntdll.dll中的zw 與nt...
Zw函式與Nt函式的分別與聯絡
ring3中的native api,和ring0的系統呼叫,都有同名的zw和nt系列函式,一度讓初學者感到迷糊。n久前的我,也是相當的迷糊。現在就以zwopenprocess和ntopenprocess函式為例,詳細闡述下他們的分別和聯絡。ntdll.dll匯出了ntopenprocess和zwop...