Windows核心编程 HOOK

news2024/11/13 13:08:23

目录

HOOK概述

HOOK API

SetWindowsHookExA 函数(winuser.h)

UnhookWindowsHookEx 函数(winuser.h)

NextHookEx 函数(winuser.h)

局部钩子

全局钩子

为什么全局钩子需要用dll作为过程函数?


HOOK概述

本质:Windows消系统的消息过滤器。

全局钩子原理:将自己的dll注入到别的进程。并不是一开始就注入所有程序。

钩子种类:

  • 局部钩子:仅仅在当前进程下有效
  • 全局钩子:又称为系统钩子,在WIndows所有的进程都有效。

不用种类的钩子有自己的不同的回调函数。

钩子原理:回调函数,操作系统先发给我们,然后在发送给窗口。

系统给w2的消息;正常情况下我们w1是获取不到的,但是可以使用hook技术,将原来的消息先勾到我们(w1)这里,然后再回给系统,系统再重新转发给w2;这样w1就可以看到w2的消息;

HOOK作为注入的技术手段之一,可以利用hook技术,往对方的进程里面注入代码,获取进程相关的信息;作监控的东西,eg:spy++

HOOK API

SetWindowsHookExA 函数(winuser.h)

将应用程序定义的钩子子程安装到钩子链中。您将安装一个钩子子程来监视系统的某些类型的事件。这些事件或者与特定的线程相关联,或者与调用线程在同一桌面中的所有线程相关联。

WINUSERAPI HHOOK WINAPI SetWindowsHookEx(
     //钩子类型
    _In_ int idHook,
    
    //回调函数地址
    _In_ HOOKPROC lpfn,
    
    //实例句柄(包含有钩子函数)
    _In_opt_ HINSTANCE hmod,
    
    //线程ID,欲勾住的线程(为0则不指定,全局)
    _In_ DWORD dwThreadId);
    
  1. 参数1 int idHook:钩子类型 
  2. 参数2 HOOKPROC lpfn:回调函数,每个类型的钩子需匹配各自对应的回调函数
  3. 参数3 HINSTANCE hMod:实例句柄,局部钩子填NULL;全局钩子填dll的模块句柄(钩子的回调函数会填入dll)。使用 GetModuleHandle("Dll1")  获取
  4. 参数4 DWORD dwThreadId:线程ID,局部钩子填自己窗口的线程ID(UI主线程);全局钩子填0会钩系统范围内所有窗口的消息。

参数一:idHook的选项:

价值意义
WH_CALLWNDPROC安装一个钩子子程,在系统将消息发送到目标窗口过程之前监视消息。
WH_CALLWNDPROCRET安装一个钩子子程,在消息被目标窗口过程处理后监视消息。
WH CBT安装一个钩子子程来接收对CBT应用程序有用的通知。
WH_DEBUG安装一个钩子子程,用于调试其他钩子子程。
WH _FOREGROUNDIDLEz安装一个钩子子程,当应用程序的前台线程即将空闲时,将调用这个钩子子程。这个挂钩对于在空闲时间执行低优先级任务很有用。
WH_GETMESSAGE安装一个钩子子程来监视发送到消息队列的消息。
WH_JOURNALPLAYBACK安装一个钩子子程,该钩子子程发送WH日志
WH_JOURNALRECORD安装一个钩子子程,记录发送到系统消息队列的输入消息。这个钩子对于记录宏很有用。
WH_KEYBOARD安装一个钩子子程来监视击键消息。
WH_KEYBOARD_LL安装一个钩子子程来监视低级键盘输入事件。
WH_MOUSE安装一个钩子子程来监视鼠标消息。
WH_MOUSE_LL安装一个钩子子程来监视低级别的鼠标输入事件。
WH_MSGFILTER安装一个钩子子程,监视对话框、消息框、菜单或滚动条中的输入事件所生成的消息。
WH_SHELL安装一个钩子子程来接收对shell应用程序有用的通知。
WH_SYSMSGFILTER安装一个钩子子程,监视对话框、消息框、菜单或滚动条中的输入事件所生成的消息。钩子子程在与调用线程相同的桌面中为所有应用程序监视这些消息。

参数二:lpfn

类型:函数指针
回调函数,钩子拿到这些信息怎么给你,通过回调函数把信息交给你;需要注意,不同钩子的回调函数不一样,可以通过msdn查看;
钩子子程的指针。如果_dwThreadId_参数为零或指定由不同进程创建的线程的标识符,则_lpfn_参数必须指向DLL中的钩子子程。否则,_lpfn_可以指向与当前进程关联的代码中的钩子子程。

