任務定義:進程DIPS和進程Explorer,前者使用視窗HOOK將DIPSLib.dll注入到後者的進程地址空間中,於是兩個進程中都有同一個DIPSLib.dll,因此可以讓兩個dll共用一些資料,從而方便以DIPS作為用戶端,以注入到Explorer的DIPSLib.dll為伺服器端進行通訊,完成對Explorer的一些操作。
具體分析:
DIPS中的函數:_tWinMain();Dlg_Proc();Dlg_OnCommand();Dlg_OnInitDialog();
DIPSLib中的函數:DllMain();SetDIPSHook();GetMsgProc();Dlg_OnClose();SaveListViewItemPositions(); RestoreListViewItemPositions();Dlg_Proc();
DIPSLib中的共用資料:g_hhook(標識設定在Explorer中的鉤子);g_dwThreadIdDIPS(標識設定HOOK的線程,也就是DIPS中的主線程);全域資料:g_hinstDll(標識當前dll執行個體,在DIPS或者在Explorer)
流程::_tWinMain()中建立DIPS的主視窗,然後根據使用者的選擇記錄SAVE或者RESTORE狀態,接著找到Explorer的目標子視窗ListView的視窗控制代碼hwndLV,繼而由此控制代碼找到建立它的線程ID,線程ID在系統中是唯一的,可以對此控制代碼設定HOOK,調用SetDIPSHook()函數(*這個函數會最終使得伺服器建立好),此時調用的是映射在DIPS地址空間中的dll中的函數,此函數在內部先把當前線程ID儲存到g_dwThreadIdDIPS,以便目標進程Explorer中的dll可以和當前進程通訊,然後對調用SetWindowsHookEx真正對前面所說的目標線程ID設定HOOK,並向它發送一個訊息,引起系統調用目標線程的HOOK函數,在這裡是GetMsgProc(),此函數如果是第一次被調用的話,會建立一個隱藏的視窗,這個視窗作為伺服器來和用戶端(也就是DIPS)通訊,然後發送一個資訊給用戶端(根據g_dwThreadIdDIPS找到用戶端線程),告訴用戶端伺服器已經準備好;當伺服器準備好了,回到前面SetDIPSHook()這個位置,此函數返回,客服端接收到伺服器剛才發送的資訊(本來伺服器在SetDIPSHook()之後會調用GetMessage()進入阻塞),於是被喚醒,然後找到隱藏的視窗(也就是伺服器視窗),根據使用者儲存的SAVE或者RESTORE狀態向伺服器發送相應的訊息,伺服器根據訊息調用自己的對話方塊處理函數Dlg_Proc(),如果是SAVE則調用SaveListViewItemPositions(),如果是RESTORE則調用RestoreListViewItemPositions();最後用戶端發送CLOSE資訊讓伺服器視窗關閉,然後unhook,這裡要注意的是unhook是通過調用SetDIPSHook(),並且參數為0,雖然是調用自己進程中的SetDIPSHook(),但是由於和目標進程中dll共用了g_hhook,因此可以真正調用UnhookWindowsHookEx()來unhook這個hook。
精華:此程式最大的精華是兩個共用變數以及幾個標識變數的使用,值得借鑒。