windows 消息钩取

2024-03-18 03:10
文章标签 windows 消息 钩取

本文主要是介绍windows 消息钩取,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

windows 消息钩取

当键盘发生输入事件时,键盘消息钩子就会提前获得消息的内容、类型

并且可以对其做出修改

实现消息钩子的api:SetWindowsHookEx

HHOOK WINAPI SetWindowsHookEx(_In_  int    idHook,            设置钩子的类型.意思就是我要设置的钩子是什么钩子. 可以是监视窗口过程.可以是监视消息队列._In_ HOOKPROC lpfn,             根据钩子类型.设置不同的回调函数._In_ HINSTANCE hMod,            钩子设置的Dll实例句柄,就是DLL的句柄_In_ DWORD dwThreadId             设置钩子的线程ID. 如果为0 则设置为全局钩子.
);

KeyBoardProc(钩子过程函数)

LRESULT CALLBACK KeyboardProc( int code,WPARAM wParam,LPARAM lParam
);

参数说明

code [in]

类型: int

挂钩过程用来确定如何处理消息的代码。 如果 代码 小于零,则挂钩过程必须将消息传递给 CallNextHookEx 函数而不进行进一步处理,并应返回 CallNextHookEx 返回的值。 此参数的取值可为下列值之一:

含义
HC_ACTION 0WParamlParam 参数包含有关击键消息的信息。
HC_NOREMOVE 3WParamlParam 参数包含有关击键消息的信息,而击键消息尚未从消息队列中删除。 (名为 PeekMessage 函数的应用程序,指定 PM_NOREMOVE 标志。 )

wParam [in]

类型: WPARAM

生成击键消息的密钥的 虚拟键代码 。

lParam [in]

类型: LPARAM

重复次数、扫描代码、扩展键标志、上下文代码、上一个键状态标志和转换状态标志。 有关 lParam 参数的详细信息,请参阅 击键消息标志。 下表描述了此值的位数。

Bits说明
0-15重复计数。 值是用户按住该键时,击键重复的次数,即。
16-23扫描代码。 该值取决于 OEM。
24指示密钥是否为扩展键,如数字键盘上的函数键或键。 如果键是扩展键,则值为 1; 否则为。否则,为0。
25-28保留。
29上下文代码。 如果 ALT 键为关闭状态,则值为 1; 否则为。否则,为0。
30之前的键状态。 如果在发送消息之前键关闭,则值为 1; 否则为。如果键已启动,则为0。
31转换状态。 如果正在按下键,则该值为 0; 如果正在释放,则该值为1。

分析源代码

hookmain.exe

先加载keyhook.dll文件

然后调用hoolstart函数开始钩取

输入q终止

#include "stdio.h"
#include "conio.h"
#include "windows.h"#define    DEF_DLL_NAME        "KeyHook.dll"
#define    DEF_HOOKSTART        "HookStart"
#define    DEF_HOOKSTOP        "HookStop"typedef void (*PFN_HOOKSTART)();//这里是定义了两个函数指针。
typedef void (*PFN_HOOKSTOP)();void main()
{HMODULE            hDll = NULL;PFN_HOOKSTART    HookStart = NULL;PFN_HOOKSTOP    HookStop = NULL;char            ch = 0;hDll = LoadLibraryA(DEF_DLL_NAME);//加载KeyHook.dll,获得dll的句柄if (hDll == NULL){printf("LoadLibrary(%s) failed!!! [%d]", DEF_DLL_NAME, GetLastError());return;}HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);//利用GetProcAddress()获得HookStart的函数地址HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);//利用GetProcAddress()获得HookStop的函数地址HookStart();//开始钩取函数printf("press 'q' to quit!\n");while (_getch() != 'q');//遇到键盘输入q就退出HookStop();//退出钩取函数FreeLibrary(hDll);
}

KeyHook

调用导出函数HookStart时,SetWindowsHookEX函数就会将KeyBoardProc函数添加到键盘钩链