参数三:hmod

类型:实例句柄
局部钩子填写NULL;全局钩子填窗口所在模块的句柄,(全局程序会卡)DLL的句柄

参数四:dwThreadId

类型:双字节值
钩子子程要关联的线程的id,要钩的窗口所在的线程所在的id,每个进程的主线程id;

类型:钩子的句柄
如果函数成功,返回值是钩子子程的句柄。
如果函数失败,返回值为NULL。若要获取扩展的错误信息,请调用错误码.


 

UnhookWindowsHookEx 函数(winuser.h)

移除安装在钩子链中的钩子子程钩子函数功能。

BOOL UnhookWindowsHookEx(
  [in] HHOOK hhk
);

参数:[in] hhk
类型:钩子的句柄
要移除的钩子的句柄,SetWindowsHookExA的返回值。此参数是通过以前调用钩子函数

返回值:类型:布尔
如果函数成功,返回值是非零的。
如果函数失败,返回值为零。若要获取扩展的错误信息,请调用错误码

NextHookEx 函数(winuser.h)

将钩子信息传递给当前钩子链中的下一个钩子子程。钩子子程可以在处理钩子信息之前或之后调用这个函数

LRESULT CallNextHookEx(
  [in, optional] HHOOK  hhk,
  [in]           int    nCode,
  [in]           WPARAM wParam,
  [in]           LPARAM lParam
);

参数

[in, optional] hhk
类型:钩子的句柄
该参数被忽略。

[in] nCode
类型:(同Internationalorganizations)国际组织
传递给当前钩子子程的钩子代码。下一个钩子子程使用这个代码来决定如何处理钩子信息。

[in] wParam
类型:WPARAM
这_参数_传递给当前钩子子程的值。此参数的含义取决于与当前挂钩链相关联的挂钩类型。

[in] lParam
类型:参数
这_参数_传递给当前钩子子程的值。此参数的含义取决于与当前挂钩链相关联的挂钩类型。

返回值
类型:LRESULT
该值由链中的下一个钩子子程返回。当前钩子子程也必须返回这个值。返回值的含义取决于钩子的类型。

局部钩子

只能钩自己的窗口

// MFC基于对话框项目
HHOOK g_hHook;
// 键盘回调函数
LRESULT CALLBACK KeyboardProc(
	_In_ int    code,
	_In_ WPARAM wParam,
	_In_ LPARAM lParam
)
{
	// 特殊检查
	if (code < 0)
	{
		return	CallNextHookEx(g_hHook, code, wParam, lParam);
	}

	CString strFmt;
	strFmt.Format("HT:%c", wParam);
	OutputDebugString(strFmt);
	return	CallNextHookEx(g_hHook, code, wParam, lParam);
}

// 局部Hook 安装
void CHookTestDlg::OnBnClickedButton1()
{
	// 设置钩子
	g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, NULL, GetCurrentThreadId());
	if (g_hHook == NULL)
	{
		AfxMessageBox("局部钩子安装失败");
	}
}

// 局部Hook 卸载
void CHookTestDlg::OnBnClickedButton3()
{
	UnhookWindowsHookEx(g_hHook);	// 卸载钩子
}
执行结果

全局钩子

钩子的回调函数会填入DLL,以便按需注入

// 动态链接库项目 HookDll.cpp代码
HHOOK g_hHook;
LRESULT CALLBACK MyKeyboardProc(int code,       // hook code
    WPARAM wParam,  // virtual-key code
    LPARAM lParam   // keystroke-message information
)
{
    if (code < 0)
    {
        return CallNextHookEx(g_hHook, code, wParam, lParam);
    }

    char szBufff[MAXBYTE];
    wsprintf(szBufff, "HT:%c pid:%d", wParam, GetCurrentProcessId());
    OutputDebugString(szBufff);

    return CallNextHookEx(g_hHook, code, wParam, lParam);
}

__declspec(dllexport) BOOL InstallHook()
{
    g_hHook = SetWindowsHookEx(
        WH_KEYBOARD,
        MyKeyboardProc,
        GetModuleHandle("HookDll"),
        0);

    if (g_hHook != NULL)
    {
        return TRUE;
    }
    return FALSE;
}

