日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

3 《Undocumented Windows 2000 Secrets》翻譯 --- 第五章( 二 )


必須采用 SPY_CALL 數(shù)組是因為 Windows 2000 的多線程本性 。當 Native API 函數(shù)被暫停( suspended )時,這種情況就會經(jīng)常出現(xiàn) ---- 此時,另一個線程將獲得控制權(quán),然后在它自己的時間片( time slice )內(nèi)調(diào)用另一個 Native API 函數(shù) 。這意味著 Spy 設(shè)備的 Hook Dispatcher 必須允許在任何時間和任何執(zhí)行點上的重進入( reenter ) 。如果 Hook Dispatcher 有單一的全局 SPY_CALL 存儲區(qū)域,它就可能在處于等待狀態(tài)的線程使用完之前被當前運行的線程覆寫( overwritten ) 。而這種情況正是藍屏的最佳候選人 。為了進一步了解 Native API 的嵌套,我在 Spy 的 DEVICE_CONTEXT 結(jié)構(gòu)中增加了 dLevel 和 dMisses 成員 。無論何時只要重進入 hook dispatcher (如,向 SPY_CALL 數(shù)組中增加一個新的 SPY_CALL ) dLevel 都不會累加一個 1。如果超過了最大嵌套層數(shù)(如,SPY_CALL 數(shù)組已滿),dMisses 就會累加一個 1 ,來標識丟失了一個日志記錄 。根據(jù)我的觀察,在實際環(huán)境下,可以很容易的發(fā)現(xiàn)嵌套層達到 4。這表示即時在高負載( heavy-load )的情況下,Native API 也會被重進入,因此,我將嵌套層數(shù)的上限設(shè)為 256。
在調(diào)用原始的 API 處理例程之前,Hook Dispatcher 會保存所有的 CPU 寄存器(包括 EFLAGS ),隨后執(zhí)行路徑將導(dǎo)向函數(shù)的進入點 。這會在 列表 5-3 中的 SpyHook5 標簽之前立即完成 。此時,SpyHook6 將位于棧頂,僅隨其后的是調(diào)用者的參數(shù) 。一旦 API 處理例程推出了,控制將被傳回到 hook dispatcher 的 SpyHook6 標簽 。從此處開始執(zhí)行的代碼也被設(shè)計為非入侵的 。此時,主要目標是允許調(diào)用者可以看到調(diào)用上下文,這和原始 API 函數(shù)建立的上下文幾乎完全一致 。Dispatcher 的主要問題是要能立即找到保存有當前 API 調(diào)用信息的 SPY_CALL 結(jié)構(gòu) 。唯一可以依賴的就是調(diào)用者的線程 ID ,該 ID 保存在 SPY_CALL 結(jié)構(gòu)的 hThread 成員中 。因此,Dispatcher 循環(huán)遍歷整個 SPY_CALL 數(shù)組以尋找匹配的線程 ID。注意,代碼不會關(guān)心 fmuse 標志的值;這并不是必須的,因為數(shù)組中所有未使用的 SPY_CALL 結(jié)構(gòu)的 hThread 都被設(shè)為了 0 ,這是系統(tǒng)空閑線程的 ID。循環(huán)會在到達數(shù)組結(jié)尾時終止 。否則的話(譯注:即沒有找到匹配的線程 ID ),Dispatcher 不會將控制返回給調(diào)用者,因為這樣做將是致命的 。在這種情況下,代碼的選擇余地很小,因此,它會進入 KeBugCheck() ,這樣做的結(jié)果當然是使系統(tǒng)以受控的方式終止 。不過這種情況應(yīng)該從來不會發(fā)生,但如果它發(fā)生了,那表示系統(tǒng)必然出現(xiàn)了很嚴重的錯誤,因此,使系統(tǒng)終止是最佳解決方案 。
如果發(fā)現(xiàn)了匹配的 SPY_CALL ,Hook Dispatcher 將結(jié)束它的工作 。最后的動作是調(diào)用日志記錄函數(shù) SpyHookProtocol() ,需要給該函數(shù)傳入一個指向 SPY_CALL 結(jié)構(gòu)的指針 。日志記錄所需的信息都保存在該結(jié)構(gòu)中 。當 SpyHookProtocol() 返回后,Dispatcher 就釋放它剛才使用的 SPY_CALL ,恢復(fù)所有的 CPU 寄存器,然后返回到調(diào)用者 。
API HOOK 協(xié)議
一個好的 API Spy 應(yīng)該可以在原始函數(shù)被調(diào)用后還能察看它使用的參數(shù),因為函數(shù)可能會通過傳入的緩沖區(qū)返回附加的數(shù)據(jù) 。因此,日志函數(shù) SpyHookProtocol() 在 hook 例程結(jié)束時將被調(diào)用,而此時 API 函數(shù)還未返回到調(diào)用者 。在討論它的實現(xiàn)秘訣之前,請先看看下面給出的兩個示例性的協(xié)議( Protocol ),它們會為你提供一個大概的方向 。圖 5-6 是在命令行下執(zhí)行 dir c: 時產(chǎn)生的日志文件的快照 。
請對比 圖 5-6 中列出的日志項和 列表 5-6 給出的協(xié)議格式化字符串 。在 示列 5-1 中,NtOpenFile() 和 NtClose() 的格式化字符串分別對應(yīng) 圖 5-6 中的第一行和第四行 。它們有著驚人的相似處;每一個格式化控制 ID 都緊隨在一個 % 號后(參考 表 5-2 ),與其相關(guān)的參數(shù)項將包含在協(xié)議中 。不過,協(xié)議還包含一些附加的信息,這些信息明顯不屬于格式字符串 。稍后我將解釋這種差異的原因 。

推薦閱讀