【已解決】Global Hook 抓不到其它的程式

Hook 對我來說是一個全新的東西,它的概念有點像以前在寫 DOS TSR (常駐程式) 的作法,必須攔截原本的中斷,然後改成呼叫自己的中斷服務常式,但自己的服務常式中又必須呼叫原本的中斷,以達到插入自己程式碼到系統中目的。

我實作的是 WH_CBT 的 Hook,當一個視窗有動作時 (包含 activating, creating, destroying, minimizing, maximizing, moving, or sizing) 都會呼叫這個 Hook,根據 MSDN 的說明,把 CBTProc 放在 DLL 中可以達到 Global Hook 的目的。

但奇怪的是,在偵錯的過程中,我把中斷點設在 CBTProc,只有點到我自己的程式時才有反應,點到其它的程式完全沒反應,不是 Global Hook 嗎?為甚麼點別的程式會攔截不到呢?



請看下圖


CBTProc 位於 My DLL 中,而 My Process 則設定 WH_CBT Hook,設定完成後,My DLL 就會插入到 Other Process 中,當 Other Process 滿足觸發條件時,就會呼叫我的 DLL

問題就出在這裡,我原本的想法是 DLL 應該只有一份,其它程式呼叫的都是同一個 DLL。實際上是,每一個程式要呼叫 DLL 時,會把它載入自己的行程中。所以 My DLL 與 Injected DLL 只是相同的副本,各自有自己的程式與資料空間 (虚擬空間)。

所以我設的中斷點其實是在 My DLL,而 Other Process 則是執行到 Injected DLL 的 CBTProc,當然攔截不到。

所幸 DLL 有一個 Shared Data 的機制可以讓資料在所有 DLL 副本中共用,因此在設定 Hook 的同時,可以把  My Process 的 HWND 存到 Shared Data 中,當 Other Process 觸發時,就可以利用該 HWND PostMessage 給 My Process,以便進一步的處理。

到這裡總算豁然開朗了,不過有辦法可以在 Injected DLL 中設定中斷點 Trace 程式嗎?再想想吧!


真是太棒了,原來 Visual Studio 就有這個功能了


Start Debugging,然後點選 Debug | Attach to Process,選擇要 Attach 的 Process。當該 Process 觸發 DLL 的中斷時,就可以攔截到了。當 Debug 結束後,選擇 Detach All 才會結束整個流程。

留言

這個網誌中的熱門文章

Linux 批次檔的寫法

【分享】如何顯示 Debug Message

[分享] Visual Studio 遠端偵錯