__declspec(dllexport) VOID UnInstallHook()
{
    UnhookWindowsHookEx(g_hHook);
}
// 使用dll的MFC对话框项目代码
__declspec(dllimport) BOOL InstallHook();
__declspec(dllimport) VOID UnInstallHook();
#pragma comment(lib, "./Debug/HookDll.lib")
// 安装全局钩子
void CHookTestDlg::OnBnClickedButton2()
{
	if (!InstallHook())
	{
		AfxMessageBox("安装全局钩子失败");
	}
}
// 卸载全局钩子
void CHookTestDlg::OnBnClickedButton4()
{
	UnInstallHook();
}

或者填写def文件

为什么全局钩子需要用dll作为过程函数?

在别的程序运行过程函数监听消息。

全局钩子在安装钩子后,如果安装钩子的程序关闭,目标进程的dll也会自动卸载。

  1. 安装了同一时间的全局钩子和局部钩子,系统优先调用局部钩子,然后调用全局钩子。
  2. 安装多个钩子处理过程,形成钩子链。当钩子结束后赢吧钩子信息传递给下一个钩子函数。钩子链式栈结构,最后安装的,最先获得控制权。
  3. 全局钩子会消耗消息处理的时间,降低系统性能,所以全局钩子并不是全部注入到所有程序中,而是在发生消息事件的时候,才将dll注入到目标程序中安装钩子。
  4. 安装的钩子需要释放,安装钩子的主程序关闭,其他程序的钩子也会自动释放。
  5. 在键盘钩子回调函数中,修改wparam的值不会影响目标进程的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1273527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何提高3D建模技能?

无论是制作影视动画还是视频游戏&#xff0c;提高3D建模技能对于你的工作都至关重要的。那么如何能创建出精美的3D模型呢&#xff1f;本文给大家一些3D建模技能方面的建议。 3D建模通过专门的软件完成&#xff0c;涉及制作三维对象。这项技能在视频游戏开发、建筑、动画和产品…

电商物流信息查询难?一招解决

在当今的电商时代&#xff0c;物流信息查询一直是电商行业的痛点。很多电商商家在处理大量快递订单时&#xff0c;经常需要手动一个个查询快递信息&#xff0c;不仅耗时而且耗力。为了解决这个问题&#xff0c;我们可以使用固乔快递查询助手&#xff0c;它可以帮助我们快速批量…

redis单机版本安装

redis单机版本安装 1.redis单机版源码编译安装搭建(4.0示例) redis下载地址 https://redis.io/download redis源码编译 #!/bin/sh yum install -y wget gcc gcc-c make tar openssl openssl-devel cmakecd /usr/local/src wget http://download.redis.io/releases/redis-4…

什么是Anaconda?作用是?使用python必须要安装嘛?

一、什么是Anaconda以及其作用&#xff1f; 通俗来讲&#xff0c;Anaconda算是一个环境容器&#xff0c;也可以叫环境管理器。 作用&#xff1a;可以在Anaconda容器中为python项目创建不同的环境。在各个不同环境中可以安装不同版本的包并且各个环境互不影响。可以在使用不同项…

Maven的安装和使用

Maven是一个基于项目对象模型&#xff08;POM&#xff09;&#xff0c;可以管理项目构建、依赖管理、项目报告等的工具&#xff0c;使构建Java项目更容易。可以说Maven是一个项目管理和构建工具&#xff0c;它可以从管理项目的角度出发&#xff0c;将开发过程中的需求纳入进来&…

微信小程序 slider 翻转最大和最小值

微信小程序 slider 翻转最大和最小值 场景代码示例index.wxmlindex.jsutil.js 参考资料 场景 我想使用 slider 时最左边是 10 最右是 -10。 但是想当然的直接改成<slider min"10" max"-10" step"1" /> 并没用。 查了文档和社区也没有现成…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之存储管理(3)》(16)

《Linux操作系统原理分析之存储管理&#xff08;3&#xff09;》&#xff08;16&#xff09; 5 存储管理5.6 分段存储管理&#xff08;1&#xff09; 地址结构&#xff08;2&#xff09; 段表&#xff08;3&#xff09; 地址变换机构&#xff08;4&#xff09; 存储共享&#x…

自动化测试理论

一、初识自动化测试 概念 软件测试的定义 在规定的条件下对程序进行操作&#xff0c;以发现程序错误&#xff0c;衡量软件质量&#xff0c;并对其是否能满足设计要求进行评估的过程。 自动化测试的定义 把人对软件的测试行为转化为由机器执行测试行为的一种实践&#xff0…

芯片技术探索:了解构芯片的设计与制造之旅

