C/C++ MinHook 库的使用技巧

在上面的各种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;
}
posted @ 2020-09-11 18:57  lyshark  阅读(2671)  评论(0编辑  收藏  举报

loading... | loading...
博客园 - 开发者的网上家园