windows钩子、SetWindowsHookEx函数的使用

这篇具有很好参考价值的文章主要介绍了windows钩子、SetWindowsHookEx函数的使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Windows钩子简介

Windows钩子技术是一种Windows操作系统提供的机制,允许程序在特定事件发生时拦截并处理操作系统消息、事件或其他程序的输入和输出。钩子可以被用来监视和记录用户的操作、增加或修改某些功能,或者对某些事件作出反应,以此来实现各种自动化和定制化的需求。

钩子技术可以通过两种方式实现:全局钩子和局部钩子。全局钩子会拦截所有应用程序的消息和事件,而局部钩子则只拦截指定的应用程序或线程的消息和事件。

如果是全局钩子或者跨进程钩子,钩子的回调函数需要写在.dll动态链接库文件中,在使用SetWindowsHookEx函数为进程挂载钩子后,被挂载钩子的进程会去加载内存中的.dll文件,这时.dll文件中的函数可以共享该进程中的所有资源(dll注入原理)。

钩子是依附于线程的,而消息循环是线程处理消息的机制,因此必须在安装钩子的主程序所在的线程中创建消息循环。在安装钩子后,当Windows操作系统检测到需要被钩子处理的事件时,将会把事件信息封装成消息发送到安装钩子的主程序的消息队列中,安装钩子的主程序需要在消息循环中接收并处理这些消息,这样才能够完成钩子的处理过程。

此外,安装钩子的主程序需要运行在一个独立的线程中,这样可以防止钩子处理逻辑阻塞其他线程的执行。在这种情况下,线程的主循环必须调用 GetMessagePeekMessage 函数以等待消息的到来。因此,必须在主程序中创建一个消息循环以便及时接收和处理钩子的消息,从而完成钩子的功能。

微软Hook介绍


下面是一个跨进程钩子的举例

dll文件

#include <windows.h>
#include <iostream>

#define MY_API __declspec(dllexport)
extern "C" MY_API HOOKPROC getDllHookProc(VOID);

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;
}

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	// 所有小于零的是系统消息不做处理如果不放行系统消息会卡死
	if (nCode >= 0)
	{
		std::cout << "nCode:" << nCode << std::endl;
		/*
		return 1;
		如果返回一个非零的数则该消息无法被捕获
		*/
	}
	
	// 调用下一个钩子一定要调用下一个钩子否则会卡死
	return CallNextHookEx(NULL, nCode, wParam, lParam);
}

HOOKPROC getDllHookProc(VOID) {
	// 返回钩子回调函数
	return HookProc;
}

钩子回调函数通常有三个参数:

nCode:表示钩子代码,是一个整数值。如果小于0,则是系统消息,需要将钩子信息传递给下一个钩子,如果大于等于0,则可拦截。

wParam:表示一个消息或一个系统事件的参数,通常是一个虚拟键码或者一个句柄等。

lParam:表示一个消息或一个系统事件的参数,通常是一个指向 MSG 或 KBDLLHOOKSTRUCT 等结构体的指针。

这三个参数中,最重要的是 lParam 参数,因为它包含了所有的消息和事件信息,通常需要对其进行解析,以便获取具体的信息,lParam指向的结构体不确定,和SetWindowsHookEx设置的监听类型有关。


.exe文件

#include<Windows.h>
#include<iostream>

using namespace std;

typedef HOOKPROC(*func)(void);