芯片技术探索:了解构芯片的设计与制造之旅 一、引言 随着现代科技的飞速发展,芯片作为信息技术的核心,已经渗透到我们生活的方方面面。从智能手机、电视、汽车到医疗设备和工业控制系统,芯片在各个领域都发挥着至关重要的作用。然而,对于大多数人来说,芯片仍然是一个神秘…

【Flink进阶】-- Flink kubernetes operator 快速入门与实战

1、课程目录 2、课程链接 https://edu.csdn.net/course/detail/38831

发朋友圈的重要性和黄金时间

一、为什么发朋友圈要选择时间发&#xff1f; 1. 增加曝光率&#xff1a;通过定时自动发朋友圈&#xff0c;可以让更多的人看到你的动态。 2. 提高互动率&#xff1a;定时自动发朋友圈可以保持你的朋友圈活跃度&#xff0c;提高与粉丝的互动率。 3. 增强品牌形象&#xff1a…

系统设计面试指南之分布式任务调度

1 简介 任务是需要资源(CPU 时间、内存、存储、网络带宽等)在指定时间内完成的一段计算工作。 通过智能地将资源分配给任务以满足任务级和系统级目标的系统称为任务调度程序。 任务调度程序&#xff1a; 及时决定和分配资源给任务的过程称为任务调度。 当我们在 Facebook 发…

Golang语言基础之切片

概述 数组的长度是固定的并且数组长度属于类型的一部分&#xff0c;所以数组有很多的局限性 func arraySum(x [3]int) int{sum : 0for _, v : range x{sum sum v}return sum } 这个求和函数只能接受 [3]int 类型&#xff0c;其他的都不支持。 切片 切片&#xff08;Slic…

2023长三角(芜湖)人工智能数字生态峰会暨视觉算法大赛颁奖典礼邀您一同参与!

时光荏苒&#xff0c;科技飞速发展&#xff0c;人工智能正在以令人瞩目的速度改变着我们的生活。在这个数字科技的新时代&#xff0c;为促进长三角地区人工智能产业的蓬勃发展&#xff0c;助推数字经济的繁荣&#xff0c;2023长三角&#xff08;芜湖&#xff09;人工智能数字生…

php请求okx接口获取比特币价格数据、k线数据

php请求okx接口获取比特币价格数据 环境配置请求头、签名设置签名配置代理 全部代码 环境 我本地用的是thinkphp框架和guzzle 安装guzzle composer require guzzlehttp/guzzle 配置请求头、签名 我们需要准备api_key&#xff0c;secret_key&#xff0c;passphrase api_key…

软件测试的测试文档怎么编写?

在软件测试中的流程中&#xff0c;测试文档也是一个重要的流程&#xff0c;所以测试人员也需要学习测试文档的编写和阅读。 一定义&#xff1a; 测试文档&#xff08;TestingDocumentation&#xff09;记录和描述了整个测试流程&#xff0c;它是整个测试活动中非常重要的文件。…

预约系统源码解析:打造智能定制化预约服务的技术奇迹

在当今数字化时代&#xff0c;预约系统的重要性日益凸显&#xff0c;而预约系统源码的开放将为各行业带来更加灵活、智能的预约解决方案。本文将深入探讨预约系统源码的技术内幕&#xff0c;为开发者提供实用的代码示例&#xff0c;助力打造智能定制化的预约服务。 技术栈概览…

泛域名SSL证书是什么?泛域名SSL证书价格多少钱?

泛域名SSL证书是一种SSL证书类型&#xff0c;也被称为通配符SSL证书。SSL证书是保护网站数据传输安全及服务器身份可信的数字证书产品&#xff0c;通常绑定域名或IP&#xff0c;配置到网站服务器上。SSL证书根据保护域名数量及域名类型的不同&#xff0c;可以分为单域名SSL证书…

分布式系统:CAP 定理

欢迎来到分布式系统系列。在本文中&#xff0c;我们将学习并理解什么是 CAP 定理。CAP 代表一致性、可用性和分区容错性。当我们谈论CAP定理时&#xff0c;我们主要谈论的是分布式系统。首先&#xff0c;让我们了解一下什么是分布式系统。分布式系统是由运行在单台或多台机器上…

(免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐

摘 要 随着时代的不断更新&#xff0c;社会的不断变换&#xff0c;信息技术的飞速发展&#xff0c;计算机科技技术也逐步走向成熟。图书馆管理系统对于当今社会来说是必不可少的一个信息组成部分&#xff0c;它可以管理大量图书、大量读者、让读者有条不紊的进行借阅图书&#…