HOOK 技術

在介紹 截獲系統消息鉤子 以前,這幾個函數是密切相關的:windows

SetWindowsHookEx() 介紹:函數

功能:將應用程序定義的掛鉤過程安裝到掛鉤鏈中。spa

函數原型:HHOOK SetWindowsHookEx(
                  int   idHook,  // 鉤子類型。
                  HOOKPROC  lpfn, // 指向掛鉤過程的指針。
                  HINSTANCE   hmod, // 包含 lpfn 參數指向的掛鉤過程的 DLL 的句柄。
                  DWORD   dwThreadId // 與掛鉤過程關聯的線程的標識符。若是爲 0,則爲全局鉤子。
                  );線程

返回值:若是函數成功, 則返回值是掛鉤過程的句柄。若是函數失敗, 返回值爲 NULL。指針

參數 idHook:調試

含義
WH_CALLWNDPROC 安裝的鉤子過程監視信息在系統將它們發送給目標窗口以前。
WH_CALLWNDPROCRET 安裝的鉤子過程監視信息在系統將它們發送給目標窗口以後。
WH_KEYBOARD 安裝監視擊鍵消息的掛鉤過程。
WH_MOUSE 安裝監視鼠標消息的掛鉤過程。
WH_GETMESSAGE 安裝用於監視將消息發送給消息隊列的掛鉤過程
WH_DEBUG 安裝用於調試其餘掛鉤過程的掛鉤過程。

 

CallNextHookEx() 介紹:code

功能:將掛鉤信息傳遞到當前掛鉤鏈中的下一個掛鉤過程。鉤子過程能夠在處理鉤子信息以前或以後調用此函數。blog

函數原型:LRESULT CallNextHookEx(
                  HHOOK  hhk,  // 一般被忽略。
                  int  nCode,  // 傳遞給當前掛鉤過程的掛鉤代碼。下一個掛鉤過程使用此代碼來肯定如何處理掛鉤信息。
                  WPARAM  wParam, // 傳遞給當前掛鉤過程的 wParam 值。此參數的含義取決於與當前掛鉤鏈關聯的掛鉤的類型。
                  LPARAM  lParam // 傳遞給當前掛鉤過程的 lParam 值。此參數的含義取決於與當前掛鉤鏈關聯的掛鉤的類型。
                  );隊列

返回值:此值由鏈中的下一個掛鉤過程返回。當前掛鉤過程還必須返回此值。返回值的含義取決於掛鉤類型。進程

 

UnhookWindowsHookEx() 介紹:

功能:移除由 SetWindowsHookEx 函數安裝在鉤子鏈中的掛鉤過程。

函數原型:BOOL UnhookWindowsHookEx(
                  HHOOK hhk // 要移除的鉤子的句柄。
                  );

返回值:非零表示成功,零表示失敗。

 

用戶自定義鉤子:(生成 dll 文件,並注入到相應的進程)

#include<windows.h>
#include<stdlib.h>
HANDLE hProc;
FARPROC pfMessageBoxA;
FARPROC pfMessageBoxW;
// 注意:自定義函數得和被 HOOK 函數的形式同樣,不然會發生異常。
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR sl, UINT u); int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR sl, UINT u); BYTE OldMessageBoxACode[5], NewMessageBoxACode[5]; BYTE OldMessageBoxWCode[5], NewMessageBoxWCode[5]; DWORD CurrentProcessId, dwOldProtect;; BOOL BHook = FALSE; BOOL Init(); void HookOn(); void HookOff(); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: Init(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: HookOff(); break; } return TRUE; } BOOL Init() { HMODULE hModule; DWORD Address; hModule = LoadLibraryA("user32.dll"); pfMessageBoxA = GetProcAddress(hModule, "MessageBoxA"); pfMessageBoxW = GetProcAddress(hModule, "MessageBoxW"); if (pfMessageBoxA == NULL || pfMessageBoxW == NULL) return FALSE; memcpy(OldMessageBoxACode,pfMessageBoxA,5); // 拷貝原來函數地址的前五個字節以備復原。 NewMessageBoxACode[0] = 0xe9; // 即 jmp 指令。 Address = (DWORD)MyMessageBoxA - (DWORD)pfMessageBoxA - 5; // 自定義函數與原函數的偏移地址。 memcpy(NewMessageBoxACode+1,&Address,4); memcpy(OldMessageBoxWCode,pfMessageBoxW,5); NewMessageBoxWCode[0] = 0xe9; Address = (DWORD)MyMessageBoxW - (DWORD)pfMessageBoxW - 5; memcpy(NewMessageBoxWCode+1,&Address,4); CurrentProcessId = GetCurrentProcessId(); HookOn(); return TRUE; } int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR pl, UINT u) { HookOff(); MessageBoxA(hWnd, "請從新安裝系統", "重要提示", MB_OK); HookOn(); return TRUE; } int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR pl, UINT u) { HookOff(); MessageBoxW(hWnd, L"請從新安裝系統", L"重要提示", MB_OK); HookOn(); return TRUE; } void HookOn() { hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, CurrentProcessId); // 打開進程,關閉內存保護,向內存空間前五個字節寫入 jmp 指令,最後打開進程保護。 VirtualProtectEx(hProc, pfMessageBoxA, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxA, NewMessageBoxACode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxA, 5, dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxW, NewMessageBoxWCode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxW, 5, dwOldProtect, &dwOldProtect); CloseHandle(hProc); BHook = TRUE; } void HookOff() { hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, CurrentProcessId); // 同理,只不過是復原內存指令。 VirtualProtectEx(hProc, pfMessageBoxA, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxA, OldMessageBoxACode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxA, 5, dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxW, OldMessageBoxWCode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxW, 5, dwOldProtect, &dwOldProtect); CloseHandle(hProc); BHook = FALSE; }

 注入後,以下圖所示:

相關文章
相關標籤/搜索