int main() {

	HINSTANCE hDll; //DLL句柄
	// 加载dll
	hDll = LoadLibrary(L"testDll.dll");

	if (hDll != NULL)
	{
		// 这里通过窗口标题获取窗口句柄,注意FindWindow只能获取顶级窗口
		HWND hwnd = FindWindow(NULL, L"记事本");
		// 获取钩子回调函数
		func proc = (func)GetProcAddress(hDll, "getDllHookProc");
		// 安装钩子
		HHOOK hook = SetWindowsHookEx(WH_KEYBOARD, proc(), hDll, 
						GetWindowThreadProcessId(hwnd, NULL));
		
		// 一定要有消息循环不然消息会卡死
		MSG msg;
		while (GetMessage(&msg, NULL, 0, 0)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		
		// 卸载钩子
		UnhookWindowsHookEx(hook);

	}
	return 0;
}

SetWindowsHookEx函数
参数解释如下:

idHook: 要安装的钩子的类型。可以是下列值之一:
WH_CALLWNDPROC: 监听全局或局部的窗口消息,每次消息被发送到窗口过程时触发。
WH_CALLWNDPROCRET: 监听全局或局部的窗口消息,每次窗口过程处理完消息后触发。
WH_CBT: 监听全局或局部的窗口事件,如窗口创建、销毁、移动、大小调整等。
WH_KEYBOARD: 监听全局或局部的键盘输入事件。
WH_MOUSE: 监听全局或局部的鼠标事件。
WH_MSGFILTER: 监听全局或局部的窗口消息,包括按键、鼠标、定时器等。
WH_SHELL: 监听全局的 shell 事件。
WH_SYSMSGFILTER: 监听全局的窗口消息,包括键盘、鼠标、定时器等。
WH_FOREGROUNDIDLE: 监听全局的空闲时间。
WH_JOURNALRECORD: 监听全局的系统事件记录。
WH_JOURNALPLAYBACK: 监听全局的系统事件回放。
WH_DEBUG: 监听全局的调试事件。
WH_MOUSE_LL: 监听全局的鼠标事件,使用鼠标低级别钩子。
WH_KEYBOARD_LL: 监听全局的键盘事件,使用键盘低级别钩子。
等等

lpfn: 指向钩子处理函数的指针。钩子过程的参数和返回值的类型取决于 idHook 的值。

hMod: 包含钩子处理函数的 DLL 的句柄。如果钩子过程在钩子处理函数所在的进程中,则为 NULL。

dwThreadId: 线程标识符,标识接收钩子信息的线程。如果为 0,则钩子过程与所有线程共享。

SetWindowsHookEx 函数成功后返回钩子的句柄。可以使用返回的句柄来卸载钩子。

需要注意的是,钩子处理函数应该尽快完成处理,以免拖慢系统性能。此外,由于全局钩子会监视所有进程的事件,可能会产生安全风险,因此应该谨慎使用。

微软参考

消息循环

GetMessage():从消息队列中取得一个消息,如果队列为空,则等待直到有消息到来。

TranslateMessage():将一个虚拟键消息翻译为字符消息,并将其放回消息队列中。

DispatchMessage():将一个消息派发给相应的窗口过程函数或者钩子函数。

这三个函数通常一起使用,构成了一个消息循环。当应用程序启动后,会创建一个消息队列,然后调用 GetMessage() 函数等待消息到来,一旦消息到来,就将其交给 TranslateMessage() 函数进行翻译,最后交给 DispatchMessage() 函数进行处理。这样循环进行,直到 GetMessage() 函数返回 0,表示退出消息循环。在消息循环中,每个消息都会依次被处理,直到消息队列为空。


说在最后

安全申明:本人才疏学浅,若有任何谬误,欢迎指正

我的博客:ひかりの博客
csdn主页:csdn博客主页文章来源地址https://www.toymoban.com/news/detail-773741.html

到了这里,关于windows钩子、SetWindowsHookEx函数的使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 使用windows钩子(HOOK)实现DLL注入

    使用windows钩子(HOOK)实现DLL注入

    在Windows中,每个进程有自己私有的地址空间。当我们用指针来引用内存的时候,指针的值表示的是进程自己的地址空间中的一个内存地址。进程不能创建一个指针来引用属于其他进程的内存。因此,如果进程有一个缺陷会覆盖随机地址处的内存,那么这个缺陷不会影响到其他

    2024年02月04日
    浏览(10)
  • 使用Windows API实现键盘鼠标监控钩子

    使用Windows API实现键盘鼠标监控钩子

    本文介绍了如何使用Windows API中的SetWindowsHookEx和RegisterHotKey函数来监控键盘和鼠标活动。特别地,我们将详细讨论RegisterHotKey函数的用法,该函数允许开发者注册全局热键并定义这些热键触发时的行为。

    2024年02月04日
    浏览(11)
  • WindowsAPI——使用Windows API中键盘、鼠标监控钩子

    WindowsAPI——使用Windows API中键盘、鼠标监控钩子

    本节将介绍如何使用 Windows API 中的 SetWindowsHookEx 和 RegisterHotKey 函数来实现键盘鼠标的监控。这些函数可以用来设置全局钩子,通过对特定热键挂钩实现监控的效果,两者的区别在于 SetWindowsHookEx 函数可以对所有线程进行监控,包括其他进程中的线程,而 RegisterHotKey 函数只能

    2024年02月04日
    浏览(10)
  • Windows系统下使用PHPCS+PHPMD+GIT钩子

    Windows系统下使用PHPCS+PHPMD+GIT钩子

    前言 0.介绍 PHP_CodeSniffer php代码嗅探器 包含phpcs(php code standard 代码标准) phpcbf(php code beautify fix 代码美化修复) 是一个代码风格检测工具,着重 代码规范 它包含两类脚本,phpcs 和 phpcbf 1.安装 2.验证是否安装成功并查看帮助 3.使用 4.集成到git 4.1 新增钩子文件 在 .githooks目录下执

    2024年02月20日
    浏览(12)
  • 微信小程序中的所有生命周期钩子函数及其使用方法

    onLaunch(options) :小程序初始化时触发,全局只触发一次。 onShow(options) :小程序启动或从后台进入前台显示时触发。 onHide() :小程序从前台进入后台时触发。 onError(error) :小程序发生脚本错误或 API 调用失败时触发。 onLoad(options) :页面加载时触发,可以获取页面参数。 onS

    2024年02月09日
    浏览(17)
  • uni-app:切换页面刷新,返回上一页刷新(onShow钩子函数的使用)

    切换页面刷新:通过onShow()便可实现 返回上一页通过uni.navigateBack({delta: 1});实现 以返回上一页刷新为例 在A页面写入方法refreshHandler() 在A页面写入onLoad(),onShow()  onLoad(): 首次进入页面时执行的方法,这里直接引入refreshHandler() 可以直接查询到页面数据 onShow(): 进入页面执行

    2024年02月15日
    浏览(57)
  • git commit使用husky校验代码格式报错 因为没有将钩子 ‘.husky/pre-commit‘ 设置为可执行

    git commit使用husky校验代码格式报错 因为没有将钩子 ‘.husky/pre-commit‘ 设置为可执行

    系统 mac husky一直没什么问题,有一天发现给git commit 的时候 终端报错 解决办法 之后在git commit 发现,husky是可以工作但是还是有报错信息 这个错误是由于系统无法找到 ‘.husky/commit-msg’ 文件或目录导致的。通常,这是因为你的项目中缺少了 ‘.husky’ 目录或者该目录中缺少

    2024年04月09日
    浏览(46)
  • 学习笔记-mysql-各种函数的基本使用

    count , sum , min , max ,avg , group_concat() (1). if逻辑判断 (2). case when mysql 8.0之后增加的,也称为开窗函数 (1). 序号函数 row_number( ) --排序 1,2,3 rank( ) --排序 1,1,3 dense_rank( ) --排序 1,1,2 另外还有开窗聚合函数:sum avg min max (2). 分布函数 cume_dist() 用途:分组内小于、等于当前rank值的行数

    2024年01月20日
    浏览(12)
  • Ionic4 生命周期钩子函数和angular生命周期钩子函数介绍

    Ionic 4(以及之后的 Ionic 版本)使用了 Angular 生命周期钩子,因为 Ionic 是基于 Angular 构建的。因此,Ionic 4 中的生命周期与 Angular 组件生命周期非常相似。以下是一些常见的 Ionic 4 生命周期钩子: ionViewDidLoad : 在页面加载完成后触发。通常用于执行一次性的初始化任务。不推

    2024年02月07日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包