以前写过出来一个软件,但是因为微信的尿性啊,有些重,其他省份使用不了,懒得再改了。所以一直没有发布,今天来仔细分析一波微信网页版的协议。有需求的可以写一下工具。
先放一下我写的成品图。
微信网页版的协议无外乎和QQ网页版协议差不多,但也有不同之处。QQ的网页协议暂不分析,以前曾经在论坛发布的源码前几天好像失效了,有人想叫我再找找问题,我找出来问题,到时候再修改吧。
协议分析开始。
- [GET]https://login.wx.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage&fun=new&lang=zh_CN&_=1540887586026
先说一下URL参数,appid不用管。直接带入。redirect_uri返回URL不用管,直接带入。标红的这个字符串,也不用管,就是一个随机数。
GET提交方式之后返回内容:
window.QRLogin.code = 200; window.QRLogin.uuid = "4ZOQ8OfKLQ==";
“4ZOQ8OfKLQ==” 此处必须记下来,因为这个是扫码的二维码必须携带的参数,方便下个包的调用。
扫码
- [GET]https://login.weixin.qq.com/qrcode/4ZOQ8OfKLQ==
标红的地址,为第一个包所得到的参数。
直接进行了提交,然后这个二维码就出现了。
二维码出现之后,那么接下来的操作就是判断扫码状态。
- [GET]https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=true&uuid=AdHVfxierg==&tip=0&r=1870135597&_=1544318065401
循环响应此包,uuid为第一次发包所得到的UUID。
进行扫码,如果判断扫码成功,登陆成功,那么返回内容:
window.code=200;window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AdSsiKmYz2u_XBWSMkWskH7y@qrticket_0&uuid=AcLnMRh9GQ==&lang=zh_CN&scan=1544318120";
出现window.redirect_uri 返回的URL,就代表明面上已经登陆成功了,但是你的登陆信息还没有得到。
获得关键信息
- [GET]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AdSsiKmYz2u_XBWSMkWskH7y@qrticket_0&uuid=AcLnMRh9GQ==&lang=zh_CN&scan=1544318120
此处请求第三个包所返回的地址,就是登陆成功的地址。在这个地方,得到请求头中的set-cookie和返回中的内容信息才算是真正的登陆成功。
先来看一下返回中的信息:
得到的是一个xml格式的消息,其中<skey><wxsid><wxuin><pass_ticket>保存并记录下来,以便后续包调用。
再来看一下cookie中的消息。
其中比较重要的是webwx_data_ticket=、webwx_auth_ticket=记录下来,以便后续包名发包时带入。
记录下来这些信息之后才算是真正的登陆成功,可以进行一些操作了。
- [POST]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1869988690&pass_ticket=xcWifD9MMB3vKNTM2PBiGWCZhYMhFryW5UK%2BORQTxJwr0spIVaJScdE6W%2BxS59zc
参数中pass_ticket为上一个包所得到的内容,
cookie无需带入。
但是发送的消息如下。
{"BaseRequest":{"Uin":"2402936223","Sid":"mJM MFX2RoB0og8h","Skey":"@crypt_239b7b7c_03d892405af9080758a6a0e1354abbf9","DeviceID":"e387877040871158"}}
Uin为上一个包得到的wxuin
Sid为上一个包得到的wxsid
Skey为上一个包得到的skey
DeviceID为e 15位的随机数。
响应为自己当前登陆的签名,以及昵称,还有最新聊天的用户,以及微信关注的消息。内容太多就不发了。
但是返回的json数据节点【data.SyncKey.List[0].Key】里面的内容必须记录下来,如果没有这些Key值,消息会发送不出去。标红的0值为递增。
记录Key值
- [GET]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=pass_ticket&r=1540953981074&seq=0&skey=sKey
URL中带入pass_ticket、Skey参数,刚才发的包里面已经得到了。至于r就是一个随机数。
返回关注的微信公众号、以前所有的好友json数据。
到了这个阶段就是开始了重头戏,因为要循环判断消息,确定是否有新的消息,而带入的请求这个key值是必不可少的。
发送Key值
- [GET]https://webpush.wx.qq.com/cgi-bin/mmwebwx-bin/synccheck?r=1540974131329&skey=" & sKey & "&sid=" & sid & "&uin=" & wxuin & "&deviceid=e" & 随机数 & "&synckey=1_KEY1|2_KEY2|3_KEY3|1000_KEY1000&_=1541036165840
这个是初始请求,初始请求需要带入Key值,这个Key值的得到是上上一个包所得到的内容。
Cookie需带入wxuin=、wxsid=、webwx_data_ticket=
在这里需记住,这个是第一次发Key值,如果有新消息的话会自动获取并自动生成一个Key值。
返回的消息:
selector为2,有新的消息,那么接下来请求最新消息,就是得到新的消息。
返回Key值
- [POST]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=sid&skey=skey&lang=zh_CN&pass_ticket=pass_ticket
URL中的参数sid为wxsid、skey为skey、pass_ticket为pass_ticket,前面发包已经得到了。
发送
{""BaseRequest"":{""Uin"":" & wxuin & ",""Sid"":""" & wxsid & """,""Skey"":""" & sKey & """,""DeviceID"":""e" & 随机数 & """},""SyncKey"":{""Count"":个数,""List"":[{""Key"":1,""Val"":" & Key1 & "},{""Key"":2,""Val"":" & Key2 & "},{""Key"":3,""Val"":" & Key3 & "},{""Key"":1000,""Val"":" & Key1000 & "}]},""rr"":914483736}
这次的请求有些繁琐,但是也能看得清,这些数据在这之前都已经获得成功了,在这里就不多说了。
uin就是得到的wxuin
Sid就是得到的wxsid
sKey就是得到的skey
DeviceID就是e 15位的随机数。
count就是下面的key有几个key,但是这个时候是不固定的。我就曾经吃过这个地方的亏。
key值就是咱们之前得到的key值。
返回的包如下:
[JavaScript] 纯文本查看 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"AddMsgCount": 0,
"AddMsgList": [],
"ModContactCount": 0,
"ModContactList": [],
"DelContactCount": 0,
"DelContactList": [],
"ModChatRoomMemberCount": 0,
"ModChatRoomMemberList": [],
"Profile": {
"BitFlag": 0,
"UserName": {
"Buff": ""
}
,
"NickName": {
"Buff": ""
}
,
"BindUin": 0,
"BindEmail": {
"Buff": ""
}
,
"BindMobile": {
"Buff": ""
}
,
"Status": 0,
"Sex": 0,
"PersonalCard": 0,
"Alias": "",
"HeadImgUpdateFlag": 0,
"HeadImgUrl": "",
"Signature": ""
}
,
"ContinueFlag": 0,
"SyncKey": {
"Count": 7,
"List": [{
"Key": 1,
"Val": 682044882
}
,{
"Key": 2,
"Val": 682045004
}
,{
"Key": 3,
"Val": 682044823
}
,{
"Key": 11,
"Val": 682043346
}
,{
"Key": 201,
"Val": 1544320212
}
,{
"Key": 1000,
"Val": 1544310122
}
,{
"Key": 1001,
"Val": 1544310196
}
]
}
,
"SKey": "",
"SyncCheckKey": {
"Count": 7,
"List": [{
"Key": 1,
"Val": 682044882
}
,{
"Key": 2,
"Val": 682045004
}
,{
"Key": 3,
"Val": 682044823
}
,{
"Key": 11,
"Val": 682043346
}
,{
"Key": 201,
"Val": 1544320212
}
,{
"Key": 1000,
"Val": 1544310122
}
,{
"Key": 1001,
"Val": 1544310196
}
]
}
}
将最后的7个key值给记录下来。再次循环POST就能进行接收消息的操作了。
获得联系人
- [GET]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?lang=zh_CN&pass_ticket=pass_ticket&r=1540953981074&seq=0&skey=skey
pass_ticket、skey为得到的内容
cookie带入wxuin=、wxsid=,即可返回所有的好友信息。
返回的JSON数据中MemberList[0].UserName 为对方的用户名码,这个必须每一个都得记录下来,不然到时候发送消息的时候确定不了对方是谁。0为递增。
发送消息
- [POST]https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?lang=zh_CN&pass_ticket=76%2F1QjLCPhAUFSojEqCbC5ib0I2Qvt1P6zf%2BE4Gr%2Fqma5Oh937hpTG7rYrrkGZtF
{"BaseRequest":{"Uin":Uin,"Sid":Sid,"Skey":Skey,"DeviceID":DeviceID},"Msg":{"Type":1,"Content":"消息内容","FromUserName":"@0ffa505f57e50f9c3f741d8d06b1dbeb5bba0de6feaaf6897eca14a81618dd95","ToUserName":"@2e7ee0f35577deaa1f43edcebe145f37","LocalID":15 随机数,"ClientMsgId":15 随机数},"Scene":0}
uin就是得到的wxuin
Sid就是得到的wxsid
sKey就是得到的skey
DeviceID就是e 15位的随机数。
FromUserName为自己的wx用户名码
ToUserName为对方的wx用户名码
LocalID:15 15位的随机数
ClientMsgId:15 15位的随机数
返回:
[HTML] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
8
9
{
"BaseResponse": {
"Ret": 0,
"ErrMsg": ""
}
,
"MsgID": "9097829072507170245",
"LocalID": "15443223305630897"
}
ret返回为0就算是消息发送成功了。
另外FromUserName、ToUserName在获得好友的时候会有这个记录。
最后再说一下如何检测好友,对方不收到消息呢,向好友发送时发送以下特殊字符,对方不会收到你的任何消息,但是如果对方将你删除或者拉黑将会显示对方已把你删除(拉黑)
但是因为是一个特殊字符,如果要向对方发送的话还需要进行转码操作。
Url转码:
[HTML] 纯文本查看 复制代码
?
1
ॣ
发送的时候解码发送即可。】
,