HOOK學習

HOOK學習

Hook技術又叫鉤子函數,在系統沒有調用該函數之前,鉤子程序就先獲取該消息,鉤子函數先得到控制權,這時鉤子函數既可以加工處理該函數的執行行爲,還可以強制結束消息的傳遞。

Hook分類

Hook分爲應用層(Ring3)Hook和內核層(Ring0)Hook,應用層Hook適用於x86和x64,而內核層Hook一般僅在x86平臺適用。

應用層Hook:

  • 消息Hook
  • 注入Hook
  • 調試Hook

消息Hook

技術原理

當發生鍵盤輸入事件時,WM_KEYDOWN消息被添加到[OS message queue]。

OS判斷哪個應用程序中發生了事件,然後從[OS message queue]取出消息,添加到相應應用程序的[application message queue]中

應用程序監視自身的[application message queue],發現新添加的WM_KEYDOWN消息後,調用相應的事件處理程序處理。

所以,只需要在[OS message queue]和[application message queue]之間安裝鉤子即可竊取鍵盤消息,並實現惡意操作。

Windows函數SetWindowsHookEx()用於設置消息Hook,只需要調用該API就能簡單地實現消息Hook。

SetWindowsHookEx(

WH_KEYBOARD, //鍵盤消息

KeyboardProc,//鉤子函數

hInstance,//鉤子函數所在DLL的handle

0 //該參數用於設定要Hook得線程ID,爲0時表示監視所有線程)

鉤子的類型,表示在什麼時機調用鉤子。

  • WH_CALLWNDPROC(4):安裝一個掛鉤處理過程,在系統消息發送至目標窗口處理過程之前,對該消息進行監視。WH_CALLWNDPROC鉤子監視SendMessage消息的傳遞,不管是系統內部調用的SendMessage()函數還是用戶進程中調用的SendMessage函數。

    SendMessage()把消息直接交給窗口過程WndProc()來處理,WndProc()處理完消息後SendMessage()函數才返回。

    如果設置了WH_CALLWNDPROC類型的鉤子,則當SendMessage()把消息交給WndProc時,在WndProc尚未執行前,系統調用CallWndProc鉤子函數,鉤子函數執行後才執行窗口過程WndProc。

    WH_CALLWNDPROC只能監視消息而不能修改

  • WH_CALLWNDPROCRET(12):安裝一個掛鉤處理過程,它對已被目標窗口處理過程處理過的消息進行監視。

  • WH_CBT(5):安裝一個掛鉤處理過程,接受對CBT應用程序有用的消息。

    在窗口激活、創建、銷燬、最小化、最大化、移動或改變尺寸的前一刻。系統會調用WH_CBT鉤子過程,鉤子過程的返回值決定了系統是允許或阻止這些操作。WB_CBT鉤子主要用於基於計算機的教學應用。

  • WH_DEBUG(9):安裝一個掛鉤處理過程以便對其它掛鉤處理過程進行調試。

    在調用與系統中的其它鉤子關聯的鉤子過程前,系統會調用WH_DEBUG鉤子過程。可以用這個鉤子來決定是否允許系統調用其它類型鉤子的鉤子函數。

  • WH_FOREGROUNDIDLE(11):安裝一個鉤子處理過程,該處理過程當應用程序的前臺線程即將進入空閒狀態時被調用,它有助於在空閒時間內執行低優先級的任務。

  • WH_GETMESSAGE(3):安裝一個鉤子處理過程對發送至消息隊列的消息進行監視。讓應用能夠監視將要被GetMessage或PeekMessage函數返回的消息。可以使用WH_GETMESSAGE鉤子來監視鼠標鍵盤輸入,以及其它投遞到消息隊列的消息。

  • WH_JOURNALPLAYBACK(1):安裝一個鉤子處理過程,對此前由WH_JOURNALRECORD掛鉤處理過程記錄的消息進行寄送。

  • WH_JOURNALRECORD(0):安裝一個鉤子處理過程,對寄送至系統消息隊列的輸入消息進行記錄。

  • WH_KEYBOARD(2):安裝一個鉤子處理過程對鍵盤消息進行監視。

  • WH_KEYBOARD_LL(13):此鉤子只能在Windows NT中被安裝,用來對底層的鍵盤輸入事件進行監視。

  • WH_MOUSE(7):安裝一個鉤子處理過程,對鼠標消息進行監視。

  • WH_MOUSE_LL(4):此鉤子只能安裝在Windows NT中,用來對底層的鼠標輸入事件進行監視。

  • WH_MSGFILTER(-1):監視由對話框、消息框、菜單欄、或滾動條中輸入事件引發的消息。

  • WH_SHELL(10):接收對外殼應用程序有用的通知。

核心函數:SetWindowsHookEx(),UnhookWindowsHookEx(),CallNextHookEx()

示例:

#include "msg.h"
#include<Windows.h>
#include<iostream>
using namespace std;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lParam);

//鉤子處理函數

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParan, LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParan, LPARAM lParam);

HHOOK mouseHook;
HHOOK keyHook;
HWND g_hwnd;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int cmdShow)
{
	TCHAR szAppClassName[] = TEXT("DunKaiEDU張三");

	WNDCLASS wc = { 0 };
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
	wc.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
	wc.hIcon = nullptr;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WindowProc;
	wc.lpszClassName = szAppClassName;
	wc.lpszMenuName = nullptr;
	wc.style = CS_HREDRAW | CS_VREDRAW;

	// 註冊窗口類
	RegisterClass(&wc);

	HWND hwnd = ::CreateWindow(szAppClassName, TEXT("福州成"), WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, nullptr, nullptr, hInstance, nullptr);
	::g_hwnd = hwnd;
	::ShowWindow(hwnd, SW_SHOW);
	::UpdateWindow(hwnd);

	//消息循壞
	//WIndows應用程序時通過消息機制驅動運行
	MSG msg = { 0 };
	while (GetMessage(&msg, nullptr, 0, 0)) 
	{
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}
	return 0;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CREATE://窗口創建消息
		//::mouseHook = SetWindowsHookEx(WH_MOUSE, MouseProc, nullptr, ::GetCurrentThreadId());
		::keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, nullptr, ::GetCurrentThreadId());
		break;
	case WM_LBUTTONDOWN://鼠標按下消息
	{
		MessageBox(hwnd, L"hell", L"sdf", MB_YESNO);
	}
	break;
	case WM_KEYDOWN:
		MessageBox(nullptr, L"sdf", L"dsfs", MB_OK);
		break;
	case WM_MOUSEMOVE:
	{
		//根據鼠標當前的位置
		int x = LOWORD(lParam);
		int y = HIWORD(lParam);
		TCHAR str[255] = { 0 };
		wsprintf(str, L"當前鼠標座標(%d,%d)", x, y);
		::SetWindowText(hwnd, str);
	}
		break;
	case WM_CLOSE:
		{
		
		}
		break;
	case WM_DESTROY:
		{
		PostQuitMessage(0);
		return 0;
		}
		break;
	}
	return ::DefWindowProc(hwnd, uMsg, wparam, lParam);
}
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	return ::CallNextHookEx(::mouseHook, nCode, wParam, lParam);//傳遞給下一個鉤子函數
}
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	if (wParam == VK_F2)
	{
		//卸載所有鉤子
		::UnhookWindowsHookEx(::keyHook);
		return 1;
	}
	else
	{
		return 1;
	}
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章