1. 程式人生 > >訊息鉤子注入示例

訊息鉤子注入示例

MessageHook.dll的h檔案:
#pragma  once
extern "C" _declspec(dllexport) bool OnHook();
extern "C" _declspec(dllexport) bool OffHook();

MessageHook.dll的cpp檔案:
#include "stdafx.h"
#include "MessageHook.h"
#include <stdio.h>
#include <stdlib.h>
extern HMODULE g_hModule;
HHOOK g_Hook = 0;
LRESULT CALLBACK MyKeyBoard(_In_ int    code, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
	// 判斷是否wParam與lParam都有鍵盤訊息,是的話則執行列印操作
	if (code == HC_ACTION){
		// 將256個虛擬鍵的狀態拷貝到指定的緩衝區中,如果成功則繼續
		BYTE KeyState[256] = { 0 };
		if (GetKeyboardState(KeyState)) {
			// 得到第16–23位,鍵盤虛擬碼
			LONG  KeyInfo = lParam;
			UINT  keyCode = (KeyInfo >> 16) & 0x00ff;
			WCHAR wKeyCode = 0;
			ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wKeyCode, 0);
			// 將其打印出來
			WCHAR szInfo[512] = { 0 };
			swprintf_s(szInfo, _countof(szInfo), L"Hook%c", (char)wKeyCode);
			OutputDebugString(szInfo);
			return 0;
		}
	}

	return CallNextHookEx(g_Hook, code, wParam, lParam);
}

//開啟訊息鉤子,攔截鍵盤訊息
bool OnHook()
{
	g_Hook = SetWindowsHookEx(WH_KEYBOARD, MyKeyBoard, g_hModule, 0);
	if (g_Hook == NULL)
	{
		return false;
	}
	return true;
}
//關閉訊息鉤子
bool OffHook()
{
	if (g_Hook != NULL)
	{
		UnhookWindowsHookEx(g_Hook);
		return true;
	}
	return false;
}

dllmain的cpp檔案:
#include "stdafx.h"
HMODULE g_hModule = 0;
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		g_hModule = hModule;
		break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

呼叫cpp檔案:
#include "stdafx.h"
#include <process.h>
#include "..\MessageHook\MessageHook.h"

#pragma comment(lib,"..\\debug\\MessageHook.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	OnHook();
	system("pause");
	OffHook();
	return 0;
}