3.4 DLL注入:全局消息钩子注入
SetWindowHookEx 是Windows系统的一个函数,可用于让一个应用程序安装全局钩子,但读者需要格外注意该方法安装的钩子会由操作系统注入到所有可执行进程内,虽然该注入方式可以用于绕过游戏保护实现注入,但由于其属于全局注入所以所有的进程都会受到影响,而如果想要解决这个问题,则需要在DllMain()也就是动态链接库开头位置进行判断,如果是我们所需操作的进程则执行该DLL模块内的功能,如果不是则自动跳过不执行任何操作即可实现指定进程的注入方式。
首先我们先来看一下该函数的原型定义;
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);
参数说明如下:
- idHook:钩子类型,标识了钩子函数要监视哪种事件。可以是整数值或预定义的常量值(如WH_MOUSE、WH_KEYBOARD、WH_SHELL等)。
- lpfn:钩子函数的地址。
- hMod:把钩子函数插入挂钩链中的应用程序的句柄,该参数通常被设置为包含钩子函数代码的DLL模块的句柄。
- dwThreadId:要设置钩子的线程标识符或进程标识符,如果为 0,则钩子通常与所有线程的输入消息联系起来。
在安装全局消息钩子时,读者需要在DLL中对外暴漏两个接口,其中SetHook()用于设置钩子,UnHook()则用于取消钩子,在DLL入口处,通过调用GetFristModuleName()我们可以判断当前进程是否为我们所需操作的进程,如果是则执行进程内的流程,如果不是则跳过执行,这个流程可以描述为如下样子,读者可自行将如下代码编译为DLL文件。
#include <iostream>
#include <TlHelp32.h>
#include <windows.h>
#include <tchar.h>
// 指定全局变量
HHOOK global_Hook;
// 判断是否是需要注入的进程
BOOL GetFristModuleName(DWORD Pid, LPCTSTR ExeName)
{
MODULEENTRY32 me32 = { 0 };
me32.dwSize = sizeof(MODULEENTRY32);
HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, Pid);
if (INVALID_HANDLE_VALUE != hModuleSnap)
{
// 先拿到自身进程名称
BOOL bRet = Module32First(hModuleSnap, &me32);
// 对比如果是需要注入进程,则返回真
if (!_tcsicmp(ExeName, (LPCTSTR)me32.szModule))
{
CloseHandle(hModuleSnap);
return TRUE;
}
CloseHandle(hModuleSnap);
return FALSE;
}
CloseHandle(hModuleSnap);
return FALSE;
}
// 获取自身DLL名称
char* GetMyDllName()
{
char szFileFullPath[MAX_PATH], szProcessName[MAX_PATH];
// 获取文件路径
GetModuleFileNameA(NULL, szFileFullPath, MAX_PATH);
int length = strlen(szFileFullPath);
// 从路径后面开始找\,即倒着找右斜杠
for (int i = length - 1; i >= 0; i--)
{
// 找到第一个\就可以马上获取进程名称了
if (szFileFullPath[i] == '\\')
{
i++;
// 结束符\0不能少 即i=length
for (int j = 0; i <= length; j++)
{
szProcessName[j] = szFileFullPath[i++];
}
break;
}
}
return szProcessName;
}
// 设置全局消息回调函数
LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return CallNextHookEx(global_Hook, nCode, wParam, lParam);
}
// 安装全局钩子 此处的 GetMyDllName()函数 可以是外部其他DLL,可将任意DLL进行注入
extern "C" __declspec(dllexport) void SetHook()
{
global_Hook = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandleA(GetMyDllName()), 0);
}
// 卸载全局钩子
extern "C" __declspec(dllexport) void UnHook()
{
if (global_Hook)
{
UnhookWindowsHookEx(global_Hook);
}
}
// DLL 主函数
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
// 当DLL被加载时触发,判断当前自身父进程是否为 lyshark.exe
BOOL flag = GetFristModuleName(GetCurrentProcessId(), TEXT("lyshark.exe"));
if (flag == TRUE)
{
MessageBoxA(0, "hello lyshark", 0, 0);
}
break;
}
case DLL_THREAD_ATTACH:
{
break;
}
case DLL_THREAD_DETACH:
{
break;
}
case DLL_PROCESS_DETACH:
{
// DLL卸载时自动清理
UnHook();
break;
}
default:
break;
}
return TRUE;
}
接着我们需要编写一个专门用来加载该DLL的程序,在调用DLL之前,我们需要通过LoadLibrary()将此模块加载到内存中,并通过GetProcAddress(hMod, "SetHook")获取到该模块的中SetHook函数的内存地址,最后直接调用SetHook()安装一个全局钩子,实现安装的代码流程如下所示;
#include <iostream>
#include <windows.h>
int main(int argc, char* argv[])
{
HMODULE hMod = LoadLibrary(TEXT("d://hook.dll"));
// 挂钩
typedef void(*pSetHook)(void);
pSetHook SetHook = (pSetHook)GetProcAddress(hMod, "SetHook");
SetHook();
while (1)
{
Sleep(1000);
}
// 卸载钩子
typedef BOOL(*pUnSetHook)(HHOOK);
pUnSetHook UnsetHook = (pUnSetHook)GetProcAddress(hMod, "UnHook");
pUnSetHook();
FreeLibrary(hMod);
return 0;
}
3.4 DLL注入:全局消息钩子注入的更多相关文章
- 安装全局消息钩子实现dll窗体程序注入
说明{ 通过设置全局消息钩子来实现dll注入,然后窗体有相关消息请求的时候就会自动加载注入dll, 然后在入口处做处理就可以了.注入方式简单很多,比代码注入和lsp等注入都简单,就不解释了. ...
- Dll注入:Windows消息钩子注入
SetWindowsHook() 是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之 ...
- Dll注入技术之消息钩子
转自:黑客反病毒 DLL注入技术之消息钩子注入 消息钩子注入原理是利用Windows 系统中SetWindowsHookEx()这个API,他可以拦截目标进程的消息到指定的DLL中导出的函数,利用这个 ...
- windows消息钩子注册底层机制浅析
标 题: [原创]消息钩子注册浅析 作 者: RootSuLe 时 间: 2011-06-18,23:10:34 链 接: http://bbs.pediy.com/showthread.php?t= ...
- windows消息钩子
1.消息钩子的概念: Windows应用程序是基于消息驱动的,不论什么线程仅仅要注冊窗体类都会有一个消息队列用于接收用户输入的消息和系统消息.为了拦截消息,Windows提出了钩子的概念.钩子(Hoo ...
- 常见注入手法第四讲,SetWindowsHookEx全局钩子注入.以及注入QQ32位实战.
常见注入手法第四讲,SetWindowsHookEx全局钩子注入.以及注入QQ32位实战. PS:上面是操作.最后是原理 一丶需要了解的API 使用全局钩子注入.我们需要了解几个WindowsAPI. ...
- Win32环境下代码注入与API钩子的实现(转)
本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...
- Win32环境下代码注入与API钩子的实现
本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- Dll注入:注册表注入
在系统中每一个进程加载User32.dll时,会受到DLL_PROCESS_ATTACH通知,当User32.dll对其进行处理时,会取得注册表键值HKEY_LOCAL_MACHINE\Softwar ...
随机推荐
- CMake + Protobuf 自动生成 cpp 文件(pb.h, pb.cc)
[Protoc]VS2019 (VS平台) 使用 CMake 编译安装.使用 Protobuf 库 本文介绍在 macOS 系统下 cmake 和 protobuf 一起使用的一种方式--使用 cma ...
- AcWing 每日一题 - 暑假
本篇解题记录题源来自 AcWing 的每日一题 · 暑假 补题链接:Here Week 1 星期四 AcWing 3761. 唯一最小数 利用 map 存出现过数的下标和次数即可 vector< ...
- 11、SpringBoot-mybatis-plus-druid多源数据事务
系列导航 springBoot项目打jar包 1.springboot工程新建(单模块) 2.springboot创建多模块工程 3.springboot连接数据库 4.SpringBoot连接数据库 ...
- <vue初体验> 基础知识 3、vue的计数器
系列导航 <vue初体验> 一. vue的引入和使用体验 <vue初体验> 二. vue的列表展示 <vue初体验> 三. vue的计数器 <vue初体验&g ...
- 深度学习(三)——Transforms的使用
一.Transforms的结构及用法 导入transforms from torchvision import transforms 作用:图片输入transforms后,可以得到一些预期的变换 1. ...
- [转帖]一文读懂 | 如何快速部署 OceanBase 开源版
2021-11-281398 版权 本文涉及的产品 云数据库 RDS MySQL Serverless,0.5-2RCU 50GB 推荐场景: 学生管理系统数据库设计搭建个人博客 立即试用 云防火墙, ...
- [转帖]Zookeeper集群搭建(3个节点为例)
Zookeeper集群搭建 1.说明 本文用的linux版本:centos6,准备3台centos6虚拟机,给他们安装zookeeper,每一台的安装过程相同,你也可以安装一台,然后克隆出另外两台.主 ...
- [转帖]15分钟了解TiDB
https://zhuanlan.zhihu.com/p/338947811 由于目前的项目把mysql换成了TiDb,所以特意来了解下tidb.其实也不能说换,由于tidb和mysql几乎完全兼容, ...
- [转帖]Redhat、CentOS添加静态路由的方法
https://www.diewufeiyang.com/post/1174.html 我们经常遇到需要在系统默认路由的基础上,额外添加静态路由的需求.为了使得下次系统启动这些静态路由依旧生效,我们可 ...
- Edge浏览器安装 wetab ChatGPT插件的简单步骤
Edge浏览器安装 wetab ChatGPT插件的简单步骤 背景 首先感谢 神通的 李诺帆老师, 之前一直使用. https://chat.jubianxingqiu.com/#/chat/1002 ...