在上面的各種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;
}