QQ批量自动登录程序的设计
因为自己的QQ号码有好几个,每次重启机子的时候一个一个的登录超级麻烦,而且腾讯老是在偶尔的时候,再把以前已经记住密码的QQ密码给置空,还要重新输入,太麻烦,因此尝试着自己搞一个批量自动登录的程序
以TM2009为例,查看了一下,未登录之前一个窗体,上边两个控件,登录以后,窗体捕获到一个控件,根据这个,首先找到QQ的登录框,输入用户名,密码的位置,获取窗体句柄的具体代码如下:
这里先定义了一个record类型,
2 QQWnd,QStatusWnd: HWND; //QQ的窗口句柄,QQ的弹出登录状态句柄
3 QQNumWnd, QQPassWnd: HWND; //QQ号码输入句柄,QQ密码输入句柄
4 end;
5
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账户信息给赋值过去,具体代码为
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密码框的坐标,来设置点击的坐标。腾讯的状态是在窗体上点击以后,弹出一个跟登录框平级的窗口,因此点击以后,需要检测是否弹出选择状态窗口,找到那个窗口句柄以后,再发送相应的点击命令,这样就完成整个的流程了
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
最后,直接的点击登录按钮就可以了,这个地方,也是要计算相对于密码输入框的坐标
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批量下载
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?