MinHook是一个轻量级的Hooking库,可以在运行时劫持函数调用。它支持钩子API函数和普通函数,并且可以运行在32位和64位Windows操作系统上。其特点包括易于使用、高性能和低内存占用。MinHook使用纯汇编语言实现,在安装和卸载钩子时只需要短暂地锁定目标线程,因此对目标线程的影响非常小。

读者可自行下载对应的库文件,本节所使用的是MinHook_133_lib版本,并配置好对应的包含文件以及库目录,如下图所示;

实现修改弹窗提示

如下一段代码其作用是hook MessageBoxA函数,当程序调用MessageBoxA时,会调用MyMessageBoxA函数代替原来的MessageBoxA函数进行处理,而MyMessageBoxA函数会将调用信息改成Hook Inject

示例中的SetHook函数用于创建并启用hook,使用MH_Initialize进行MinHook库初始化,然后使用MH_CreateHook创建钩子并保存MessageBoxA原函数指针到fpMessageBoxA中,最后使用MH_EnableHook启用hook。而UnHook函数用于禁用和释放hook,使用MH_DisableHook禁用钩子,然后使用MH_Uninitialize释放MinHook库资源。

DllMain函数中,如果是DLL进程附加事件,则执行SetHook函数,如果是DLL进程分离事件,则执行UnHook函数禁用和释放钩子。

#include <Windows.h>
#include <MinHook.h> #pragma comment(lib,"libMinHook-x86-v120-md.lib") typedef int (WINAPI *OldMessageBox)(HWND, LPCSTR, LPCSTR, UINT); OldMessageBox fpMessageBoxA = NULL; // 自定义弹窗
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
int ret = fpMessageBoxA(hWnd, "Hook Inject hello lyshark", lpCaption, uType);
return ret;
} // 安装钩子
void SetHook()
{
if (MH_Initialize() == MB_OK)
{
MH_CreateHook(&MessageBoxA, &MyMessageBoxA, reinterpret_cast<void**>(&fpMessageBoxA));
MH_EnableHook(&MessageBoxA);
}
} // 卸载钩子
void UnHook()
{
if (MH_DisableHook(&MessageBoxA) == MB_OK)
{
MH_Uninitialize();
}
} BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
UnHook();
break;
}
return TRUE;
}

编译上述代码,使用注入器将hook.dll注入到特定进程内,此时点击弹窗提示会发现弹窗内容已经被替代了,如下图所示;

实现修改窗口标题

一般来说程序中的修改标题功能都是调用SetWindowTextA来实现的,我们可以Hook这个函数对其进行处理后返回新标题即可,当然也可以钩挂住GetWindowTextA函数,同样可以实现标题的修改。

如下代码通过对SetWindowTextA函数进行挂钩,当读者点击设置标题是则触发自定义fpSetWindowTextA函数,该函数内部通过调用自定义标题修改函数实现了将当前软件标题替换为破解版本,并返回给用户。

#include <Windows.h>
#include <MinHook.h> #pragma comment(lib,"libMinHook-x86-v120-md.lib") typedef BOOL(WINAPI *OldSetWindowTextA)(HWND, LPCSTR); OldSetWindowTextA fpSetWindowTextA = NULL; BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString)
{
BOOL ret = fpSetWindowTextA(hWnd, "破解版本");
return ret;
} void SetHook()
{
if (MH_Initialize() == MB_OK)
{
MH_CreateHook(&SetWindowTextA, &MySetWindowTextA, reinterpret_cast<void**>(&fpSetWindowTextA));
MH_EnableHook(&SetWindowTextA);
}
} void UnHook()
{
if (MH_DisableHook(&SetWindowTextA) == MB_OK)
{
MH_Uninitialize();
}
} BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
UnHook();
break;
}
return TRUE;
}

当读者将hook.dll注入到程序中后,我们再次点击设置标题按钮,此时标题将被修改为破解版本,如下图所示;

实现监控进程创建

要实现监控进程创建,我们可以通过MinHook库来钩住explorer.exe程序,通过劫持程序内的CreateProcessW函数,在Windows操作系统中,大部分进程都是由 explorer.exe 进程派生出来的。explorer.exe 是Windows资源管理器的主进程,负责启动和管理用户界面、任务栏、桌面等。

当用户登录到系统后,explorer.exe 进程会自动启动,并成为用户交互的主要界面。在用户打开应用程序、文件夹或执行其他操作时,explorer.exe 进程会根据用户的请求创建新的进程来运行相应的应用程序或执行相应的任务。

通过对该进程进行挂钩,即可实现监控应用层其他进程创建或销毁的目的,读者可自行使用64位库编译下方代码,并注入到explorer.exe进程中,即可实现监控进程的创建功能。

#include <Windows.h>
#include <MinHook.h> #pragma comment(lib,"libMinHook-x64-v120-md.lib") typedef int (WINAPI *OldCreateProcessW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL,
DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); OldCreateProcessW fpCreateProcessW = NULL; int WINAPI MyCreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
{
MessageBoxW(0, lpApplicationName, 0, 0); int nRetn = fpCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
return nRetn;
} void SetHook()
{
if (MH_Initialize() == MB_OK)
{
// 参数一: 函数名称
// 参数二: 自定义函数
// 参数三: 原始函数指针
MH_CreateHook(&CreateProcessW, &MyCreateProcessW, reinterpret_cast<void**>(&fpCreateProcessW));
MH_EnableHook(&CreateProcessW);
}
} void UnHook()
{
if (MH_DisableHook(&CreateProcessW) == MB_OK)
{
MH_Uninitialize();
}
} BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
SetHook();
break;
case DLL_PROCESS_DETACH:
UnHook();
break;
}
return TRUE;
}

读者可使用x64模式编译上方代码,并将其注入到explorer.exe文件中,至此当有新进程被加载时则会弹出该进程的详细路径信息,如下图所示;

4.5 MinHook 挂钩技术的更多相关文章

  1. Windows Hook技术

    0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...

  2. PE格式: 分析IatHook并实现

    Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...

  3. 浅谈Hybrid技术的设计与实现第二弹

    前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 接上文:浅谈Hybrid技术的设计与实现(阅读本文前,建议阅读这个先) ...

  4. EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...

  5. Hook技术

    hook钩子: 使用技术手段在运行时动态的将额外代码依附现进程,从而实现替换现有处理逻辑或插入额外功能的目的. 它的技术实现要点有两个: 1)如何注入代码(如何将额外代码依附于现有代码中). 2)如何 ...

  6. 构建通过 Database.com 提供技术支持的 PhoneGap 应用程序

    要求 其他必要产品 Database.com account 用户级别 全部 必需产品 PhoneGap Build 范例文件 Database.Com-PhoneGap-Sample 在这篇文章中, ...

  7. JIT(动态编译)和AOT(静态编译)编译技术比较

    Java 应用程序的性能经常成为开发社区中的讨论热点.因为该语言的设计初衷是使用解释的方式支持应用程序的可移植性目标,早期 Java 运行时所提供的性能级别远低于 C 和 C++ 之类的编译语言.尽管 ...

  8. API HOOK技术

    API HOOK技术是一种用于改变API执行结果的技术,Microsoft 自身也在Windows操作系统里面使用了这个技术,如Windows兼容模式等. API HOOK 技术并不是计算机病毒专有技 ...

  9. 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展

    [Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...

  10. 转:Web 测试的创作与调试技术

    摘要:学习有关 Visual Studio 2005 Web 测试的更多知识,包括 Web 测试引擎和记录器如何工作,以及如何创建有效的 Web 测试. 本页内容 读者 简介 记录一个 Web 测试  ...

随机推荐

  1. Python网络编程:ZeroMQ

    大家好,我是老胡.最近在和小伙伴们一起搞事情,我是学统计出身,编程能力其实很差,有点拖后腿了.所以需要恶补基础,这个系列会更新几篇,感兴趣的同学可以一起学习交流. ZeroMQ概述 ZeroMQ(又名 ...

  2. CJ88 DUMP The ASSERT condition was violated

    一.CJ88运行某个项目时DUMP,其他项目正常 The ASSERT condition was violated. 源代码位置为交易货币为空导致DUMP 经过长时间的源码调试,也只定位在查询语句这 ...

  3. 分享几个常用的运维 shell 脚本

    今天咸鱼给大家分享几个不错的 Linux 运维脚本,这些脚本中大量使用了 Linux 的文本三剑客: 1. awk 2. grep 3. sed 建议大家这三个工具都要了解并最好能够较为熟练的使用 根 ...

  4. P1379 八数码难题 ( A* 算法 与 IDA_star 算法)

    P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...

  5. Windows 10 修改环境变量不重启生效的解决方案

    # 表示 Win 键 #R 进入 cmd(不要使用 Listary 的 cmd 方式进入,设置不会生效) 键入 set PATH=C: 关闭窗口 同样方式打开 cmd 键入 echo %PATH%,会 ...

  6. linux安装pyarmor踩坑记录

    现有环境 centos 7.8 python 3.7.6 pip 20.0 找度娘学习安装pyarmor pip install pyarmor 然后查看版本 pyarmor --version 进入 ...

  7. java读取解析endnote文件

    有些项目中会要求代码解析endnote文献资料获取一些标准的信息,例如XX在某著名期刊上发表了某篇文章,关于发表文章的这个事情的描述就会给坐着一个endnote文件来记录文章名称.作者.期刊名称.出版 ...

  8. <vue 基础知识 6、条件判断标签v-if>

    代码结构 一.     01-v-if用法 1.效果 根据分数的不同展现不同的汉字 2.代码 01-v-if用法.html <!DOCTYPE html> <html lang=&q ...

  9. shell 编程中 awk ,wc ,$0,$1 等 命令的使用总结

    本文为博主原创,转载请注明出处: 1. awk 的常用场景总结 2. wc 常用场景总结 3. $0,$1,$# 的使用总结 4. seq 的使用总结 5. 获取用户输入 read 使用 1. awk ...

  10. Elasticsearch 索引与文档的常用操作总结二:复杂条件查询

    本文为博主原创,未经允许不得转载: 1.  查询所有:match_all GET /es_db/_doc/_search { "query":{ "match_all&q ...