SetWindowsHook() 是Windows消息處理機制的一個平臺,應用程序能夠在上面設置子程以監視指定窗口的某種消息,並且所監視的窗口能夠是其餘進程所建立的。當消息到達後,在目標窗口處理函數以前處理它。ios
鉤子機制容許應用程序截獲處理window消息或特定事件。ide
HHOOK WINAPI SetWindowsHookEx( __in int idHook, \\鉤子類型 __in HOOKPROC lpfn, \\回調函數地址 __in HINSTANCE hMod, \\實例句柄 __in DWORD dwThreadId); \\線程ID
使用API函數SetWindowsHookEx()把一個應用程序定義的鉤子子程安裝到鉤子鏈表中。 SetWindowsHookEx函數老是在Hook鏈的開頭安裝Hook子程。當指定類型的Hook監視的事件發生時,系統就調用與這個Hook關聯的 Hook鏈的開頭的Hook子程。每個Hook鏈中的Hook子程都決定是否把這個事件傳遞到下一個Hook子程。Hook子程傳遞事件到下一個 Hook子程須要調用CallNextHookEx函數。函數
SetWindowsHookEx()函數的最後一個參數決定了此鉤子是系統鉤子仍是線程鉤子。佈局
#include "stdafx.h" #include <Windows.h> #include<TlHelp32.h> #include<iostream> using namespace std; BOOL InjectDllBySetWindowsHook(ULONG32 ulTargetProcessID); DWORD getThreadID(ULONG32 ulTargetProcessID); int main() { ULONG32 ulTargetProcessID; cout << "請輸入目標進程ID:"; cin >> ulTargetProcessID; if (!InjectDllBySetWindowsHook(ulTargetProcessID)) { cout << "Set Hook Unsuccess!\r\n" << endl; return 0; } cout << "Inject Success!\r\n" << endl; return 0; return 0; } BOOL InjectDllBySetWindowsHook(ULONG32 ulTargetProcessID) { HANDLE TargetProcessHandle = NULL; TargetProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ulTargetProcessID); if (NULL == TargetProcessHandle) { printf("Couldn't get Target Process Handle\r\n"); return FALSE; } HMODULE DllModule = LoadLibrary(L"Dll.dll"); if (DllModule == NULL) { printf("cannt find dll\r\n"); return FALSE; } //獲取Dll中導出的函數的地址 HOOKPROC Sub_1Address = NULL; Sub_1Address = (HOOKPROC)GetProcAddress(DllModule, "MyMessageProcess"); if (Sub_1Address == NULL) { printf("cannt found MyMessageProcess"); return FALSE; } DWORD ThreadID = getThreadID(ulTargetProcessID); HHOOK Handle = SetWindowsHookEx(WH_KEYBOARD, Sub_1Address, DllModule, ThreadID); if (Handle == NULL) { printf("cannt hook\r\n"); return FALSE; } printf("hook success\r\n"); getchar(); getchar(); getchar(); UnhookWindowsHookEx(Handle); FreeLibrary(DllModule); } DWORD getThreadID(ULONG32 ulTargetProcessID) { HANDLE Handle = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (Handle != INVALID_HANDLE_VALUE) { THREADENTRY32 te; te.dwSize = sizeof(te); if (Thread32First(Handle, &te)) { do { if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) { if (te.th32OwnerProcessID == ulTargetProcessID) { HANDLE hThread = OpenThread(READ_CONTROL, FALSE, te.th32ThreadID); if (!hThread) { printf("Couldn't get thread handle\r\n"); } else { return te.th32ThreadID; } } } } while (Thread32Next(Handle, &te)); } } CloseHandle(Handle); return (DWORD)0; }
Dll部分:spa
#pragma data_seg(SHARD_SEG_NAME) static HHOOK g_hHook; #pragma data_seg() BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { MessageBox(NULL, L"Inject Success!", L"1", 0); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } extern "C" __declspec(dllexport)LRESULT MyMessageProcess(int Code, WPARAM wParam, LPARAM lParam) { // //你本身對消息的處理 // MessageBox(NULL, L"GetMessage!", L"Message", 0); return CallNextHookEx(g_hHook, Code, wParam, lParam); }
可參考百度百科線程