HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,   
HINSTANCE hMod,    
DWORD dwThreadId);

idHook: 钩子类型
lpfn:钩子过程的指针 ,也即拦截到指定系统消息后的预处理过程,定义在DLL中
hMod:应用程序实例的句柄 如果是全局钩子, hInstance是DLL句柄(DllMain中给的模块地址。就是包含HookProc的动态库加载地址。否则给0就可以了,即勾自己。
dwThreadId:要安装钩子的线程ID ,指定被监视的线程,如果明确指定了某个线程的ID就只监视该线程,此时的钩子即为线程钩子;如果该参数被设置为0,则表示此钩子为监视系统所有线程的全局钩子。

其中idHook参数可以取如下常量:
WH_CALLWNDPROC //窗口钩子,当系统向目标窗口发送消息时将触发此钩子
WH_CALLWNDPROCRET //窗口钩子,当窗口处理完消息后将触发此钩子
WH_CBT //当Windows激活、产生、释放(关闭)、最小化、最大化或改变窗口时都将触发此事件
WH_DEBUG //调试钩子
WH_GETMESSAGE //当往消息队列中增加一个消息时将触发此钩子
WH_JOURNALPLAYBACK //回放钩子,可以用于播放已记录的鼠标和键盘的操作
WH_JOURNALRECORD //记录钩子,可以用于记录鼠标和键盘的操作,木马程序可以使用此钩子窃取受控方在屏幕中敲入的密码
WH_KEYBOARD //当敲击键盘时将触发此钩子
WH_MOUSE //当有鼠标操作时将触发此钩子
WH_MSGFILTER //消息过滤钩子
WH_SHELL //Shell钩子
WH_SYSMSGFILTER //系统消息过滤钩子

原理:通过SetWindowsHookEx函数将DLL注入到进程的地址空间中,最后一个参数dwThreadId指向的是被注入进程内的某个线程ID。
(1) 进程A对线程dwThread挂键盘钩子
(2) 线程dwThreadId获取到的键盘消息会实现被钩子拦截
(3) 系统检查hMod指向的DLL是否已被载入到线程dwThreadId所在的进程地址空间中,若否,则载入。这时,假设DLL被载入到进程B
(4) 系统在进程B的地址空间中调用lpfn函数

*********************************************************************************

DLL部分

*********************************************************************************

LRESULT CALLBACK FunProc(
	int code,       // hook code
	WPARAM wParam,  // virtual-key code
	LPARAM lParam   // keystroke-message information
	)
{
	MessageBox(NULL,"KEY PRESS","hook inject",MB_OK);
	return CallNextHookEx(0,code,wParam,lParam);
}HHOOK g_HookHandle;
__declspec(dllexport) void SetHook()
{
	DWORD tid = 0;
	// 获取窗口句柄
	HWND gameh = FindWindow(NULL,"test.txt - 记事本");
	if (gameh == 0)
	{
		return;
	}
	// 获取创建这个窗口的线程
	tid = GetWindowThreadProcessId(gameh,NULL);
	// 安装钩子到指定线程 WH_KEYBOARD 键盘钩子
	g_HookHandle = SetWindowsHookEx(WH_KEYBOARD, FunProc, GetModuleHandle("HOOKInject.dll"),tid);
}__declspec(dllexport) void UnHook()  
{  
	UnhookWindowsHookEx(g_HookHandle);  
}

*********************************************************************************

EXE部分

*********************************************************************************

typedef void (*lpFun)();
int main()
{
	HINSTANCE hDll; //DLL句柄 
	lpFun SetHook;  //函数指针
	lpFun UnHook;   //函数指针
	hDll = LoadLibrary("..\\Debug\\HOOKInject.dll");
	if (hDll != NULL)
	{
		SetHook = (lpFun)GetProcAddress(hDll, "SetHook");
		UnHook = (lpFun)GetProcAddress(hDll, "UnHook");
	}	if (SetHook != NULL)
	{
		SetHook();
	}
	getchar();
	UnHook();
	if (hDll != NULL)
	{
		FreeLibrary(hDll);
	}	return 0;
}