4.5 MinHook 挂钩技术

minhook,挂钩,技术 · 浏览次数 : 44

小编点评

**MinHook 库简介** MinHook 是一个轻量级 Hooking 库,可以在运行时劫持函数调用。它支持钩子 API 函数和普通函数,并且可以运行在 32 位和 64 位 Windows 操作系统上。其特点包括易于使用、高性能和低内存占用。 **库功能** * 创建和启用钩子 * 获取和设置钩子函数指针 * 启用和禁用钩子 * 获取和设置钩子信息 **示例代码** ```c++ // 使用 MinHook 创建并启用钩子 void SetHook() { if (MH_Initialize() == MB_OK) { MH_CreateHook(&MessageBoxA, &MyMessageBoxA, reinterpret_cast(&fpMessageBoxA)); MH_EnableHook(&MessageBoxA); } } // 使用 MinHook 卸载钩子 void UnHook() { if (MH_DisableHook(&MessageBoxA) == MB_OK) { MH_Uninitialize(); } } ``` **用法** 1. 将 MinHook 库的 DLL 文件复制到应用程序的 `lib` 文件夹中。 2. 在应用程序代码中包含 `MinHook.h` 头文件。 3. 在 `SetHook()` 和 `UnHook()` 函数中,设置和获取钩子函数的指针。 4. 在应用程序启动时调用 `SetHook()` 函数创建钩子。 5. 在应用程序关闭时调用 `UnHook()` 函数释放钩子。 **注意** * MinHook 只能被在运行 Windows 的应用程序中使用。 *钩子的创建和设置只能在应用程序启动前进行。 * 钩子的执行权限必须与应用程序的进程相同。

正文

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文件中,至此当有新进程被加载时则会弹出该进程的详细路径信息,如下图所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/c425464c.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与4.5 MinHook 挂钩技术相似的内容:

4.5 MinHook 挂钩技术

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

4.5 x64dbg 探索钩子劫持技术

钩子劫持技术是计算机编程中的一种技术,它们可以让开发者拦截系统函数或应用程序函数的调用,并在函数调用前或调用后执行自定义代码,钩子劫持技术通常用于病毒和恶意软件,也可以让开发者扩展或修改系统函数的功能,从而提高软件的性能和增加新功能。钩子劫持技术的实现一般需要在对端内存中通过`create_alloc()`函数准备一块空间,并通过`assemble_write_memory()`函数,将一段汇编代

4.5 C++ Boost 文件目录操作库

Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序

【RocketMQ】DLedger模式下的选主流程分析

RocketMQ 4.5版本之前,可以采用主从架构进行集群部署,但是如果master节点挂掉,不能自动在集群中选举出新的Master节点,需要人工介入,在4.5版本之后提供了DLedger模式,使用Raft算法,如果Master节点出现故障,可以自动选举出新的Master进行切换。 Raft协议 R

【RocketMQ】【源码】DLedger选主源码分析

RocketMQ 4.5版本之前,可以采用主从架构进行集群部署,但是如果master节点挂掉,不能自动在集群中选举出新的Master节点,需要人工介入,在4.5版本之后提供了DLedger模式,使用Raft算法,如果Master节点出现故障,可以自动选举出新的Master进行切换。 **Raft协议

[转帖]BASH编写入门与实例

1 2 3 4 5 6 7 8 9 10 怎么写shell脚本: 。使用任何编辑工具编写shell脚本 例如vi -#!/bin/bash #在第一行放置头格式说明 -#!/usr/bin/gawk //awk需要添加的头格式,让系统知道用什么方式去解析此文件 -#!/usr/local/bin/p

瀚高4.5.8的安装部署过程

瀚高4.5.8的安装部署过程 说明 大周末的写文档. 主要是备忘,之前写的太乱了. 本来想自己写一份, 但是怀疑找到了瀚高工程师的文档 准备直接学习一下: https://blog.csdn.net/qiuchenjun/article/details/125985256 感谢原作者 安装 rpm

[转帖]Redhat 8 磁盘调度策略变化:NOOP改为NONE

说明 在 redhat 4/5/6/7版本中的NOOP调度策略,从8开始修改为NONE,官方解释: none Implements a first-in first-out (FIFO) scheduling algorithm. It merges requests at the generic

.NET周报 【4月第5期 2023-04-30】

国内文章 基于 Github 平台的 .NET 开源项目模板. 嘎嘎实用! https://www.cnblogs.com/NMSLanX/p/17326728.html 大家好,为了使开源项目的维护和管理更方便一些,出于个人需求写了一款开源项目的模板,该模板基于 Github 平台,并使用 .NE

队列的内置模块(deque)--双向队列

博客地址:https://www.cnblogs.com/zylyehuo/ # -*- coding: utf-8 -*- from collections import deque q = deque([1,2,3,4,5], 5) q.append(6) # 队尾进队 print(q.popl