Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access to hook in hook procedure

Tags:

c++

c

winapi

hook

How can I access to the handle of a hook from his procedure ?

Example :

HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)hookProc, GetModuleHandle(NULL), 0);

LRESULT CALLBACK hookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    //I want my HHOOK here :O
}
like image 350
Triton Avatar asked Mar 05 '26 07:03

Triton


1 Answers

You need to store the HHOOK variable in global memory. Don't declare it as a local variable of whatever function is calling SetWindowsHookEx().

Edit: Here is a class-based example for 32-bit CPUs:

class THookKeyboardLL
{
private:
    HHOOK hHook;

    void *pProxy;
    static LRESULT CALLBACK ProxyStub(THookKeyboardLL *This, int nCode, WPARAM wParam, LPARAM lParam);

    LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);

public:
    THookKeyboardLL();
    ~THookKeyboardLL();
};

.

#include <pshpack1.h>
struct sProxy
{
    unsigned char PopEax;
    unsigned char Push;
    void *ThisPtr;
    unsigned char PushEax;
    unsigned char Jmp;
    int JmpOffset;
};
#include <poppack.h>

long CalcJmpOffset(void *Src, void *Dest)
{
    return reinterpret_cast<long>(Dest) - (reinterpret_cast<long>(Src) + 5);
}

LRESULT CALLBACK THookKeyboardLL::ProxyStub(THookKeyboardLL *This, int nCode, WPARAM wParam, LPARAM lParam)
{
    return This->HookProc(nCode, wParam, lParam);
}

THookKeyboardLL::THookKeyboardLL()
    : hHook(NULL), pProxy(NULL)
{
    sProxy *Proxy = (sProxy*) VirtualAlloc(NULL, sizeof(sProxy), MEM_COMMIT, PAGE_READWRITE);

    Proxy->PopEax = 0x58;
    Proxy->Push = 0x68;
    Proxy->ThisPtr = this;
    Proxy->PushEax = 0x50;
    Proxy->Jmp = 0xE9;
    Proxy->JmpOffset = CalcJmpOffset(&(Proxy->Jmp), &ProxyStub);

    // Note: it is possible, but not in a portable manner, to
    // get the memory address of THookKeyboardLL::HookProc()
    // directly in some compilers.  If you can get that address,
    // then you can pass it to CalcJmpOffset() above and eliminate
    // THookKeyboardLL::ProxyStub() completely. The important
    // piece is that the Proxy code above injects this class
    // instance's "this" pointer into the call stack before
    // calling THookKeyboardLL::HookProc()...

    DWORD dwOldProtect;
    VirtualProtect(Proxy, sizeof(sProxy), PAGE_EXECUTE, &dwOldProtect);
    FlushInstructionCache(GetCurrentProcess(), Proxy, sizeof(sProxy));

    pProxy = Proxy;
    hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)pProxy, GetModuleHandle(NULL), 0);
}

THookKeyboardLL::~THookKeyboardLL()
{
    if (hHook != NULL)
        UnhookWindowsHookEx(hHook);

    if (pProxy)
        VirtualFree(pProxy, 0, MEM_RELEASE);
}

LRESULT CALLBACK THookKeyboardLL::HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    // ...

    return CallNextHookEx(hHook, nCode, wParam, lParam);
    // when this method exits, it will automatically jump
    // back to the code that originally called the Proxy.
    // The Proxy massaged the call stack to ensure that...
}
like image 181
Remy Lebeau Avatar answered Mar 07 '26 19:03

Remy Lebeau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!