4.5 MinHook 挂钩技术

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

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 许可协议。转载请注明出处!

目录
相关文章
|
5天前
|
弹性计算 数据库
生命周期挂钩概述
生命周期挂钩概述
18 0
|
5天前
|
监控 安全 API
5.9 Windows驱动开发:内核InlineHook挂钩技术
在上一章`《内核LDE64引擎计算汇编长度》`中,`LyShark`教大家如何通过`LDE64`引擎实现计算反汇编指令长度,本章将在此基础之上实现内联函数挂钩,内核中的`InlineHook`函数挂钩其实与应用层一致,都是使用`劫持执行流`并跳转到我们自己的函数上来做处理,唯一的不同的是内核`Hook`只针对`内核API`函数,但由于其身处在`最底层`所以一旦被挂钩其整个应用层都将会受到影响,这就直接决定了在内核层挂钩的效果是应用层无法比拟的,对于安全从业者来说学会使用内核挂钩也是很重要。
47 1
5.9 Windows驱动开发:内核InlineHook挂钩技术
|
8月前
|
存储 监控 编译器
4.3 IAT Hook 挂钩技术
IAT(Import Address Table)Hook是一种针对Windows操作系统的API Hooking 技术,用于修改应用程序对动态链接库(DLL)中导入函数的调用。IAT是一个数据结构,其中包含了应用程序在运行时使用的导入函数的地址。IAT Hook的原理是通过修改IAT中的函数指针,将原本要调用的函数指向另一个自定义的函数。这样,在应用程序执行时,当调用被钩子的函数时,实际上会执行自定义的函数。通过IAT Hook,我们可以拦截和修改应用程序的函数调用,以实现一些自定义的行为,比如记录日志、修改函数参数或返回值等。
67 0
4.3 IAT Hook 挂钩技术
|
8月前
|
Windows
4.4 EAT Hook 挂钩技术
EAT(Export Address Table)用于修改动态链接库(DLL)中导出函数的调用。与`IAT Hook`不同,EAT Hook是在DLL自身中进行钩子操作,而不是修改应用程序的导入表。它的原理是通过修改DLL的导出函数地址,将原本要导出的函数指向另一个自定义的函数。这样,在应用程序调用DLL的导出函数时,实际上会执行自定义的函数。与IAT不同是EAT存放的不是函数地址,而是导出函数地址的偏移,使用时需要加上指定Dll的模块基地址,当Hook挂钩之后,所有试图通过导出表获取函数地址的行为都会受到影响,EATHook并不会直接生效,它只能影响`Hook`之后对该函数地址的获取。
91 1
4.4 EAT Hook 挂钩技术
|
12月前
|
监控 安全
加强网络风险生命周期
加强网络风险生命周期
|
Linux 测试技术 调度
Linux调度器何时需触发抢占?—— 从hackbench谈起
作者:何惟禹 吴一昊一、背景:性能之战“不服跑个分”虽然已经沦为手机行业的调侃用语,但在操作系统领域仍然是最重要的评价方式之一。本文的故事也源于一次 Alinux3 与 CentOS8 的一次跑分的较量。当然比分较量并不是目的,更重要的是发现存在的回归缺陷并进行修复,最终让 Alinux3 全方位持平或超过 CentOS8。在本次较量中,我们使用 hackbench 作为跑分软件,我们在测试过程中
2326 0
Linux调度器何时需触发抢占?—— 从hackbench谈起
好客租房62-组件的生命周期三个阶段-4卸载时
好客租房62-组件的生命周期三个阶段-4卸载时
95 0
好客租房62-组件的生命周期三个阶段-4卸载时
好客租房61-组件的生命周期三个阶段-3更新时
好客租房61-组件的生命周期三个阶段-3更新时
90 0
好客租房61-组件的生命周期三个阶段-3更新时
|
前端开发
好客租房60-组件的生命周期三个阶段-2更新时
好客租房60-组件的生命周期三个阶段-2更新时
96 0
好客租房60-组件的生命周期三个阶段-2更新时
|
安全 Cloud Native 网络安全
启动云计算事件响应策略的5个步骤
如今,数据转储、勒索软件攻击、恶意软件攻击事件已屡见不鲜,这意味着事件管理策略已成为必要选项。