消息Hook
要想实现消息Hook需要使用到三个相关的Api
- SetWindowsHookEx // 设置钩子
- CallNextHookEx // 将钩子信息传递到当前钩子链中的下一个子程序
- UnhookWindowsHookEx // 卸载钩子
我们编写的消息钩子需要将设置钩子的函数写到dll里面,当钩住一个线程后,产生消息时,如果系统发现包含的钩子dll不在当前进程中,系统就会将这个钩子dll强行加载进去,这也算是一种注入的手段
HHOOK SetWindowsHookExW(
[in] int idHook, // 要Hook的消类型
[in] HOOKPROC lpfn, // 对应要Hook的消息类型的回调函数
[in] HINSTANCE hmod, // 当前dll的实例句柄
[in] DWORD dwThreadId // 要Hook的线程id(如果为0则表示挂钩所有线程消息)
);
主要功能dll部分
// hookdll.h
#pragma one
#include<iostream>
#include<Windows.h>
extern "C" _declspec(dllexport) BOOL __stdcall unInstallHook();
extern "C" _declspec(dllexport) BOOL __stdcall InstallHook();
===============================================================
// hookdll.cpp
#include "hookdll.h"
HINSTANCE g_hDllInstance = NULL;
HHOOK g_hKeyBoarHook = NULL;
// 键盘钩子
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
if (code == HC_ACTION) {
BYTE KeyState[256] = { 0 };
// GetKeyboardState 用于获取所有虚拟键的当前状态(按下或释放)
if (GetKeyboardState(KeyState)) {
LONG keyInfo = lParam;
// 获取键值
UINT keyCode = (keyInfo >> 16) & 0x00ff;
WCHAR wkeyCode = 0;
// 转换为Ascii字符
ToAscii((UINT)wParam,keyCode,KeyState,(LPWORD)&wkeyCode,NULL);
CHAR strInfo[24] = { 0 };
sprintf_s(strInfo,_countof(strInfo),"[消息Hook][按键:%c]",wkeyCode);
OutputDebugStringA(strInfo);
return 0;
}
}
// 把钩子传递给下一个钩子
return CallNextHookEx(g_hKeyBoarHook, code, wParam, lParam);
}
// 卸载钩子
BOOL unInstallHook() {
return UnhookWindowsHookEx(g_hKeyBoarHook);
}
BOOL InstallHook() {
g_hKeyBoarHook = SetWindowsHookEx(WH_KEYBOARD,KeyboardProc, g_hDllInstance,NULL);
if (g_hKeyBoarHook) {
return TRUE;
}
return FALSE;
}
BOOL DllMain(HINSTANCE hInstance,DWORD dwCallReason,LPVOID lpResverd) {
// 当前模块的实例句柄
switch (dwCallReason) {
case DLL_PROCESS_ATTACH:
g_hDllInstance = hInstance;
break;
}
return TRUE;
}
调用程序编写
#include<windows.h>
#include<iostream>
// 定义函数指针
typedef BOOL(*installHook)();
typedef BOOL(*unInstallHook)();
int main() {
HMODULE hModule = LoadLibraryW(L"消息Hook.dll");
installHook myInstallHook = (installHook)GetProcAddress(hModule, "InstallHook");
unInstallHook myUnInstallHook = (unInstallHook)GetProcAddress(hModule, "unInstallHook");
if (myInstallHook()) {
printf("Hook成功!");
}
system("pause");
myUnInstallHook();
return 0;
}
实现效果