QQ Chat Robot Bulk Tool (Java Edition) (i)

Source: Internet
Author: User

This is recently because of interest to write small things, most of the Internet is easy language version, Java only version is also old, the old version of the WEBQQ protocol early failure, so now I wrote a latest version of. To achieve mass and auto-reply messages and more custom features, first of all to achieve landing QQ, here is mainly about how to analyze the QQ protocol and how to log in.

I do not use a very professional clutch tool, in fact, now the browser generally can see the main content of the Get,post request, and we need is the requested content and address, so a 360 browser or Google browser enough for us to analyze.

First, analyze the process and then talk about the method. The first step to login WEBQQ site, we will see the login interface, open F12, every time will execute a request, presumably is to determine the left side of the QR code is invalid method, but this is not related to the landing, directly ignored.


After filling in the account, lose the input box focus, will trigger a request, returned a string, the returned string may be to execute some JS method (probably, I do not know), but this is not important, first look at the picture:

This request is to determine whether the account needs to fill in the image verification code to log in. Do not look outside the method name, inside the first parameter 0 means do not need to fill in the Image verification code landing, the second parameter to write down, equivalent to the login to use the verification code (but it is different from the image verification code, if you need to send a request for picture verification code to obtain the picture, and then according to the letter in the picture to fill And here is equivalent to omit this section, can be understood as the server directly tell you the verification code is what, the following will introduce the need for picture verification Code of the process), the third parameter is your account hexadecimal value, but not related to the login link, the last 2 parameters what use I do not know, but the main landing link is irrelevant.

In order to require verification code to log on the returned data, the first parameter is 1 for the need to verify the code (then send a request to obtain a verification code picture), the second parameter to write down, and so on as to get the picture code request parameters passed to the server.


At this point you need to send a request to obtain a picture verification code, such as:


Get to the verification code after the completion of the password login, but the landing is divided into a few steps, first landing, the first to return the success of the parameter, 0 that success can be executed down, 4 that is, the code error, 3 is the account password error. The 3rd parameter is a successful callback method, which is the one you want to send immediately after the first step is successfully logged in. If the first step failed to login, there will be no callback method, the third parameter returned is 0, it is not clear.


If the first step is successful, the next request is sent, and the requested address is the 3rd parameter (URL link) returned after the first successful login. This step is necessary, to update the cookie (follow-up), or the second step to the landing must fail.

This step does nothing to return the results, only to update the cookie, for the second step to login.

