在上面的各种Hook挂钩方式中,我们都是在手写封装代码,但这样的方式并不高效,真正的生产环境中我们必须使用现成的Hook库,常用的Hook库有免费开源的MinHook和商业的Detours Hook,这里我们就选择介绍MinHook这个迷你函数库,该Hook库是完全开源免费的,使用起来也非常的简单.
MinHook的GitHub地址: https://github.com/TsudaKageyu/minhook
Hook 实现修改弹窗: 实现Hook MsgBox
弹窗,该库的原理与我们上面手动实现的方式是相同的.
#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x86.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", 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 实现修改标题: 程序中的修改标题功能一般都是调用SetWindowTextA
来实现的,我们可以Hook这个函数对其进行处理后返回新标题即可,当然也可以钩挂住GetWindowTextA
函数,同样可以实现标题的修改.
#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x86.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 实现拦截文件创建: 文件与进程的创建离不开CreateFileA
函数,我们可以Hook这个函数来拦截程序创建文件,此方法可用于对抗恶意代码,一些杀软也会通过挂钩该函数实现监控系统文件的创建.
#include <Windows.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x86.lib")
typedef HANDLE(WINAPI *OldCreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
OldCreateFileA fpCreateFileA = NULL;
// 定义个性化的CreateFileA 并实现过滤功能
HANDLE WINAPI MyCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
char *path = "c://test.txt";
if (strcmp(lpFileName, path))
{
MessageBoxA(NULL, lpFileName, "MsgBox", NULL);
MessageBoxA(0, TEXT("拦截到创建文件请求"), 0, 0);
lpFileName = "";
}
return fpCreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
}
void SetHook()
{
if (MH_Initialize() == MB_OK)
{
// 参数一: 函数名称 参数二: 自定义函数 参数三: 原始函数指针
MH_CreateHook(&CreateFileA, &MyCreateFileA, reinterpret_cast<void**>(&fpCreateFileA));
MH_EnableHook(&CreateFileA);
}
}
void UnHook()
{
if (MH_DisableHook(&CreateFileA) == 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注入到explorer.exe
进程中,即可监控系统的进程创建,在其中可以做查杀检测等,即可实现简单的主动防御.
#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x64.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;
}
Hook 实现禁止结束进程: 通过将DLL注入到系统的任务管理器中,实现禁止结束某个进程,任务管理器通过调用TerminateProcess()
函数来执行强杀进程,我们只需要Hook系统中的OpenProcess()
打开进程并让其返回假,那么TerminateProcess()
拿不到句柄也就无法完成结束进程了.
#include <Windows.h>
#include <stdio.h>
#include <MinHook.h>
#pragma comment(lib,"libMinHook.x64.lib")
typedef HANDLE(WINAPI *OldOpenProcess)(DWORD, BOOL, DWORD);
OldOpenProcess fpOpenProcess = NULL;
HANDLE WINAPI MyOpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{
HWND handle = NULL;
handle = FindWindow(L"TXGuiFoundation", L"QQ");
if (handle != NULL)
{
HANDLE Retn = fpOpenProcess(dwDesiredAccess, bInheritHandle, 0);
return Retn;
}
HANDLE Retn = fpOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
return Retn;
}
void SetHook()
{
if (MH_Initialize() == MB_OK)
{
// 参数一: 函数名称 参数二: 自定义函数 参数三: 原始函数指针
MH_CreateHook(&OpenProcess, &MyOpenProcess, reinterpret_cast<void**>(&MyOpenProcess));
MH_EnableHook(&OpenProcess);
}
}
void UnHook()
{
if (MH_DisableHook(&OpenProcess) == 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;
}