windows 提供 SetWindowsHookEx 來對windows 的幾個服務進行hook操作

而Hook的項目被定義在 WinUser.h 如下:

  • WH_JOURNALRECORD  
  • WH_JOURNALPLAYBACK
  • WH_KEYBOARD       
  • WH_GETMESSAGE     
  • WH_CALLWNDPROC    
  • WH_CBT            
  • WH_SYSMSGFILTER   
  • WH_MOUSE
  • WH_KEYBOARD_LL
  • WH_MOUSE_LL          

其中只有WH_MOUSE 和 WH_KEYBOARD 可以直接撰寫EXE進行全域的監聽。

以下針對WH_KEYBOARD的案例進行說明:


以下程式碼為 利用 SetWindowsHookEx 對 鍵盤Hook 操作:

 

SetWindowsHookEx(WH_KEYBOARD_LL, HookMouseProcedure, hInst, HOOK_LISTEN_GLOBAL);
if (!_hook[IDX_HOOK_KEYBOARD])MessageBox(NULL, "Hook keyboard fails.", "Error", MB_OK);

 

以下為SetWindowsHookEx的函數原型:

SetWindowsHookExA(
    _In_ int idHook,
    _In_ HOOKPROC lpfn,
    _In_opt_ HINSTANCE hmod,
    _In_ DWORD dwThreadId);

 

首先SetWindowsHookEx 針對其參數進行說明:

1. 為要進行Hook的項目,以此案例為說明即是 WH_KEYBOARD_LL

2. Hook 處理函數(Function Point),當觸發Hook的目標事件時會呼叫該函數進行處理

3. hInstance 物件

4. 要Hook的目標 Thread Id ( 若設定為0代表全域Hook )


 

如果是進行 Keyboard Hook ,鍵盤的操作動作儲存在wParam之中,而實際被操作的按鈕資訊則被存放在lParam之中。

以下程式為HookMouseProcedure的處理函數內容:

 

LRESULT CALLBACK HookKeyboardProcedure(int nCode, WPARAM wParam, LPARAM lParam){
	PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;

	const char *info = NULL;
	HDC hdc = NULL;
	char text[100], pData[50], mData[50];

	if (nCode >= 0){
		switch (wParam)
		{
		case WM_KEYDOWN:info = "key down.";
			break;
		case WM_KEYUP:	info = "key up.";
			break;
		case WM_SYSKEYDOWN:		info = "system key down.";
			break;
		case WM_SYSKEYUP:	info = "system key up.";
			break;
		default:
			info = "W.O.";
			break;
		}

		ZeroMemory(text, sizeof(text));
		wsprintf(text, "Keyboard status¡G%10s,0x%x - key code: [%04d], scan code: [%04d]", info, wParam, p->vkCode, p->scanCode);
		hdc = GetDC(_hWnd);
		TextOut(hdc, 0, 40, text, strlen(text));

		ReleaseDC(_hWnd, hdc);
	}

	return CallNextHookEx(_hook[IDX_HOOK_KEYBOARD], nCode, wParam, lParam);
}

 

完整程式碼 ( 連結 )

arrow
arrow
    文章標籤
    win32 winapi c++ hook
    全站熱搜

    Lung-Yu,Tsai 發表在 痞客邦 留言(0) 人氣()