ローカルフック

投稿者: | 2012/11/13

まず一番基本的なプロセス内でのフックであるローカルフックからやってみる。

基本的な処理フローはこんな感じ。

  1. SetWindowsHookExでフックプロシージャを登録
  2. フックプロシージャでフック処理
    CallNextHookExで次のフックへ引き継ぎ
  3. nhookWindowsHookExでフック解除

コードは以下のような感じ。

HHOOK hMyHook;

/*
     CallNextHookExの第一引数にはフックのインスタンスを渡す
     NULLを渡してしまうと前のフックに戻ることができなくなってしまう。どこかのフックで誤作動してしまうかもしれない。
*/

LRESULT CALLBACK MyHookProc(int nCode, WPARAM wParam, LPARAM lParam){
     //     nCodeがマイナスの場合は何もしないですぐに返す。そういう決まり。
     if(nCode < 0){ return CallNextHookEx(hMyHook, nCode, wParam, lParam); }

     // any hook

    return CallNextHookEx(hMyHook, nCode, wParam, lParam);
}

bool BeginHook(){
     hMyHook = SetWindowsHookEx(
          WH_KEYBOARD,              // フックタイプ
          (HOOKPROC)MyHookProc,     // フックプロシージャのアドレス
          NULL,                     // ローカルフックではNULL。システムフックではDLLのハンドル。
          GetCurrentThreadId());    // フックされるスレッド

     if(hMyHook == NULL){
          return false;
     }

     return true;
}

void EndHook(){
     if(UnhookWindowsHookEx(hMyHook) == 0){
          MessageBoxA(NULL, "Failed to delete hook!", "Error", MB_OK);
     }
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
     // ウィンドウの生成など

     BeginHook();

     while (GetMessage(&msg, NULL, 0, 0))
     {
          if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

          {
               TranslateMessage(&msg);
               DispatchMessage(&msg);
          }
     }

     EndHook();

     return (int) msg.wParam;

}

BeginHook()でフック開始。EndHook()でフック終了。その間のキーボードフックは設定したMyHookProc関数で処理している。SetWindowsHookExで設定しているWH_KEYBOARDとプロシージャを変えればマウスフックなども簡単そうだ。

参考
http://www.kab-studio.biz/Programing/Codian/DLL_Hook_SClass/07.html
http://www.kumei.ne.jp/c_lang/sdk2/sdk_160.htm


コメントを残す

メールアドレスが公開されることはありません。