QQ批量自动登录程序的设计

因为自己的QQ号码有好几个,每次重启机子的时候一个一个的登录超级麻烦,而且腾讯老是在偶尔的时候,再把以前已经记住密码的QQ密码给置空,还要重新输入,太麻烦,因此尝试着自己搞一个批量自动登录的程序

以TM2009为例,查看了一下,未登录之前一个窗体,上边两个控件,登录以后,窗体捕获到一个控件,根据这个,首先找到QQ的登录框,输入用户名,密码的位置,获取窗体句柄的具体代码如下:

这里先定义了一个record类型,

1    TQQWnd =   record
2      QQWnd,QStatusWnd: HWND;   // QQ的窗口句柄,QQ的弹出登录状态句柄
3      QQNumWnd, QQPassWnd: HWND;  // QQ号码输入句柄,QQ密码输入句柄
4     end ;
5 

 

 

 1     function  GetQQLoginHwd( var  AQQWnd: TQQWnd): Boolean;
 2     var
 3      WinTitle:  array [ 0 .. 254 of  Char;
 4      WinClass:  array [ 0 .. 254 of  Char;
 5     begin
 6      Result: =  False;
 7      AQQWnd.QQWnd: =   0 ;
 8      AQQWnd.QQNumWnd: =   0 ;
 9      AQQWnd.QQPassWnd: =   0 ;
10      AQQWnd.QQWnd: =  FindWindow( nil ' TM2009 ' );
11       while  AQQWnd.QQWnd <>   0   do   begin
12        AQQWnd.QQNumWnd: =  FindWindowEx(AQQWnd.QQWnd,  0 ' ATL:30A4D1D8 ' nil );
13        AQQWnd.QQPassWnd: =  FindWindowEx(AQQWnd.QQWnd,  0 ' Edit ' nil );
14         if  (AQQWnd.QQNumWnd <>   0 ) and  (AQQWnd.QQPassWnd <>   0 then   begin
15          Result: =  True;
16          FOpened: =  True;
17          Exit;
18         end   else   begin
19          AQQWnd.QQWnd: =  GetWindow(AQQWnd.QQWnd, GW_HWNDNEXT);
20           if  AQQWnd.QQWnd = 0   then  Continue;
21          GetWindowText(AQQWnd.QQWnd, @WinTitle, SizeOf(WinTitle));
22           if  WinTitle <> ' TM2009 '   then  Continue;
23         end ;
24       end ;
25     end ;
26 

 

 

因为腾讯的密码输入框,采用的是低级钩子,然后定时的释放,建立钩子这种方式来防止木马程序去捕获,我尝试了下,直接的用Sendmessage去发送密码信息,没反应,因此这里我采用了SendInput的方式去输入密码,而用户框因为没有做任何的保护措施,所以可以直接的通过发送消息,将QQ账户信息给赋值过去,具体代码为

 

 1        SetForegroundWindow(QQWnds.QQWnd);  // QQ窗体设置为活动窗体
 2         // 设置QQ号码
 3         SendMessage(QQWnds.QQNumWnd,WM_SETFOCUS, 0 , 0 );  // 聚焦至QQ号码输入框
 4        Sleep( 20 );
 5        SendMessage(QQWnds.QQNumWnd,WM_SETTEXT, 0 ,LPARAM(FQQNum));  // 设置QQ号码
 6 
 7        SendMessage(QQWnds.QQPassWnd,WM_SETFOCUS, 0 , 0 );  // 聚焦密码输入框
 8        Sleep( 20 );
 9         // 设置QQ密码
10        SIKeyInput(FQQPass,  10 );  // QQ密码采取SENDINPUT方式
11 
12 
13 

 

 

解下来要操作的,就是设置登录方式了,譬如说“我在线上”,“隐身”等状态,由于腾讯的登录窗体是采用的GUI,所以是捕获不到句柄的,只能通过坐标来捕获,我之前的时候,是用的固定坐标,然后有的电脑可以用,有的不能用,后来才发现,是由于腾讯的界面可以拉动,只要一拉动,他的坐标位置就变了,因此我这里采取相对坐标,根据QQ密码框的坐标,来设置点击的坐标。腾讯的状态是在窗体上点击以后,弹出一个跟登录框平级的窗口,因此点击以后,需要检测是否弹出选择状态窗口,找到那个窗口句柄以后,再发送相应的点击命令,这样就完成整个的流程了

 

 1  const
 2    QQStatusYArray:  array [ 0 .. 5 of  Integer =  ( 19 38 62 86 105 131 );
 3 
 4 
 5        ClickTimes: =   0 // 为防止有的时候点击过程中出现其他不可预料的错误,这里可以重复点击三次
 6        QQWnds.QStatusWnd: =   0 // 设置QQ状态初始句柄为0
 7         // 鼠标点击
 8         while  ClickTimes < 3   do   begin
 9          PostMessage(QQWnds.QQWnd,$ 201 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQNumRec.Bottom -  QQRect.Top + 21 , 4 ) + IntToHex(QQNumRec.Left - QQRect.Left + 25 , 4 )));  // 发送点击消息,这里如果采用SendMessage,会死线程,因此我采用了PostMessage
10          PostMessage(QQWnds.QQWnd,$ 202 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQNumRec.Bottom -  QQRect.Top + 21 , 4 ) + IntToHex(QQNumRec.Left - QQRect.Left + 25 , 4 )));
11          Sleep( 200 );
12          QQWnds.QStatusWnd: =  FindWindow( ' TXGuiFoundation ' , ' TXMenuWindow ' );  // 检测是否存在QQ设置状态窗体
13           if  QQWnds.QStatusWnd <> 0   then   begin
14             try
15              PostMessage(QQWnds.QStatusWnd,$ 201 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQStatusYArray[FQQStatus], 4 ) + IntToHex( 27 , 4 )));  // 如果存在窗体,直接的发送点击信息
16              PostMessage(QQWnds.QStatusWnd,$ 202 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQStatusYArray[FQQStatus], 4 ) + IntToHex( 27 , 4 )));
17             except
18             end ;
19            Break;
20           end ;
21          ClickTimes: = ClickTimes + 1 ;
22         end ;
23         if  QQWnds.QStatusWnd = 0   then   begin   // 如果一直没有捕获到设置状态窗体,程序则自动退出
24          Task.Comm.Send(MSG_QQ_ERR, IntToStr(QQRect.Left) + ' ' +  IntToStr(QQRect.Top) +   ' ' +  IntToStr(QQRect.Right) +   ' ' +  IntToStr(QQRect.Bottom)
25             + ' ' +  IntToStr(QQNumRec.Left) + ' ' +  IntToStr(QQNumRec.Top) +   ' ' +  IntToStr(QQNumRec.Right) +   ' ' +  IntToStr(QQNumRec.Bottom)
26             +  IntToStr(QQNumRec.Bottom -  QQRect.Top + 21 ) + ' 设置状态失败 ' );
27  //         Task.Comm.Send(MSG_QQ_ERR, IntToStr(QQNumRec.Left - QQRect.Left + 25 ) + ' ' +  IntToStr(QQNumRec.Bottom -  QQRect.Top + 21 ) + ' 设置状态失败 ' );
28          Exit;
29         end ;
30 

 

 

最后,直接的点击登录按钮就可以了,这个地方,也是要计算相对于密码输入框的坐标

 

1         // 点击登录按钮
2         try
3          PostMessage(QQWnds.QQWnd,$ 201 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQNumRec.Bottom -  QQRect.Top + 114 , 4 ) + IntToHex(QQNumRec.Left - QQRect.Left + 64 , 4 )));
4          PostMessage(QQWnds.QQWnd,$ 202 ,MK_LBUTTON,StrToInt(# 36 + IntToHex(QQNumRec.Bottom -  QQRect.Top + 114 , 4 ) + IntToHex(QQNumRec.Left - QQRect.Left + 64 , 4 )));
5         except
6         end ;
7 

 

 

至此,整个的流程完毕了,最后,还可以增加上检测该QQ号码是否已经登录

以下是最后出来的界面,我直接的将QQ信息保存在数据库当中,密码采用了AES加密,所以也不用担心密码信息被泄

可以点击这里下载QQ批量下载

本文出自 “痛苦的转变” 博客,转载请与作者联系!

你可能感兴趣的:(qq,职场,自动登录,批量,休闲)