工大后院

 找回密码
 加入后院

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 2531|回复: 1

我的QQ尾巴友好版

[复制链接]
发表于 2007-11-4 13:45 | 显示全部楼层 |阅读模式
1、前言
       直至QQ推出了2007版本,QQ尾巴还是会出现.QQ的源程序没有加过壳,通过反汇编可以得到源码,这给想修改QQ的人提
       供了方便,例如珊瑚虫。我在参考了网上的一些资料后自己做了一个qq尾巴友好版程序,模拟了QQ尾巴中把文字黏贴到
       QQ的输入框中的效果.
      本人才疏学浅,本文肯定会有说得不对的地方,欢迎大家指出!

2、实现原理
       a、找到QQ的对话窗口(前提肯定是要先打开一个聊天窗口拉!),QQ聊天窗口的布局是这样的:
          *“#32770”(QQ聊天窗口的第一层窗口)
          |
          |——*“#32770”(QQ聊天窗口的第二层,“发送”“聊天模式”等按钮都在这层里面,这两个按钮很重要!)
               |
               |——*“AfxWnd42” (真正的输入框是在这一层!)
          最终我们是要找到“AfxWnd42”所在的窗口,然后找到RichEdit控件,找到就可以@##¥了!
        b、把文本粘结进RichEdit中,首先把文字复制到剪切版,因为QQ的RichEdit控件控件是做了保护的,不能直接发送
           WM_PASTE消息过去(这个让我郁闷了很久,最后终于找到解决办法!),不能直接黏贴就只能模拟按键信息了
          (QQ再厉害也不可能禁止我按ctrl+v吧?),现在就是要模拟 ctrl+v的按键效果!我的做法就是找到QQ对话窗口后
           把它置顶,然后模拟 ctrl+v!这样文字就可以粘进RichEdit里面了。(真正的QQ尾巴是在用户按下“发送”
           按钮后才把文本粘进去的,那时焦点是落在QQ对话窗口里的,但是我 这里QQ对话窗口不一定能获得焦点,所以
           黏贴时必须让它获得焦点!)
