2012-02-11 25 views
3

彼のプロシージャからフックのハンドルにアクセスするにはどうすればよいですか?フック・イン・フック・プロシージャへのアクセス

例:

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 
} 
+0

ここをクリックしてください:http://stackoverflow.com/questions/214022/how-to-correctly-use-setwindowshookex-callnexthookex – Asaf

答えて

3

あなたがグローバルメモリにHHOOK変数を格納する必要があります。 SetWindowsHookEx()を呼び出す関数のローカル変数として宣言しないでください。

編集は:

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(); 
}; 

:ここでは32ビットCPUのクラスベースの例です。

#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... 
} 
+0

フックを作成するクラスを作成したいので、私は使用できません。私はいくつかのオブジェクトを作成できなければならないからです。 – Triton

+1

'SetWindowsHookEx()'はクラスの使用をサポートしていません。フックプロシージャとしてクラスメソッドを使用し、複数のクラスインスタンスを使用して複数のフックを設定する場合は、各クラスインスタンスごとに別々のプロキシサンクを作成し、そのプロキシを 'SetWindowsHookEx()'に渡す必要があります。プロキシは必要に応じて関連するクラスインスタンスに呼び出します。まっすぐC/C++でそれを行うことはできません。あなたはアセンブリでプロキシを書く必要があります(少なくともSetWindowsHookEx()が呼び出します)。 –

+0

あまりにも難しくありません(少なくとも32ビットで、私は64ビットについてはわかりません)。 –

1

あなたがCallNextHookExためdocumentationを見れば、あなたはHHOOKパラメータは、Windows 9xのをサポートする必要があるならば、あなたはグローバル変数にHHOOKを格納する必要があり、Windows NT上で任意であることがわかります。

グローバルフックが高価なので、複数のコールバック関数を登録する場合は、アプリケーションが1つのフックとそこに登録するコールバック関数を設定するように、これを抽象化する必要がありますあなたの本当の機能を(リンクされたリストなどで)呼び出します。