Wednesday, October 17, 2007
OSR的好文章 : Nt vs. Zw - Clearing Confusion On The Native API
連結 : OSR的好文章 : Nt vs. Zw - Clearing Confusion On The Native API
這篇提到一件很有趣的事情
所有的Native API都有Nt 跟Zw兩種 prefix
再加上ntdll.dll與ntosknl.exe各自都有expose Nt*/Zw*
所以總共有四種可能性
1.User mode呼叫Nt*
2.User mode呼叫Zw*
3.Kernel mode呼叫Nt*
4.Kernel mode呼叫Zw*
如果用debugger下去看的話,會發現1跟2沒有差別。3
的話就是直接呼叫真正的service,也就是1跟2最後會到的地方。
4卻會規規矩矩的把service放到eax,ebx指向parameter然後呼叫KiSystemService,KiSystemService再依照eax的值,查KeServiceDecriptorTable->KiServiceTable的內容
呼叫對應的service,也就是3。
乍看之下這樣的作法,與1跟2在ntdll.dll裡面的作法很像。
差別在於kernel service需要知道呼叫自己的人是來自於user mode或是kernel mode。
如果用1.2.呼叫,就是來自user mode。
4的話則是來自kernel mode。基本上service會信任kernel mode,而懷疑user mode。
這樣微妙的差異會導致某些運算成功或是失敗。
那麼3的previous mode會設定成甚麼呢?答案是user mode。
所以雖然3的呼叫方式看起來overhead比較小,但是會加上諸多限制。
所以比較好的作法是,在user mode使用1跟2。kernel mode使用4。
The moral of this bedtime story is that if you are in User Mode, use whatever variant you think makes your code look pretty. In Kernel Mode, use the ZwXxx routines and get your previous mode set properly, to Kernel Mode.
Labels:
Programming,
Windows
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment