在dll注入后,SetWindowshookEx有时无法正常工作

时间:2013-03-09 00:20:09

标签: c++ visual-studio winapi keyboard-hook dll-injection

我正在使用这个lib http://code.google.com/p/injex/来注入一个包含键盘钩子函数的dll。 dll很简单,只需创建一个线程并使用'setWindowsHookEx'函数。

注射总是成功,但键盘钩子并不适用于所有情况。

  1. 我写了一个简单的'hello world'win32应用程序,并使用injex.exe将键盘钩子dll注入其中。一切都按预期进行。

  2. 如果我选择一个复杂的程序来注入(一个用delphi编写的游戏),dll被成功注入(我可以看到注入的主窗体),但它无法挂钩键盘。

    < / LI>

    所以我的问题是:

    1. 由于注入方法或键盘挂钩功能导致键盘挂钩失败?

    2. 是否有可能注入dll,但其功能无法保证?

    3. 所以欢迎任何建议。

      这是dll代码:

      // dllmain.cpp : Defines the entry point for the DLL application.
      #include "stdafx.h"
      
      #include <Windows.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <tchar.h>
      
      //GUI==============================================================================
      #define MYMENU_EXIT         (WM_APP + 101)
      #define MYMENU_MESSAGEBOX   (WM_APP + 102) 
      
      HINSTANCE  inj_hModule;          //Injected Modules Handle
      HWND       prnt_hWnd;            //Parent Window Handle
      
      //WndProc for the new window
      LRESULT CALLBACK DLLWindowProc (HWND, UINT, WPARAM, LPARAM);
      
      //Register our windows Class
      BOOL RegisterDLLWindowClass(wchar_t szClassName[])
      {
          WNDCLASSEX wc;
          wc.hInstance =  inj_hModule;
          wc.lpszClassName = (LPCWSTR)L"InjectedDLLWindowClass";
          wc.lpszClassName = (LPCWSTR)szClassName;
          wc.lpfnWndProc = DLLWindowProc;
          wc.style = CS_DBLCLKS;
          wc.cbSize = sizeof (WNDCLASSEX);
          wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
          wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
          wc.hCursor = LoadCursor (NULL, IDC_ARROW);
          wc.lpszMenuName = NULL;
          wc.cbClsExtra = 0;
          wc.cbWndExtra = 0;
          wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
          if (!RegisterClassEx (&wc))
              return 0;
      }
      //Creating our windows Menu
      HMENU CreateDLLWindowMenu()
      {
          HMENU hMenu;
          hMenu = CreateMenu();
          HMENU hMenuPopup;
          if(hMenu==NULL)
              return FALSE;
          hMenuPopup = CreatePopupMenu();
          AppendMenu (hMenuPopup, MF_STRING, MYMENU_EXIT, TEXT("Exit"));
          AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hMenuPopup, TEXT("File")); 
      
          hMenuPopup = CreatePopupMenu();
          AppendMenu (hMenuPopup, MF_STRING,MYMENU_MESSAGEBOX, TEXT("MessageBox")); 
          AppendMenu (hMenu, MF_POPUP, (UINT_PTR) hMenuPopup, TEXT("Test")); 
          return hMenu;
      }
      
      
      //Our new windows proc
      LRESULT CALLBACK DLLWindowProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
      {
          switch (message)
          {
              case WM_KEYDOWN:
                  if(wParam == VK_HOME) {
                  //TextOut(hdc,15, 15, keydown, _tcslen(keydown));
                  // etc.
                      MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL);
                  }
              break;
              case WM_COMMAND:
                     switch(wParam)
                     {
                          case MYMENU_EXIT:
                              SendMessage(hwnd, WM_CLOSE, 0, 0);
                              break;
                          case MYMENU_MESSAGEBOX:
                              MessageBox(hwnd, L"Test", L"MessageBox",MB_OK);
                              break;
                     }
                     break;
              case WM_DESTROY:
                  PostQuitMessage (0);
                  break;
              default:
                  return DefWindowProc (hwnd, message, wParam, lParam);
          }
          return 0;
      }
      
      //HOOK LIB=====================================================================================================
      // This will be called when keys are pressed.
      
      HHOOK g_kbHook=NULL;
      
      LRESULT CALLBACK KeyboardHook(int nCode,WPARAM wParam,LPARAM lParam)
      {
          KBDLLHOOKSTRUCT* key;
          if(wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN){
              key = (KBDLLHOOKSTRUCT*)lParam;
              if(key->vkCode == VkKeyScan('a')){
                  //odprintf("You pressed 'a'");
                  MessageBox(NULL, _T("Pressed a"), _T("Win32 Guided Tour"), NULL);
              }
      
              if(key->vkCode == VK_F1){
                  MessageBox(NULL, _T("Pressed F1"), _T("Win32 Guided Tour"), NULL);
                  //odprintf("You pressed F1");
              }
          }
      
          return 0;
      }
      
      LRESULT CALLBACK _KeyboardHookProc(int nCode,WPARAM wParam,LPARAM lParam){
          //g_kbHookFunction(nCode,wParam,lParam);
          KeyboardHook(nCode,wParam,lParam);
          return CallNextHookEx(g_kbHook,nCode,wParam,lParam);
      };
      
      //ENTRY POINT================================================================================================
      //our start function, start everything here
      
      DWORD WINAPI start(LPVOID lpParam){
          // START YOUR CODE HERE...
      
          // Lay some hooks, season libraly with pwnsauce.
          // Do whatever you want here, this is your thread to play with.
          // NOTE: This is used as the starting function in most examples.
      
          // STOP HERE.
      
          MSG messages;
          wchar_t *pString = reinterpret_cast<wchar_t * > (lpParam);
          HMENU hMenu = CreateDLLWindowMenu();
          RegisterDLLWindowClass(L"InjectedDLLWindowClass");
          prnt_hWnd = FindWindow(L"Window Injected Into ClassName", L"Window Injected Into Caption");
          HWND hwnd = CreateWindowEx (0, L"InjectedDLLWindowClass", L"mywindow", WS_EX_PALETTEWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, prnt_hWnd, hMenu,inj_hModule, NULL );
          ShowWindow (hwnd, SW_SHOWNORMAL);
      
          g_kbHook = SetWindowsHookEx(WH_KEYBOARD_LL,_KeyboardHookProc,GetModuleHandle(NULL),0);
          if (!g_kbHook) {
      
          }
      
          while (GetMessage (&messages, NULL, 0, 0))
          {
              TranslateMessage(&messages);
              DispatchMessage(&messages);
          }
          return 1;
          g_kbHook = NULL;
      }
      
      
      BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {
          switch (ul_reason_for_call) {
              case DLL_PROCESS_ATTACH:
                  // We create a new thread to do our bidding in, this way we don't hold the loader lock.
                  // We close the handle to the thread for various reasons.
                  inj_hModule = hModule;
                  CloseHandle(CreateThread(NULL, 0, start, (LPVOID)hModule, 0, NULL));
      
              break;
              case DLL_THREAD_ATTACH:
              case DLL_THREAD_DETACH:
              case DLL_PROCESS_DETACH:
              break;
          }
      
          return TRUE;
      }
      

1 个答案:

答案 0 :(得分:1)

如果您尝试挂钩的进程已安装了自己的键盘挂钩,则该挂钩可能无法调用CallNextHookEx()将消息传递给您的挂钩。请参阅MSDN处的说明(请注意“返回值”部分中的说明)。如果这确实是您的问题的原因,您唯一的选择可能是在进程安装自己的挂钩之前安装挂钩。