WIN32 消息Hook API

Dear 丶 2022-10-09 03:20 349阅读 0赞

前言

Win32中存在一个消息机制,程序任何点击或者消息都会通过窗口过程下发,而微软提供SetWindowsHookExAPI来来允许我们进行相关事件监听,并且这个监听操作是优先于原始的函数调用的。

微软setwindowshookexa相关文档

  1. HHOOK SetWindowsHookExA(
  2. int idHook,
  3. HOOKPROC lpfn,
  4. HINSTANCE hmod,
  5. DWORD dwThreadId
  6. );

微软把Hook分为两种:

  1. 线程钩子
  2. 全局钩子

线程钩子:HOOK自身程序消息
全局钩子:HOOK其他应用消息,内部机制是利用dll注入方式到其他程序。

在这里插入图片描述
Hook系统全局的方式

线程钩子

一个小Demo:
在这里插入图片描述

  1. HHOOK g_hHook = NULL;
  2. //每个键盘按下和弹起都会回调
  3. LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
  4. //文档说只能大于0才可以处理,否则传递事件
  5. if (code > 0)
  6. {
  7. char msg[100];
  8. sprintf_s(msg, "接收到的字符串 %c \r\n", wParam);
  9. OutputDebugString(msg);
  10. }
  11. return CallNextHookEx(g_hHook, code, wParam, lParam);
  12. }
  13. //开启键盘hook
  14. void CMFCApplication2Dlg::OnBnClickedButton1()
  15. {
  16. //调用微软函数提供Hook函数
  17. g_hHook = SetWindowsHookEx(
  18. WH_KEYBOARD,//这里设置你想Hook哪些消息,具体可参阅文档,WH_KEYBOARD表示键盘消息
  19. KeyboardProc,//这个WH_KEYBOARD消息回调的地址
  20. NULL,//如果仅仅Hook自己的应用固定传NULL即可
  21. GetCurrentThreadId()//如果HOOk是自身应用传入当前线程即可。
  22. );
  23. if (g_hHook == NULL)
  24. {
  25. ::AfxMessageBox("hook失败了");
  26. }
  27. }
  28. void CMFCApplication2Dlg::OnBnClickedButton2()
  29. {
  30. //卸载hook
  31. UnhookWindowsHookEx(g_hHook);
  32. }

点击弹窗的安装Hook按钮然后输入键盘看日志如下:
在这里插入图片描述

全局钩子

首先要定义dll库内容如下:

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "pch.h"
  3. #include<stdio.h>
  4. HHOOK g_hHook = NULL;
  5. //每个键盘按下和弹起都会回调
  6. LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
  7. if (code > 0)
  8. {
  9. char msg[100];
  10. sprintf_s(msg, "接收到的字符串 %c \r\n", wParam);
  11. OutputDebugString(msg);
  12. }
  13. return CallNextHookEx(g_hHook, code, wParam, lParam);
  14. }
  15. //开启键盘hook
  16. __declspec(dllexport) void myInsject()
  17. {
  18. //调用微软函数提供Hook函数
  19. g_hHook = SetWindowsHookEx(
  20. WH_KEYBOARD,//这里设置你想Hook哪些消息,具体可参阅文档,WH_KEYBOARD表示键盘消息
  21. KeyboardProc,//这个WH_KEYBOARD消息回调的地址
  22. GetModuleHandle("HookDll"),//如果需要hook全部进程,那么这里需要传入module句柄
  23. 0//全局hook传入0
  24. );
  25. if (g_hHook == NULL)
  26. {
  27. ::MessageBox(NULL,"hook失败了",NULL,MB_OK);
  28. }
  29. }
  30. BOOL APIENTRY DllMain( HMODULE hModule,
  31. DWORD ul_reason_for_call,
  32. LPVOID lpReserved
  33. )
  34. {
  35. switch (ul_reason_for_call)
  36. {
  37. case DLL_PROCESS_ATTACH:
  38. case DLL_THREAD_ATTACH:
  39. case DLL_THREAD_DETACH:
  40. case DLL_PROCESS_DETACH:
  41. break;
  42. }
  43. return TRUE;
  44. }

然后我们在另一个进程调用这个库函数

  1. __declspec(dllimport) void myInsject();
  2. #pragma comment(lib,"..\\x64\\Debug\\HookDll.lib")
  3. //开启键盘
  4. void CMFCApplication2Dlg::OnBnClickedButton1()
  5. {
  6. myInsject();
  7. }

此时你可以Hook到其他程序的消息比如有道词典等

发表评论

表情:
评论列表 (有 0 条评论,349人围观)

还没有评论,来说两句吧...

相关阅读

    相关 WIN32 绘制消息

    在 `Win32`开发中会收到系统发来的各种消息,`WM_PAINT`表示希望程序开始绘制界面。 什么时候会发出`WM_PAINT`消息: > 当窗口存在一个无效的区域时(

    相关 WIN32 消息Hook API

    前言 在`Win32`中存在一个消息机制,程序任何点击或者消息都会通过窗口过程下发,而微软提供`SetWindowsHookEx`API来来允许我们进行相关事件监听,并且