Next to get a parameter vfwebqq, this parameter is not related to the login, but you have to get QQ friends List and group list must be brought on ( Note: The second step will also return this parameter, but the request to get VFWEBQQ different, But the parameters that really get the buddy list and the group list are the one that this step gets, possibly the result of the most recent update .


Next is the last step, the second landing, if the return success, the landing QQ will be squeezed offline, the first parameter of 0 means that the login success (in the process of QQ Landing, the return of the JSON data Retcode Basic representative return results, 0 is successful), the parameters returned in the following methods are introduced.


A summary of the landing process is:

1. Determine if a verification code is required to log in, if necessary, first obtain the verification code picture.

2. Fill out the form information to complete the first landing.

3. Perform the callback method (send request) after the first step login is successful.

4. Get VFWEBQQ. (This parameter is not required if you want to make an auto-reply robot, but if you want to do mass software you need to get a list of friends and groups, you have to get this parameter; As for why this step is in the first step of landing and the second step in the middle is because the page QQ is in this order to send the request, What's the effect of changing the order? I don't know, but at least it won't affect the second landing.

5. The second step to landing, if the successful landing success.

The above is only the process analysis, if the future WEBQQ protocol changes, in theory, can follow this process to catch the package re-analysis, should be changed to change the parameters, change the method of the link on the small problem, at least 13 years to the present process is nothing too much change.


The following describes the Java implementation method, the entire communication process is implemented by sending HTTP requests, I see the online approach is mostly their own encapsulation HttpURLConnection class send HTTP requests, but I use defaulthttpclient this class, Additional jar packages need to be referenced. I'll just introduce myself to the way I write.

1. Check if a verification code is required

Request url:https://ssl.ptlogin2.qq.com/check?pt_tea=1&uin=2368295990&appid=501004106&js_ver=10124 &js_type=0&login_sig=&u1=http%3a%2f%2fw.qq.com%2fproxy.html&r=0.7602819891180843request Method: GET
Here is a GET request, in addition to the UIn to be set to their own account, the other parameters can be fixed, some of the parameters, some are random parameters, the most insurance is not changed ....

The return string is, if no verification code is required, the second parameter is logged (that is! KBK, each access gets a different value).

PTUI_CHECKVC (' 0 ', '! KBK ', ' \x00\x00\x00\x00\x8d\x29\x54\x36 ', ' 2C6BF125C7708D33CC7C9BEA99A9B5F6FD7E7D3F3F8E676CBFF24BB0845DE8CEFAF75B88EA5EFD5D36CAA2D34B997D0EE8C7B638757AF32A ' , ' 0 ');
If a verification code is required, that is, the first parameter returns 1, the second parameter is logged as the next request to send the parameter (that is, jfmgyuolfstyrbtmi9i2ui8apugejxo4a1l3oaj1ksu3vkqfdz8w8g**)

PTUI_CHECKVC (' 1 ', ' jfmgyuolfstyrbtmi9i2ui8apugejxo4a1l3oaj1ksu3vkqfdz8w8g** ', ' \x00\x00\x00\x00\xc3\x54\x60\x81 ') , ', ' 0 ');

Send a request to get a CAPTCHA picture:

Request url:https://ssl.captcha.qq.com/getimage?aid=501004106&r=0.008850367739796638&uin=3277086849 &cap_cd=jfmgyuolfstyrbtmi9i2ui8apugejxo4a1l3oaj1ksu3vkqfdz8w8g**request Method:GET
The request is still get,uin as the account, CAP_CD is the parameter just now. At this time to return the image of the binary data stream, and then see how to deal with the picture, I first attached my way to handle the picture, in fact, the data stream is written into the picture file, saved in the local, and then displayed to the interface. The pixel of the verification code is generally 130*53,zoominimage (path) is to reduce the image, easy to display to the interface, or in the foreground to change the resolution picture is always displayed incomplete. Because I do not deal with the swing interface picture, so the processing technique is rather poor, directly ignore it.
/** * @title generate pictures from binary string * @param data * Generate a binary string of pictures * @param fileName * Picture name (full path) * @param type * Picture type * @return */public static void SaveImage (string data, String fileName, String type) {BufferedImage image = new BufferedImage (53,bufferedimage.type_byte_binary); Bytearrayoutputstream Byteoutputstream = new Bytearrayoutputstream (); try {imageio.write (image, type, Byteoutputstream ); byte[] bytes = hex2byte (data); String Path = System.getproperty ("User.dir") + "/resources/img/" + fileName; String Respath = System.getproperty ("User.dir") + "/resources/img/temp.jpg"; Randomaccessfile file = new Randomaccessfile (path, "RW"), File.write (bytes); File.close (); zoominimage (path);//Shrink picture} catch (IOException e) {e.printstacktrace ();}} /** * Reformat byte * * @param s * @return */public static byte[] Hex2byte (String s) {byte[] src = s.tolowercase (). GetBytes (); byte[] ret = new Byte[src.length/2];for (int i = 0; i < src.length; i + = 2) {byte hi = src[i];byte low = Src[i + 1];hi = (byte) ((Hi >= ' a ' && hi <= ' f ')? 0x0a + (Hi-' a '): Hi-' 0 '); low = (byte) ((Low >= ' a ' &amp ;& low <= ' F ')? 0x0a + (Low-' a '): Low-' 0 '), RET[I/2] = (byte) (Hi << 4 | low);} return ret;}
Attach the method of sending the HTTP request:

private static Cookiestore cs = null;//Store The most recent cookie with this cookie the next time the HTTP request is sent
Receive Message and Cookiepublic static object[] Gethttpdataandcookie (String URL) throws Exception {defaulthttpclient client = new Def Aulthttpclient (); HttpGet httpget = new HttpGet (URL); Httpclientparams.setcookiepolicy (Client.getparams (), cookiepolicy.browser_compatibility);//Set Cookiestoreif (cs! = NULL) {Client.setcookiestore (CS);} HttpResponse HttpResponse = Client.execute (httpget);//Save cookiestorecs = Client.getcookiestore (); Httpentity httpent = httpresponse.getentity (); String code = string.valueof (Httpresponse.getstatusline (). Getstatuscode ()); String Line; StringBuffer sb = new StringBuffer ();//Get cookielist<cookie> cookies = ((abstracthttpclient) client). Getcookiestore (). GetCookies (); hashmap<string, string> map = new hashmap<string, string> (), if (!cookies.isempty ()) {for (int i = 0; i < CO Okies.size (); i++) {map.put (Cookies.get (i). GetName (), Cookies.get (i). GetValue ());}} if (httpent! = null) {BufferedReader BR = new BufferedReader (New InputStreamReader (Httpent.getcontent (), "UTF-8 ") (line = Br.readline ())! = null) {sb.append (line);} Br.close ();} return new object[] {sb.tostring (), Code, map};}
It is important to pay attention to this parameter, that is, the most recent request to obtain the cookie, the next time you send a request must be brought! The first few steps may not be wrong, but the next few steps have been unsuccessful is probably the reason why the cookie is not integrated (I was stuck here for a long time). Map is the cookie I will return to do the processing turned into HashMap because some places store the returned cookie field as a parameter for the next request. In the overall process of the first step, you need to get a parameterptvfsession。 If no verification code is required to log in, this parameter is extracted from the cookie returned by the detection verification code, as follows:

Ptvfsession = ((hashmap<string, string>) response[2]). Get ("ptvfsession");
If a verification code is required to log in, it is extracted from the cookie returned by the image, as in the same way, the cookie is obtained after the request is sent, and then the value of the specified field is obtained.
2. First time Login

Request URL: https://ssl.ptlogin2.qq.com/login?u=3277086849&p= nrjiisex0-13yk3oc5ibhwkidogp3pbado0fxhvcvxz49bom8qvdrkvrslq0evw*vuigbqzielir18cw* Q5nv9zr4vsxiwko99lchjvug3dijiasj5ib9zvzuvhwd7lsvcy8dgvsaodgjqf0wg0izapvevfsgiwzcuq7xsdrgezjrypxcuejb5ofekakrehbx9csjq5zvb uasd8jqpnvew__&verifycode=uwno&webqq_type=10&remember_uin=1&login2qq=1&aid=501004106& u1=http%3a%2f%2fw.qq.com%2fproxy.html%3flogin2qq%3d1%26webqq_type%3d10&h=1&ptredirect=0&ptlang= 2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-21-1678643& Mibao_css=m_webqq&t=1&g=1&js_type=0&js_ver=10124&login_sig=&pt_randsalt=0&pt_vcode _v1=0&pt_verifysession_v1=h02b7ejxn9dccz7wqzlvnwbqweqlvaygwimcvohr2v5zchm7iphi63jnnsdf3o5gq7serlwot_cd_ Ijonlbizh3wypecsvauno1request Method:get 
is still a GET request, u that is the account, p that is encrypted after the password (and so on how to encrypt), verifycode that is the verification code (4-bit, if there is a picture verification code, the letter is filled in the picture, do not need to fill in the value of the previous return, that is!) Beginning of the 4-bit), the middle of a string of parameters can not be changed, the result of the parameters ptvfsession for the first step we get to the ptvfsession.
The string returned in this step is:

PTUICB (' 0 ', ' 0 ', ' http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=3277086849&service=login& nodirect=0&ptsigx= A8f07aea84f23d76363c625b3aa1da48fbb21288078e3229e331955dd64727440da4b0892214efa457a69685a910a2592fb29aa6896121bfbcac6e0bf 88dff1e&s_url=http%3a%2f%2fw.qq.com%2fproxy.html%3flogin2qq%3d1%26webqq_type%3d10&f_url=&ptlang= 2052&ptredirect=100&aid=501004106&daid=164&j_later=0&low_login_hour=0&regmaster=0& Pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0 ', ' 0 ', ' Login successful! ', ' Scumvirus ');
0 is successful, and the 3rd parameter is the URL address of the callback method.

This step still takes a parameter based on the returned cookie-ptwebqq.

The following describes how to encrypt the password, the encryption method is implemented on the JS, and then attach the JS file (may change once in a while, but there will always be a great God to crack it). I encrypt the password by calling the Getencryption () method directly in JS, and attach the method of calling JS:

/** * Executes the JS function to get the value of the desired value *  * @param paras * @return * @throws scriptexception * @throws filenotfoundexception * @throws N Osuchmethodexception */public static string MdP (string p, string account, string code) {Object T = null;try {Scriptenginem Anager m = new Scriptenginemanager (); ScriptEngine se = M.getenginebyname ("javascript"); Se.eval (new FileReader (New File ("Resources/js/qqrsa.js")); t = Se.eval ("Getencryption (\" "+ P +" \ ", \" "+ account +" \ "," "" + code + "\") "); return t.tostring ();} catch (Exception e) {e.printstacktrace ();} return t.tostring ();}
Where P is an unencrypted password, account is QQ accounts, code is Verifycode, that is, the verification code, ibid. The returned string is the encrypted password. Attached JS file: qqrsa.js

3. Execute callback method Update cookie

Request url:http://ptlogin4.web2.qq.com/check_sig?pttype=1&uin=3277086849&service=login&nodirect=0 &ptsigx= A8f07aea84f23d76363c625b3aa1da48fbb21288078e3229e331955dd64727440da4b0892214efa457a69685a910a2592fb29aa6896121bfbcac6e0bf 88dff1e&s_url=http%3a%2f%2fw.qq.com%2fproxy.html%3flogin2qq%3d1%26webqq_type%3d10&f_url=&ptlang= 2052&ptredirect=100&aid=501004106&daid=164&j_later=0&low_login_hour=0&regmaster=0& Pt_login_type=1&pt_aid=0&pt_aaid=0&pt_light=0request Method:get
Or get method, the URL address is the first step to the return address, do not need to log any parameters, as long as you do not forget to update the cookie again.

4. Get vfwebqq, let's write it here, lest we introduce it later.

Request url:http://s.web2.qq.com/api/getvfwebqq?ptwebqq= 9d37ec0c729300bb5dbd927c917f0e851794662e9164c2e6fadab64cea4f6208&clientid=53999199&psessionid=&t= 1432729913114Request method:getreferer:http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1

The method is still get,ptwebqq the first step to get to, ClientID is a 8-9-bit arbitrary value,Psessionid is empty, T is the current timestamp. But add a request header here:

Httpget.setheader ("Referer", "http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1");
The return value is in JSON format and gets ptwebqq directly after parsing.

{"Retcode": 0, "result": {"VFWEBQQ": " A57e6b8ea3409910fb139d5949b850e47879e71f133b6aa5e7c593c1724343ae8789f9f0c5286f91 "}}
5. Second Step Login

Request url:http://d.web2.qq.com/channel/login2request method:postcontent-type:application/ X-www-form-urlencodedreferer:http://d.web2.qq.com/proxy.html?v=20130916001&callback=1&id=2form-data:r= {"PTWEBQQ": "9d37ec0c729300bb5dbd927c917f0e851794662e9164c2e6fadab64cea4f6208", "ClientID": 53999199, "Psessionid" : "", "status": "Online"}
Post request, URL connection is simple, but you must set Content-type to application/x-www-form-urlencoded, set referer:http://d.web2.qq.com/proxy.html v=20130916001&callback=1&id=2, attach My Code:

public static synchronized string[] Posthttpdata (string URL, string data) throws Exception {//POST request Defaulthttpclient CLI ent = new Defaulthttpclient (); HttpPost Postjson = new HttpPost (URL);p ostjson.setheader ("Referer", "http://d.web2.qq.com/proxy.html?v=20130916001 &callback=1&id=2 "); Httpclientparams.setcookiepolicy (Client.getparams (), cookiepolicy.browser_compatibility); Client.getParams (). Setparameter (Coreconnectionpnames.connection_timeout), Client.getparams (). Setparameter ( Coreconnectionpnames.so_timeout, 5000); stringentity entity = new Stringentity (data), Entity.setcontenttype ("application/x-www-form-urlencoded"); Postjson.setentity (entity);//Set Cookiestoreif (cs! = null) {Client.setcookiestore (CS);} Get the returned JSON packet HttpResponse HttpResponse = Client.execute (Postjson); Httpentity httpent = httpresponse.getentity ();//Save cookiestorecs = Client.getcookiestore (); String code = string.valueof (Httpresponse.getstatusline (). Getstatuscode ()); String Line; StringBuffer sb = new StringbuffeR (); if (httpent! = null) {BufferedReader BR = new BufferedReader (New InputStreamReader (Httpent.getcontent (), "UTF-8")); while (line = Br.readline ())! = null) {sb.append (line);} Br.close ();} return new string[] {sb.tostring (), Code};}
Here are the parameters that are taken with the post:

String obj = "r={\" ptwebqq\ ": \" "+ ptwebqq +" \ ", \" clientid\ ":" + ClientID + ", \" psessionid\ ": \" \ ", \" status\ ": \" Online\ "} ";
where "r=" can not be lost, or not recognized, can not be successful landing. The previous 3 parameters are described earlier, the last parameter is the login state, online is on-line, hidden is stealth.
If the login is successful, return:

{"Retcode": 0, "result": {"UIn": 3277086849, "CIP": 1899593934, "index": 1075, "Port": 53012, "status": "Online", "VFWEBQQ" : "0f28abebb129b3e77be531d95640217425dfcb9b65faf36108f136239b4df2efdb69865776ba26f0", "Psessionid": " 8368046764001d636f6e6e7365727665725f77656271714031302e3133392e372e313630000012a800000aef026e0400816054c36d0000000a4042564 56156376766746d000000280f28abebb129b3e77be531d95640217425dfcb9b65faf36108f136239b4df2efdb69865776ba26f0 "," User _state ": 0," F ": 0}}
Where just record thePsessionid, you will need to send the message later.

If the final step succeeds, then you have successfully landed QQ. After that, there will be time to introduce the mass message and auto-reply function.









QQ Chat Robot Bulk Tool (Java Edition) (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.