Windows核心编程 HOOK

目录

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 codeWPARAM wParam,  // virtual-key codeLPARAM 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.mzph.cn/news/185098.shtml

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

相关文章

嵌入式常见的几种接口

嵌入式开发中&#xff0c;常见的外设通信接口/协议有SPI&#xff0c;I2C&#xff0c;UART三种&#xff0c;本文先分三个部分对SPI&#xff0c;I2C&#xff0c;UART进行介绍&#xff0c;最后对这三种协议进行比较。 1 SPI 1.1 SPI的简介 SPI&#xff08;Serial Peripheral …

SAP S/4HANA 中的业务合作伙伴概念

原文地址&#xff1a;https://blogs.sap.com/2023/07/16/business-partner-concept-in-sap-s-4hana/ 1.1 什么是业务合作伙伴&#xff1f; 在 SAP S/4 HANA 中&#xff0c;业务合作伙伴是维护业务合作伙伴、客户和供应商&#xff08;以前称为供应商&#xff09;主数据的主…

超级利器!Postman自动化接口测试让你提升测试效率,节省宝贵时间!

Postman自动化接口测试 该篇文章针对已经掌握 Postman 基本用法的读者&#xff0c;即对接口相关概念有一定了解、已经会使用 Postman 进行模拟请求的操作。 当前环境&#xff1a; Window 7 - 64 Postman 版本&#xff08;免费版&#xff09;&#xff1a;Chrome App v5.5.3 …

Airtest进阶使用篇!提高脚本稳定性 + 批量运行脚本!

一、背景 今天彭于晏为大家分享Airtest进阶使用篇&#xff0c;主要包含两块的内容&#xff1a; 提高脚本稳定性批量运行脚本生成测试报告 二、提高脚本稳定性 1、添加全局配置: #全局设置 ST.FIND_TIMEOUT10 #设置隐式等待时长,默认识别图片时间是30秒&#xff0c;可改为…

C++:C++11新特性---右值引用

文章目录 初始化方式显示查看类型initializer_listdecltype左值引用和右值引用move左右值引用的场景 万能引用和完美转发 本篇总结C11新特性 初始化方式 C11对参数列表的初始化有了更明确的定义&#xff0c;可以这样进行定义 // 列表初始化 void test1() {// 旧版本int x 0…

免费WordPress站群插件-批量管理站群的免费软件

WordPress站群插件&#xff1a;让文章管理如丝般顺滑 在众多网站建设工具中&#xff0c;WordPress一直以其简便易用、丰富的插件生态而备受青睐。对于站群管理者而言&#xff0c;如何高效地更新、发布和推送文章是一项不可忽视的任务。本文将专注分享一款WordPress站群插件&am…

Audacity降噪消除视频中杂音

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

QListWidget中自定义widget大小自适应

背景&#xff1a; QListWidget中的item&#xff0c;可以添加自定义的widget。 但是怎么去调整widget的大小呢&#xff1f; 参考&#xff1a;QT QListWidget的添加与删除&#xff0c;滚动条显示或隐藏&#xff0c;判断是否滑到顶部或底部&#xff0c;并使QListWidgetItem自适…

Node.js【文件系统模块、路径模块 、连接 MySQL、nodemon、操作 MySQL】(三)-全面详解(学习总结---从入门到深化)

目录 Node.js 文件系统模块&#xff08;二&#xff09; Node.js 文件系统模块&#xff08;三&#xff09; Node.js 文件系统模块&#xff08;四&#xff09; Node.js 路径模块 Node.js 连接 MySQL Node.js nodemon Node.js 操作 MySQL Node.js 应用 Node.js 文件系统模块…

每日汇评:在美国通胀数据前,黄金多头变得谨慎起来

黄金价格在连续五天上涨后&#xff0c;周四早间稍作休息&#xff1b; 在个人消费支出通胀数据公布前&#xff0c;美元和美债收益率巩固了下行空间&#xff1b; 超买状况可能限制金价的上行空间&#xff0c;因为月底的资金流动可能占主导地位&#xff1b; 昨日亚盘交易时段&…

子类拷贝构造函数会调用父类拷贝构造函数吗?

一. 编译器提供的默认子类拷贝构造函数会调用父类拷贝构造函数。 #include <iostream> #include <string> using namespace std;class Parent { public:Parent(string home_address "中国") : m_home_address(home_address) {cout << "调用…

学习笔记小结

redis-cluster集群 redis3.0引入的分布式存储方案 集群由多个node节点组成&#xff0c;redis数据分布在这些节点当中。 在集群之中分为主节点和从节点 集群模式当中&#xff0c;主从一一对应&#xff0c;数据的写入和读取与主从模式一样&#xff0c;主负责写&#xff0c;从…

C陷阱与缺陷——第3章 语义陷阱

1. 指针和数组 C语言中只有一维数组&#xff0c;而且数组的大小必须在编译器就作为一个常数确定下来&#xff0c;然而在C语言中数组的元素可以是任何类型的对象&#xff0c;当然也可以是另外的一个数组&#xff0c;这样&#xff0c;要仿真出一个多维数组就不是难事。 对于一个…

Mac电脑版程序创建工具 VMware InstallBuilder Enterprise mac最新

VMware InstallBuilder Enterprise 是一款功能强大、操作简单、跨平台支持的软件安装和部署工具&#xff0c;可以让开发者更加高效地创建和部署软件&#xff0c;并提供了丰富的功能和工具&#xff0c;适用于不同的用户需求和场景。 内置调试器 轻松排除应用程序安装过程中的故…

样品实验EPONEX1510氢化双酚A环氧树脂TDS说明书

样品实验EPONEX1510氢化双酚A环氧树脂TDS说明书 200克 500克 1KG/瓶

使用Docker安装Jenkins,解决插件安装失败,版本太低等问题

如果已经遇到插件安装部分失败&#xff0c;Jenkins版本太低&#xff0c;又要换什么清华镜像地址&#xff0c;不要犹豫&#xff0c;直接以下步骤卸载重装就好了 开始安装 yum 更新到最新 yum update到Jenkins官网查找最新的LST版本 最后的版本号一定要带&#xff0c;指定下载具…

深入探索Maven:优雅构建Java项目的新方式(二)

Meven高级 1&#xff0c;属性1.1 属性1.1.1 问题分析1.1.2 解决步骤步骤1:父工程中定义属性步骤2:修改依赖的version 1.2 配置文件加载属性步骤1:父工程定义属性步骤2:jdbc.properties文件中引用属性步骤3:设置maven过滤文件范围步骤4:测试是否生效 1.3 版本管理 2&#xff0c;…

Sass 安装

文章目录 前言SASS的系统要求安装Ruby例子后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Sass和Less &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&…

Informer辅助笔记:data/dataloader.py

以WTH为例 import os import numpy as np import pandas as pdimport torch from torch.utils.data import Dataset, DataLoader # from sklearn.preprocessing import StandardScalerfrom utils.tools import StandardScaler from utils.timefeatures import time_featuresim…

什么是光模块光模块看我这张就够啦!

1、什么是光模块 信号在光网络中传输时&#xff0c;必须进行光/电转换。光模块就是专门在光网络中完成光/电转换工作的部件。光模块的外观结构如图1所示&#xff0c;简单的来说&#xff0c;双绞线最大传输距离是100米&#xff0c;用的是电信号&#xff0c;那如果说传输距离超过…