#include "stdio.h"
#include "windows.h"#define DEF_PROCESS_NAME		"notepad.exe"HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;
HWND g_hWnd = NULL;BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{switch( dwReason ){case DLL_PROCESS_ATTACH:g_hInstance = hinstDLL;break;case DLL_PROCESS_DETACH:break;	}return TRUE;
}LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{char szPath[MAX_PATH] = {0,};char *p = NULL;if( nCode >= 0 ){// bit 31 : 0 => key press, 1 => key releaseif( !(lParam & 0x80000000) )	//释放键盘按键时{GetModuleFileNameA(NULL, szPath, MAX_PATH);p = strrchr(szPath, '\\');// 比较当前进程名称,若为notepad.exe ,则消息不会传递给应用程序(或下一个钩子)if( !_stricmp(p + 1, DEF_PROCESS_NAME) )return 1;}}// 若非notepad.exe 则调用 CallNextHookEx() 函数,将消息传递给应用程序(或下一个钩子)return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}#ifdef __cplusplus
extern "C" {
#endif__declspec(dllexport) void HookStart(){g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);}__declspec(dllexport) void HookStop(){if( g_hHook ){UnhookWindowsHookEx(g_hHook);g_hHook = NULL;}}
#ifdef __cplusplus
}
#endif

调试分析

具体看书,这里列出主要内容

先调试HookMain.exe

通过od搜索字符串找到核心的代码部分并设置断点

在这里插入图片描述

继续调试,先经过401006处调用函数进入KeyHook函数EP

之后在40104B处调用ebx处函数:KeyHook中的HookStart函数,进入看看
在这里插入图片描述

接下来的四行push指令传入SetWindowsHookEXW的第4,3,2,1个参数,根据本文上面的参数说明,第二个参数:回调函数的地址

所以回调函数地址是10001020(钩子过程的地址)

再调试notepad.exe进程中的KeyHook.dll

拖入od f9 运行

然后在选项中设置:

在这里插入图片描述

这样当程序有dll载入时会自动暂停调试到dll的入口

接着运行HookMain.exe

在notepad中输入,没有显示,但od自动停在了dll 的 ep

在这里插入图片描述

接着找到刚才获得的HookStart函数地址10001020(KeyboardProc):
在这里插入图片描述

堆栈中还能看到KeyboardProc参数;
在这里插入图片描述

这篇关于windows 消息钩取的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/821003

相关文章

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起

Windows如何添加右键新建菜单

Windows如何添加右键新建菜单 文章目录 Windows如何添加右键新建菜单实验环境缘起以新建`.md`文件为例第一步第二步第三步 总结 实验环境 Windows7 缘起 因为我习惯用 Markdown 格式写文本,每次新建一个.txt后都要手动修改为.md,真的麻烦。如何在右键新建菜单中添加.md选项呢? 网上有很多方法,这些方法我都尝试了,要么太麻烦,要么不凑效

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

Windows下Nginx的安装及开机启动

1、将nginx-1.16.1.zip解压拷贝至D:\web\nginx目录下。 2、启动Nginx,两种方法: (1)直接双击nginx.exe,双击后一个黑色的弹窗一闪而过。 (2)打开cmd命令窗口,切换到nginx目录下,输入命令 nginx.exe 或者 start nginx ,回车即可。 3、检查nginx是否启动成功。 直接在浏览器地址栏输入网址 http://lo

Windows环境利用VS2022编译 libvpx 源码教程

libvpx libvpx 是一个开源的视频编码库,由 WebM 项目开发和维护,专门用于 VP8 和 VP9 视频编码格式的编解码处理。它支持高质量的视频压缩,广泛应用于视频会议、在线教育、视频直播服务等多种场景中。libvpx 的特点包括跨平台兼容性、硬件加速支持以及灵活的接口设计,使其可以轻松集成到各种应用程序中。 libvpx 的安装和配置过程相对简单,用户可以从官方网站下载源代码

C++实现俄罗斯方块(Windows控制台版)

C++实现俄罗斯方块(Windows控制台版) 在油管上看到一个使用C++控制台编写的俄罗斯方块小游戏,源代码200多行,B站上也有相关的讲解视频,非常不错,值得学习。 B站讲解视频地址为:【百万好评】国外技术大神C++游戏编程实战教程,油管580W收藏,新手10小时入门,并快速达到游戏开发能力(中英字幕) B站 CSDN博主千帐灯无此声还为此写了一篇博客:C++实现俄罗斯方块(源码+详解),讲

Windows下php扩展开发c++动态库

PHP扩展开发,从零了解到初步完成一个小项目,经过三天的仔细研究,现整理如下 一、需求介绍 PHP扩展开发,调用自己之前的c++动态库,完成功能 二、项目之前 系统:windows xp  开发工具:vs 2008 web环境:apache2.4  PHP5.3.29-VC9-ts-x86 aphach和PHP 环境之前已经搭建完成 PHP源码:去官网http://www.php.n

Java消息队列:RabbitMQ与Kafka的集成与应用

Java消息队列:RabbitMQ与Kafka的集成与应用 大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在现代的分布式系统中,消息队列是实现系统间通信、解耦和提高可扩展性的重要组件。RabbitMQ和Kafka是两个广泛使用的消息队列系统,它们各有特点和优势。本文将介绍如何在Java应用中集成RabbitMQ和Kafka,并展示它们的应用场景。 消息队

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系

Windows与linux中docker的安装与使用

windos中安装使用docker 下载Docker_Desktop 安装包进入docker官网下载Docker_Desktop: https://www.docker.com/ 启用wsl 我们搜索“启用或关闭Windows功能”,打开后勾选适用于Linux的Windows 子系统 Docker_Desktop设置 出现Docker Engine stopped的解决