WIN32 消息Hook API
Posted 不会写代码的丝丽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WIN32 消息Hook API相关的知识,希望对你有一定的参考价值。
前言
在Win32
中存在一个消息机制,程序任何点击或者消息都会通过窗口过程下发,而微软提供SetWindowsHookEx
API来来允许我们进行相关事件监听,并且这个监听操作是优先于原始的函数调用的。
HHOOK SetWindowsHookExA(
int idHook,
HOOKPROC lpfn,
HINSTANCE hmod,
DWORD dwThreadId
);
微软把Hook分为两种:
- 线程钩子
- 全局钩子
线程钩子:HOOK自身程序消息
全局钩子:HOOK其他应用消息,内部机制是利用dll注入方式到其他程序。
Hook
系统全局的方式
线程钩子
一个小Demo:
HHOOK g_hHook = NULL;
//每个键盘按下和弹起都会回调
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
//文档说只能大于0才可以处理,否则传递事件
if (code > 0)
{
char msg[100];
sprintf_s(msg, "接收到的字符串 %c \\r\\n", wParam);
OutputDebugString(msg);
}
return CallNextHookEx(g_hHook, code, wParam, lParam);
}
//开启键盘hook
void CMFCApplication2Dlg::OnBnClickedButton1()
{
//调用微软函数提供Hook函数
g_hHook = SetWindowsHookEx(
WH_KEYBOARD,//这里设置你想Hook哪些消息,具体可参阅文档,WH_KEYBOARD表示键盘消息
KeyboardProc,//这个WH_KEYBOARD消息回调的地址
NULL,//如果仅仅Hook自己的应用固定传NULL即可
GetCurrentThreadId()//如果HOOk是自身应用传入当前线程即可。
);
if (g_hHook == NULL)
{
::AfxMessageBox("hook失败了");
}
}
void CMFCApplication2Dlg::OnBnClickedButton2()
{
//卸载hook
UnhookWindowsHookEx(g_hHook);
}
点击弹窗的安装Hook
按钮然后输入键盘看日志如下:
全局钩子
首先要定义dll库内容如下:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include<stdio.h>
HHOOK g_hHook = NULL;
//每个键盘按下和弹起都会回调
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
if (code > 0)
{
char msg[100];
sprintf_s(msg, "接收到的字符串 %c \\r\\n", wParam);
OutputDebugString(msg);
}
return CallNextHookEx(g_hHook, code, wParam, lParam);
}
//开启键盘hook
__declspec(dllexport) void myInsject()
{
//调用微软函数提供Hook函数
g_hHook = SetWindowsHookEx(
WH_KEYBOARD,//这里设置你想Hook哪些消息,具体可参阅文档,WH_KEYBOARD表示键盘消息
KeyboardProc,//这个WH_KEYBOARD消息回调的地址
GetModuleHandle("HookDll"),//如果需要hook全部进程,那么这里需要传入module句柄
0//全局hook传入0
);
if (g_hHook == NULL)
{
::MessageBox(NULL,"hook失败了",NULL,MB_OK);
}
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
然后我们在另一个进程调用这个库函数
__declspec(dllimport) void myInsject();
#pragma comment(lib,"..\\\\x64\\\\Debug\\\\HookDll.lib")
//开启键盘
void CMFCApplication2Dlg::OnBnClickedButton1()
{
myInsject();
}
此时你可以Hook到其他程序的消息比如有道词典等
以上是关于WIN32 消息Hook API的主要内容,如果未能解决你的问题,请参考以下文章