有趣——windows键盘消息截获

理解下windows的消息机制:

1.发生键盘输入事件时,WM_KEYDOWN消息被添加到操作系统消息队列

2.OS判断哪个APP发生了事件,然后从系统消息队列取出消息分发到应用程序消息队列

3.APP监视自身的消息队列,发现新的消息,调用相应的事件处理程序

在OS消息队列和APP消息队列之间存在一条钩链,处于钩链之中的钩子比APP消息队列先看到相应信息

API函数SetWindowsHookEx()可实现消息钩取,钩子过程是由OS调用的回调函数,安装“钩子”时,“钩子”过程需要存在某个DLL内部

安装好钩子后,某个进程生成指定消息时,OS会将相应DLL强制注入进程中,然后调用“钩子”过程

dll源码

#include<stdio.h>
#include<Windows.h>

#define DEF_PROCESS_NAME "notepad++.exe"

HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
	switch (dwReason)
	{
	case DLL_PROCESS_ATTACH:
		g_hInstance = hinstDLL;
		break;	

	case DLL_PROCESS_DETACH:
		break;
	}
	return true;
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	char szPath[MAX_PATH] = { 0, };
	char* p = NULL;

	if (nCode=0)
	{
		if (!(lParam & 0x80000000))
		{
			GetModuleFileNameA(NULL, szPath, MAX_PATH);
			p = strrchr(szPath, \);
		}

		if (!_stricmp(p + 1, DEF_PROCESS_NAME))
			return 1;
	}

	return 1;//CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

#ifdef __cplusplus
extern "C" 
{
#endif
	__declspec(dllexport) void HookStart()
	{
		g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
	}

	__declspec(dllexport) void HookStop()
	{
		if (g_hHook)
		{
			UnhookWindowsHookEx(g_hHook);
			g_hHook = NULL;
		}
	}
#ifdef __cplusplus
}
#endif

主程序源码
#include<stdio.h>
#include<conio.h>
#include<Windows.h>

#define DEF_DLL_NAME "KeyHookDLL.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"

typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();

int main()
{
	HMODULE hDLL = NULL;
	PFN_HOOKSTART HookStart = NULL;
	PFN_HOOKSTOP HookStop = NULL;

	char ch = 0;
	hDLL = LoadLibraryA(DEF_DLL_NAME);
	//获取导出函数地址
	HookStart = (PFN_HOOKSTART)GetProcAddress(hDLL, DEF_HOOKSTART);
	HookStop = (PFN_HOOKSTOP)GetProcAddress(hDLL, DEF_HOOKSTOP);

	HookStart();

	printf("press q to quit!
");
	while (getchar() != q);

	HookStop();

	FreeLibrary(hDLL);
}

windows7下亲测通过,钩子为全局钩子,所有程序都无法接收键盘消息
经验分享 程序员 微信小程序 职场和发展