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 ...
随机推荐
- 生成学习全景:从基础理论到GANs技术实战
本文全面探讨了生成学习的理论与实践,包括对生成学习与判别学习的比较.详细解析GANs.VAEs及自回归模型的工作原理与结构,并通过实战案例展示了GAN模型在PyTorch中的实现. 关注TechLea ...
- Codeforces Round #717 (Div. 2) 个人题解 A~C (A思維,B位運算,C背包DP)
1516A. Tit for Tat 題意: 給定大小為 \(n\) 的數組和可操作次數 \(k\) , 每次操作都選定兩個數(如果 \(1 \le a_i\) ),使第一個數 - \(1\) ,另一 ...
- C#对字符串进行加密解密
首先上效果图 加解密接口 internal string ToEncrypt(string encryptKey, string str) { try { byte[] P_byte_key = // ...
- Avalonia使用默认弹窗
Avalonia使用默认弹窗 在Avalonia中使用官方默认弹窗WindowNotificationManager Views\MainWindow.axaml相关代码 <Window xml ...
- 神经网络优化篇:详解局部最优的问题(The problem of local optima)
局部最优的问题 在深度学习研究早期,人们总是担心优化算法会困在极差的局部最优,不过随着深度学习理论不断发展,对局部最优的理解也发生了改变.向展示一下现在怎么看待局部最优以及深度学习中的优化问题. 这是 ...
- 利用工具查看JMS微服务在线情况,可直接调用远程方法,也可自动生成微服务客户端代码
链接:https://cccscls-my.sharepoint.com/personal/jack_mutc_ca/_layouts/15/onedrive.aspx?id=%2Fpersonal% ...
- MyBatis——第一个程序
MyBatis1:初识 MyBatis第一个程序 流程:搭建环境–>导入MyBatis–>编写代码–>测试 1.创建一张User表. 关键字id.username.pwd 2.导入相 ...
- 【面试题精讲】为什么G1收集器不需要调优性能也很优秀
G1(Garbage-First)收集器是一种面向服务器端应用的垃圾回收器,它在JDK 7u4版本中首次引入,主要用于替代CMS(Concurrent Mark Sweep)收集器.相比于其他垃圾回收 ...
- Harbor镜像仓库的导出与整理之二
Harbor镜像仓库的导出与整理之二 背景 前几天参照大神的blog进行了一下harbor的镜像列表的获取与下载. 当时发现一个很诡异的问题. 实际上镜像仓库里面的镜像很多. 但是导出和列表里面的却很 ...
- [转帖]如何使用 minio 进行 BR 备份
https://tidb.net/blog/ada69456#5.%20%E4%BD%BF%E7%94%A8%20minio%20%E8%BF%9B%E8%A1%8C%20BR%20%E5%A4%87 ...