Windows操作系统是事件驱动的。事件被包装了消息发送给窗口,比如点击菜单,按钮,移动窗口等等
如:
1 按下键盘时,会产生一个键盘按下的消息,这个消息首先加入系统消息队列
2 操作系统从系统消息队列里面分发消息给具体的程序的消息队列
3 程序自身通过GetMessage获取消息,DispatchMessage分发消息,通过消息回调函数处理消息
HOOK就是从系统消息队列到应用程序消息队列之前,对消息进行处理,处理之后再扔给下一个消息钩子(HOOK)或者扔到应用程序的消息队列中。也就是说在系统消息队列分发消息给应用程序的过程中把消息勾住。
一个消息可以被多个钩子钩子,多个钩子称为钩子链
SetWindowsHookEx | 设置钩子 |
---|---|
CallNextHookEx | 将钩子信息传递到当前钩子链中的下一个子程序 |
UnhookWindowsHookEx | 卸载钩子 |
编写消息钩子需要将设置钩子的函数写到dll里面,当勾住一个线程后,产生消息时,假如系统发现包含钩子的dll不在本进程中,系统会将dll强行加载进去,这也是一种注入dll的手段
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()
直接把句柄传进去就好,这个函数比较简单
//.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
原文:https://www.cnblogs.com/Sna1lGo/p/14494362.html