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 技术的主要内容,如果未能解决你的问题,请参考以下文章

如何将 react-hook-form 用于嵌套数组

hook技术整理

Android Hook技术

Frida 实现 Hook 功能的强大能力

Hook CreateProcess

使用Hook更新上下文状态值