HOOK 技术
Posted m-anonymous
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HOOK 技术相关的知识,希望对你有一定的参考价值。
在介绍 截获系统消息钩子 之前,这几个函数是密切相关的:
SetWindowsHookEx() 介绍:
功能:将应用程序定义的挂钩过程安装到挂钩链中。
函数原型:HHOOK SetWindowsHookEx(
int idHook, // 钩子类型。
HOOKPROC lpfn, // 指向挂钩过程的指针。
HINSTANCE hmod, // 包含 lpfn 参数指向的挂钩过程的 DLL 的句柄。
DWORD dwThreadId // 与挂钩过程关联的线程的标识符。如果为 0,则为全局钩子。
);
返回值:如果函数成功, 则返回值是挂钩过程的句柄。如果函数失败, 返回值为 NULL。
参数 idHook:
值 | 含义 |
WH_CALLWNDPROC | 安装的钩子过程监视信息在系统将它们发送给目标窗口之前。 |
WH_CALLWNDPROCRET | 安装的钩子过程监视信息在系统将它们发送给目标窗口之后。 |
WH_KEYBOARD | 安装监视击键消息的挂钩过程。 |
WH_MOUSE | 安装监视鼠标消息的挂钩过程。 |
WH_GETMESSAGE | 安装用于监视将消息发送给消息队列的挂钩过程 |
WH_DEBUG | 安装用于调试其他挂钩过程的挂钩过程。 |
CallNextHookEx() 介绍:
功能:将挂钩信息传递到当前挂钩链中的下一个挂钩过程。钩子过程可以在处理钩子信息之前或之后调用此函数。
函数原型:LRESULT CallNextHookEx(
HHOOK hhk, // 通常被忽略。
int nCode, // 传递给当前挂钩过程的挂钩代码。下一个挂钩过程使用此代码来确定如何处理挂钩信息。
WPARAM wParam, // 传递给当前挂钩过程的 wParam 值。此参数的含义取决于与当前挂钩链关联的挂钩的类型。
LPARAM lParam // 传递给当前挂钩过程的 lParam 值。此参数的含义取决于与当前挂钩链关联的挂钩的类型。
);
返回值:此值由链中的下一个挂钩过程返回。当前挂钩过程还必须返回此值。返回值的含义取决于挂钩类型。
UnhookWindowsHookEx() 介绍:
功能:移除由 SetWindowsHookEx 函数安装在钩子链中的挂钩过程。
函数原型:BOOL UnhookWindowsHookEx(
HHOOK hhk // 要移除的钩子的句柄。
);
返回值:非零表示成功,零表示失败。
用户自定义钩子:(生成 dll 文件,并注入到相应的进程)
#include<windows.h> #include<stdlib.h> HANDLE hProc; FARPROC pfMessageBoxA; FARPROC pfMessageBoxW; int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR sl, UINT u); int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR sl, UINT u); BYTE OldMessageBoxACode[5], NewMessageBoxACode[5]; BYTE OldMessageBoxWCode[5], NewMessageBoxWCode[5]; DWORD CurrentProcessId, dwOldProtect;; BOOL BHook = FALSE; BOOL Init(); void HookOn(); void HookOff(); BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: Init(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: HookOff(); break; } return TRUE; } BOOL Init() { HMODULE hModule; DWORD Address; hModule = LoadLibraryA("user32.dll"); pfMessageBoxA = GetProcAddress(hModule, "MessageBoxA"); pfMessageBoxW = GetProcAddress(hModule, "MessageBoxW"); if (pfMessageBoxA == NULL || pfMessageBoxW == NULL) return FALSE; memcpy(OldMessageBoxACode,pfMessageBoxA,5); // 拷贝原来函数地址的前五个字节以备复原。 NewMessageBoxACode[0] = 0xe9; // 即 jmp 指令。 Address = (DWORD)MyMessageBoxA - (DWORD)pfMessageBoxA - 5; // 自定义函数与原函数的偏移地址。 memcpy(NewMessageBoxACode+1,&Address,4); memcpy(OldMessageBoxWCode,pfMessageBoxW,5); NewMessageBoxWCode[0] = 0xe9; Address = (DWORD)MyMessageBoxW - (DWORD)pfMessageBoxW - 5; memcpy(NewMessageBoxWCode+1,&Address,4); CurrentProcessId = GetCurrentProcessId(); HookOn(); return TRUE; } int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR pl, UINT u) { HookOff(); MessageBoxA(hWnd, "请重新安装系统", "重要提示", MB_OK); HookOn(); return TRUE; } int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR pl, UINT u) { HookOff(); MessageBoxW(hWnd, L"请重新安装系统", L"重要提示", MB_OK); HookOn(); return TRUE; } void HookOn() { hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, CurrentProcessId); VirtualProtectEx(hProc, pfMessageBoxA, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxA, NewMessageBoxACode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxA, 5, dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxW, NewMessageBoxWCode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxW, 5, dwOldProtect, &dwOldProtect); CloseHandle(hProc); BHook = TRUE; } void HookOff() { hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, CurrentProcessId); VirtualProtectEx(hProc, pfMessageBoxA, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxA, OldMessageBoxACode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxA, 5, dwOldProtect, &dwOldProtect); VirtualProtectEx(hProc, pfMessageBoxW, 5, PAGE_READWRITE, &dwOldProtect); WriteProcessMemory(hProc, pfMessageBoxW, OldMessageBoxWCode, 5, 0); VirtualProtectEx(hProc, pfMessageBoxW, 5, dwOldProtect, &dwOldProtect); CloseHandle(hProc); BHook = FALSE; }
以上是关于HOOK 技术的主要内容,如果未能解决你的问题,请参考以下文章