1. 程式人生 > >鉤子程式設計(HOOK) 安裝系統全域性鉤子 (3)

鉤子程式設計(HOOK) 安裝系統全域性鉤子 (3)

摘要:全域性鉤子,鉤子一詞多用於計算機程式設計中,英文叫hook,指利用api來提前攔截並處理windows訊息的一種技術。如鍵盤鉤子,許多木馬都有這東西,監視你的鍵盤操作。全域性鉤子是系統鉤子的一種,當指定的一些訊息被系統中任何應用程式所處理時,這個鉤子就被呼叫。

目錄:

鉤子程式DLL

觸發DLL的客戶端

補充:動態載入DLL

---------------------------------

下面我們演示一下安裝全域性鉤子,遮蔽你的計算機滑鼠的所有操作~~~~

全域性鉤子,由兩部分組成:鉤子程式DLL觸發DLL的客戶端。其中,鉤子程式DLL是負責邏輯處理的那部分——也就是鉤子程式的主要執行體;由於DLL不能獨立執行,顧需要一個觸發DLL的客戶端,其實該客戶端就一個作用——呼叫鉤子程式DLL中的相關函式,讓DLL跑起來。下文將一步步講解如何對著兩部分進行開發。

第一部分:《鉤子程式DLL》

鉤子程式DLL是整個系統全域性鉤子的核心,所有的事物操作全部在DLL中完成。

Step 1:開啟VC6.0,選擇編寫DLL(動態連結庫,Win32 Dynamic-Link Library),將工程命名為GHookDll。其實就和建立C/C++專案工程一樣簡單,只不過這裡建立的是DLL工程。


Step 2:建立一個.cpp檔案,命名為hook.cpp (步驟和平時編寫win32 Console Application一樣),這裡面主要就是存放Hook的主要邏輯執行體。


Step 3:在hook.cpp裡面編寫如下鉤子事件~~~~

#include <windows.h>

HHOOK g_hMouse = NULL;

//滑鼠鉤子過程
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	return 1;
}
//安裝滑鼠鉤子過程的函式
void SetHook()
{
	g_hMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, GetModuleHandle("GHookDll"),0);
}

Step 4:再在本工程裡面新建一個hook.def檔案,(這個主要用來編碼,函式命名錯誤問題)


Step 5:在裡面編寫如下程式碼,

LIBRARY GHookDll
EXPORTS
SetHook  @2

此時,工程目錄應該是這樣...


Step 6:編譯->連結。(DLL是不能單獨執行的,所以點選連結之後,目錄下就會生成相應的DLL與Lib,如下文,不要企圖點選執行)


好了,DLL全域性鉤子已經編寫好了,關閉DLL工程。

第二部分:《觸發DLL的客戶端》

觸發DLL的客戶端,這裡簡單介紹使用MFC對話方塊應用程式來觸發DLL鉤子程式。

Step 1:重新開啟VC6.0,新建一個基於對話方塊的MFC應用程式(步驟,MFC AppWizard(exe) -> 基於對話方塊 -> 完成),命名為GHookEXE。


Step 2:將開始編寫好的GHookDll.dll與GHookDll.lib兩個檔案拷貝到當前目錄下面。注意是.cpp存放的同級目錄下,不要放置下Debug目錄下了,將會導致DLL無法找到。這裡需要說明,DLL與Lib的關係:DLL裡面放置的是具體的實現函式,Lib裡面是函式的清單——Lib也就是負責告訴程式設計者,DLL中有哪些方法可以呼叫,函式名為什麼,應該如何傳參等。


Step 3:如果不想動態載入,也可以手動配置一下,GHookDll.lib檔案。(點選工程->設定->連結,然後將GhookDll.lib的名字寫進去)。在實際開發中,一般也都是使用此種方式。(但下文也會介紹動態載入DLL的方法。)


Step 4:在BOOL CGlobalHookDlg::OnInitDialog()函式上面插入一行如下程式碼,宣告dll動態連結庫,宣告SetHook()函式之後,程式中就可以直接使用了。(但SetHook函式,必須在DLL中有具體的實現,同時實現名也必須一致)。

_declspec(dllimport) void SetHook();

Step 5:在OnInitDialog()函式中呼叫安裝鉤子函式 SetHook(),做了上述如此多鋪墊,就是為了呼叫SetHook函式。該函式也只有一個目的——觸發DLL鉤子程式,


Step 6:編譯->連結->執行。這時候,你發現不管你通過鍵盤ALT+TAB切換到哪個介面,你的滑鼠都用不了。

如果你要退出:請切換回程式切面(用ALT+TAB切換),然後按一下 回車鍵。(這時候響應了ID_OK按鈕,自動呼叫關閉視窗,這時候你發現滑鼠又能用了)。可能有些時候,上述方式並不能退出,這時候你應該按CTRL+ALT+DEL撥出工作管理員,使用上下左右方向鍵選擇當前執行的exe客戶端,最後CTRL+E——終止掉程式。

文章閱讀到這裡,其實已經結束了,下文知識做一些知識點的擴充套件、補充。

《補充:關於DLL動態載入》

如果你需要實現DLL動態載入,而不是像上面那樣,在連結裡面新增 GHookDll.lib 檔案。那麼就有必要說明一下動態載入DLL了。

Step 1:將GHookDll.dll 和 GHookDll.lib拷貝到客戶端目錄下面。

Step 2:將 _declspec(dllimport) void SetHook();  這行程式碼註釋掉。

Step 3:在OnInitDialog()函式裡面新增如下程式碼(實現動態載入DLL)...

HINSTANCE hInst;
hInst = LoadLibrary("GHookDLL.dll");
typedef void (*SetHookProc)();
SetHookProc SetHook = (SetHookProc)GetProcAddress(hInst,"SetHook");

下面是新增位置截圖,