3、具体实现
        a、寻找QQ窗口
            这里主要是用到FindWindowEx,GetWindowText,FindWindow函数(这些函数的具体使用请上网查查)
            HWND getTheFirst_window()
            {
             HWND temp_handle = 0;
             char *flag="no";
             TCHAR szText[500];
             szText[0] = '\0';
             CString temp_str;
             CString temp_str1;
             TCHAR szText_8[500];
             int str_length=0;
             while((temp_handle = FindWindowEx(0,temp_handle,"#32770",NULL))!=NULL)
             {

                ::GetWindowText(temp_handle,szText,sizeof(szText));
                //AfxMessageBox(szText);
                //使用CString截取以适用所有窗口
                temp_str = szText;
                temp_str1 = szText;
                str_length = strlen(szText);
                temp_str = temp_str.Mid(str_length-6,str_length);


                lstrcpy(szText, temp_str.GetBuffer(6));
                temp_str.ReleaseBuffer();

                temp_str1 = temp_str1.Mid(str_length-8,str_length);

                lstrcpy(szText_8, temp_str1.GetBuffer(8));
                temp_str1.ReleaseBuffer();
                //AfxMessageBox(szText_8);
                if(strcmp(szText_8,"发送消息")==0||strcmp(szText,"聊天中")==0)
                {
                        //AfxMessageBox(szText);
                        break;
                }

             }

             return temp_handle;
            }
       说明:试过了几种寻找QQ聊天窗口的方式,最后选用了这种,用FindWindowEx寻找Class Name是#32770的窗口,你会发
       现竟然不止一个!!(真奇怪,不过对窗口不熟,不知道为什么),因为会有很多个#32770,所以要筛选一下,“发送
       消息”,“聊天中”,熟悉吧?对拉,就是QQ聊天窗口顶部的文字啊!(好像没什么技术含量。。。。),好,成功!
       终于完成了一小步!接下来就要找输入框了!
      
       下面这个函数是网上找的,直接用好了!
       /*---------------------------------------------------------------------
       递归枚举hFatherWindow指定的窗口下的所有子窗口和兄弟窗口,
       返回和lstyle样式相同的窗口句柄,如果没有找到,返回NULL
       ---------------------------------------------------------------------*/
       HWND GetStyleWindow(HWND hFatherWindow, const long lstyle)
       {
         //如果这个窗口符合查找条件,返回此句柄
        if (GetWindowLong(hFatherWindow, GWL_STYLE) == lstyle)
        {
        return hFatherWindow;
         }

        HWND hNextWindow, hDestWindow;

        //得到子窗口句柄
       if ((hNextWindow = GetWindow(hFatherWindow, GW_CHILD))!= NULL)
        {
           //递归查找子窗口
        if ((hDestWindow = GetStyleWindow(hNextWindow, lstyle)) != NULL)
        {
                return hDestWindow;
        }
        }

         //递归查找兄弟窗口
       if ((hNextWindow = GetWindow(hFatherWindow, GW_HWNDNEXT)) != NULL)
        {
        return GetStyleWindow(hNextWindow, lstyle);
          }

         //没有匹配的则返回NULL
         return NULL;
       }
       说明:这里的lstyle参数其实就是窗口的风格(QQ第二层窗口的样式是0x50000044,好像一直都是这个值不知道为什
       么,可能是系统定义好的!所以每次都不会变!)
       通过以上两步,终于找到了QQ输入框所在的窗口!(year!)下面就要寻找传说中的RichEdit了!

       //获得输入框的句柄 RichEdit RichEdit20A RICHEDIT
       HWND get_RichEdit_handle(HWND hChildWnd)
      {
        HWND hAfxWnd = 0;
        HWND hRichEditWnd = 0;
         while((hAfxWnd=FindWindowEx(hChildWnd,hAfxWnd,"AfxWnd42",NULL))!=NULL)
        {
                if((hRichEditWnd=FindWindowEx(hAfxWnd,0,"RichEdit20A",NULL))!=NULL)
                {
                        //AfxMessageBox("找到RichEdit");
                        break;
                }
        }
        return hRichEditWnd;
       }
       谢天谢地!终于找到RichEdit的句柄了!下面可以开始粘一段文字进去了!(兴奋吧?)
       把QQ尾巴文字粘到剪切版中

       ::OpenClipboard(NULL);
        EmptyClipboard();
        // 分配内存空间  
         hMem = GlobalAlloc(GMEM_DDESHARE,sizeof(g_str));
        pStr = (char*)GlobalLock(hMem);
        lstrcpy(pStr, LPCSTR(g_str));
        GlobalUnlock(hMem);
        // 设置剪贴板文本
        SetClipboardData(CF_TEXT, hMem);
        CloseClipboard();
        // 释放内存空间
        GlobalFree(hMem);
         
         //获得对话窗口的坐标 getwindowrect,因为把QQ窗口置顶的时候位置要和它缩小的时候一样。
        ::GetWindowRect(NodeWindow,&rect);
                //把窗口置顶
        ::SetWindowPos(NodeWindow,HWND_TOPMOST,rect.left,rect.top,0,0,SWP_SHOWWINDOW||SWP_NOMOVE||SWP_NOSIZE);
         
         //模拟ctrl+v按键
         keybd_event(VK_CONTROL,(BYTE)0,0,0);
        keybd_event('V',BYTE(0),0,0);
        keybd_event('V',BYTE(0),KEYEVENTF_KEYUP,0);
         keybd_event(VK_CONTROL,MapVirtualKey(VK_CONTROL,0),KEYEVENTF_KEYUP,0);
         
         黏贴完给“发送”按钮发个BM_CLICK消息,尾巴就送出去了。
          到此,我的QQ尾巴就完成了。

4、总结
         我的QQ尾巴技术含量不高,而且还有很多东西没实现,例如,把这个程序做成dll然后用hock拦截QQ窗口的发送消
         息,然后执行QQ尾巴程序等等。。。。。(这些难度较大)整个制作的过程遇到很多问题,但是最终还是得以解决。这个发现问题-
       -解决问题的过程让我很快乐!
         
         感谢大家花时间阅读本文章。
发表于 2007-11-4 21:31 | 显示全部楼层
  原来牛人是这样产生嘀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入后院

本版积分规则

QQ|Archiver|手机版|小黑屋|广告业务Q|工大后院 ( 粤ICP备10013660号 )

GMT+8, 2025-5-12 22:16

Powered by Discuz! X3.5

Copyright © 2001-2024 Tencent Cloud.

快速回复 返回顶部 返回列表