32/64 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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM