微信协议简单调研笔记.docx
- 文档编号:18097050
- 上传时间:2023-04-24
- 格式:DOCX
- 页数:14
- 大小:375.10KB
微信协议简单调研笔记.docx
《微信协议简单调研笔记.docx》由会员分享,可在线阅读,更多相关《微信协议简单调研笔记.docx(14页珍藏版)》请在冰豆网上搜索。
微信协议简单调研笔记
聂永的博客
记录工作/学习的点点滴滴。
微信协议简单调研笔记
前言
微信可调研点很多,这里仅仅从协议角度进行调研,会涉及到微信协议交换、消息收发等。
所谓“弱水三千,只取一瓢”吧。
杂七杂八的,有些长,可直接拉到最后看结论好了。
一。
微信协议概览
微信传输协议,官方公布甚少,在微信技术总监所透漏PPT《微信之道—至简》文档中,有所体现。
纯个人理解:
因张小龙做邮箱Foxmail起家,继而又做了QQMail等,QQMail是国内第一个支持ExchangeActiveSync协议的免费邮箱,基于其从业背景,微信从一开始就采取基于ActiveSync的修改版状态同步协议Sync,也就再自然不过了。
一句话:
增量式、按序、可靠的状态同步传输的微信协议。
大致交换简图如下:
如何获取新数据呢:
1.服务器端通知,客户端获取
2.客户端携带最新的SyncKey,发起数据请求
3.服务器端生成最新的SyncKey连同最新数据发送给客户端
4.基于版本号机制同步协议,可确保数据增量、有序传输
5.SyncKey,由服务器端序列号生成器生成,一旦有新消息产生,将会产生最新的SyncKey。
类似于版本号
服务器端通知有状态更新,客户端主动获取自从上次更新之后有变动的状态数据,增量式,顺序式。
二。
微信Web端简单调试
在线版本微信:
通过Firefox+Firebug组合调试,也能证实了微信大致通过交换SyncKey方式获取新数据的论述。
1.发起GET长连接检测是否存在新的需要同步的数据
会携带上最新SyncKey
返回内容:
window.synccheck={retcode:
"0",selector:
"2"}
selector值大于0,表示有新的消息需要同步。
据目测,心跳周期为27秒左右。
2.一旦有新数据,客户端POST请求主动获取同步的数据
携带消息体:
{"BaseRequest":
{"Uin":
937355,"Sid":
"s7c/sxpGRSihgZAA"},"SyncKey":
{"Count":
6,"List":
[{"Key":
1,"Val":
620943725},{"Key":
2,"Val":
620943767},{"Key":
3,"Val":
620943760},{"Key":
11,"Val":
620942796},{"Key":
201,"Val":
1393208365},{"Key":
1000,"Val":
1393203219}]},"rr":
1393208447374}
会携带上最新的SyncKey,会返回复杂结构体JSON内容。
但浏览端收取到消息之后,如何通知服务器端已确认收到了?
Web版本微信,没有去做。
在以往使用过程中,曾发现WEB端有丢失消息的现象,但属于偶尔现象。
但Android微信客户端(只要登陆连接上来之后)貌似就没有丢失过。
3.发送消息流程
1.发起一个POST提交,用于提交用户需要发送的消息
发送内容:
{"BaseRequest":
{"Uin":
937355,"Sid":
"lQ95vHR52DiaLVqo","Skey":
"A6A1ECC6A7DE59DEFF6A05F226AA334DECBA457887B25BC6","DeviceID":
"e937227863752975"},"Msg":
{"FromUserName":
"yongboy","ToUserName":
"hehe057854","Type":
1,"Content":
"hello","ClientMsgId":
1393988414380,"LocalID":
1393988414380}}
相应内容:
{
"BaseResponse":
{
"Ret":
0,
"ErrMsg":
""
}
"MsgID":
1020944348,
"LocalID":
"1393988414380"
}
1.再次发起一个POST请求,用于申请最新SyncKey
发送内容:
{"BaseRequest":
{"Uin":
937355,"Sid":
"lQ95vHR52DiaLVqo"},"SyncKey":
{"Count":
6,"List":
[{"Key":
1,"Val":
620944310},{"Key":
2,"Val":
620944346},{"Key":
3,"Val":
620944344},{"Key":
11,"Val":
620942796},{"Key":
201,"Val":
1393988357},{"Key":
1000,"Val":
1393930108}]},"rr":
1393988414756}
响应的(部分)内容:
"SKey":
"8F8C6A03489E85E9FDF727ACB95C93C2CDCE9FB9532FC15B"
1.终止GET长连接,使用最新SyncKey再次发起一个新的GET长连接
三。
微信Android简单分析
Windows桌面端Android虚拟机中运行最新版微信(5.2),通过tcpdump/Wireshark组合封包分析,以下为分析结果。
0.初始连接记录
简单记录微信启动之后请求:
11:
20:
35dns查询
返回一组IP地址
11:
20:
35DNS查询
返回一组IP地址,本次通信中,微信使用了最后一个IP作为TCP长连接的连接地址。
11:
20:
35
用于请求服务器获得最优IP路径。
服务器通过结算返回一个xml定义了域名:
IP对应列表。
仔细阅读,可看到微信已经开始了国际化的步伐:
香港、加拿大、韩国等。
具体文本,请参考:
11:
20:
35
获取到最优IP,然后建立到101.227.131.105的TCP长连接
11:
21:
25
POSTHTTP/1.1(application/octet-stream)
返回一个名为“micromsgresp.dat”的附件,估计是未阅读的离线消息
11:
21:
31
POSTHTTP/1.1(application/octet-stream)
大概是资讯、订阅更新等
中间进行一些资源请求等,类似于
GET
图片等一些静态资源都会被分配到域名下面
不明白做什么用途
POSTHTTP/1.1(application/octet-stream)
输出为micromsgresp.dat文件
11:
21:
47
GETHTTP/1.1
返回chunked分块数据
11:
21:
49
POSTHTTP/1.1(application/octet-stream)
1.心跳频率约为5分钟
上次使用Wireshark分析有误(得出18分钟结论),再次重新分析,心跳频率在5分钟左右。
2.登陆之后,会建立一个长连接,端口号为8080
简单目测为HTTP,初始以为是双通道HTTP,难道是自定义的用于双通道通信的HTTP协议吗,网络上可见资料都是模棱两可、语焉不详。
具体查看长连接初始数据通信,没有发现任何包含"HTTP"字样的数据,以为是微信自定义的TCP/HTTP通信格式。
据分析,用于可能用于获取数据、心跳交换消息等用途吧。
这个后面会详谈微信是如何做到的。
2.0初始消息传输
个人资料、离线未阅读消息部分等通过POSTHTTP短连接单独获取。
2.1二进制简单分析
抽取微信某次HTTP协议方式通信数据,16进制表示,每两个靠近的数字为一个byte字节:
微信协议可能如下:
一个消息包=消息头+消息体
消息头固定16字节长度,消息包长度定义在消息头前4个字节中。
单纯摘取第0000行为例,共16个字节的头部:
0000001000100001000000060000000f
16进制表示,每两个紧挨着数字代表一个byte字节。
微信消息包格式:
1.前4字节表示数据包长度,可变值为16时,意味着一个仅仅包含头部的完整的数据包(可能表示着预先定义好的业务意义),后面可能还有会别的消息包2.2个字节表示头部长度,固定值,0x10=163.2个字节表示谢意版本,固定值,0x01=14.4个字节操作说明数字,可变5.序列号,可变6.头部后面紧跟着消息体,非明文,加密形式7.一个消息包,最小16byte字节
通过上图(以及其它数据多次采样)分析:
1.0000-0040为单独的数据包
2.0050行为下一个数据包的头部,前四个字节值为0xca=202,表示包含了从0050-0110共202个字节数据
3.一次数据发送,可能包含若干子数据包
4.换行符\n,16进制表示为0x0a,在00f0行,包含了两个换行符号
5.一个数据体换行符号用于更细粒度的业务数据分割是否蒙对,需要问问做微信协议的同学
6.所有被标记为HTTP协议通信所发送数据都包含换行符号
2.2动手试试猜想,模拟微信TCP长连接
开始很不解为什么会出现如此怪异的HTTP双通道长连接请求,难道基于TCP通信,然后做了一些手脚?
很常规的TCP长连接,传输数据时(不是所有数据传输),被wireshark误认为HTTP长连接。
这个需要做一个实验证实一下自己想法,设想如下:
写一个Ping-Pong客户端、服务器端程序,然后使用Wireshark看一下结果,是否符合判断。
Java版本的请求端,默认请求8080端口:
C语言版本的服务器程序,收到什么发送什么,没有任何逻辑,默认绑定8080端口:
这里有一个现场图:
可以尝试稍微改变输出内容,去除换行符“\n”,把端口换成9000,试试看,就会发现Wireshark输出不同的结果来。
2.3结论是什么呢?
若使用原始TCP进行双向通信,则需要满足以下条件,可以被类似于Wireshark协议拦截器误认为是HTTP长连接:
1.使用80/8080端口(81/3128/8000经测试无效)也许8080一般被作为WEB代理服务端口,微信才会享用这个红利吧。
2.输出的内容中,一定要包含换行字符"\n"
因此,可以定性为微信使用了基于8080端口TCP长连接,一旦数据包中含有换行"\n"符号,就会被Wireshark误认为HTTP协议。
可能微信是无心为之吧。
3.新消息获取方式
1.TCP长连接接收到服务器通知有新消息需要获取
2.APP发起一个HTTPPOST请求获取新状态消息,会带上当前SyncKey地址为:
HTTP/1.1,看不到明文
3.APP获取到新的消息,会再次发起一次HTTPPOST请求,告诉服务器已确认收到,同时获取最新SyncKey地址为:
4.接受一个消息,TCP长连接至少交互两次,客户端发起两次HTTPPOST请求
具体每次交互内容是什么,有些模糊
5.服务器需要支持:
状态消息获取标记,状态消息确认收取标记。
只有被确认收到,此状态消息才算是被正确消费掉
6.多个不同设备同一账号同时使用微信,同一个状态消息会会被同时分发到多个设备上
此时消息请求截图如下:
4.发送消息方式
发送消息走已经建立的TCP长连接通道,发送消息到服务器,然后接受确认信息等,产生一次交互。
小伙伴接收到信息阅读也都会收到服务器端通知,产生一次交互等。
可以确定,微信发送消息走TCP长连接方式,因为不对自身状态数据产生影响,应该不交换SyncKey。
∙在低速网络下,大概会看到消息发送中的提示,属于消息重发机制
∙网络不好有时客户端会出现发送失败的红色感叹号
∙已发送到服务器但未收到确认的消息,客户端显示红色感叹号,再次重发,服务器作为重复消息处理,反馈确认
∙上传图片,会根据图片大小,分割成若干部分(大概1.5K被划分为一部分),同一时间点,客户端会发起若干次POST请求,各自上传成功之后,服务器大概会合并成一个完整图片,返回一个缩略图,显示在APP聊天窗口内。
APP作为常规的文字消息发送到服务器端
∙上传音频,则单独走TCP通道,一个两秒的录制音频,客户端录制完毕,分为两块传输,一块最大1.5K左右,服务端响应一条数据通知确认收到。
共三次数据传输。
音频和纯文字信息一致,都是走TCP长连接,客户端发送,服务器端确认。
四。
微信协议小结
1.发布的消息对应一个ID(只要单个方向唯一即可,服务器端可能会根ID判断重复接收),消息重传机制确保有限次的重试,重试失败给予用户提示,发送成功会反馈确认,客户端只有收到确认信息才知道发送成功。
发送消息可能不会产生新SyncKey。
2.基于版本号(SynKey)的状态消息同步机制,增量、有序传输需求水到渠成。
长连接通知/短连接获取、确认等,交互方式简单,确保了消息可靠谱、准确无误到达。
3.客户端/服务器端都会存储消息ID处理记录,避免被重复消费客户端获取最新消息,但未确认,服务器端不会认为该消息被消费掉。
下次客户端会重新获取,会查询当前消息是否被处理过。
根据一些现象猜测。
4.总体上看,微信协议跨平台(TCP或HTPP都可呈现,处理方式可统一),通过“握手”同步,很可靠,无论哪一个平台都可以支持的很好
5.微信协议最小成本为16字节,大部分时间若干个消息包和在一起,批量传输。
微信协议说不上最简洁,也不是最节省流量,但是非常成功的。
6.若服务器检测到一些不确定因素,可能会导致微启用安全套接层SSL协议进行常规的TCP长连接传输。
短连接都没有发生变化
以上,根据有限资料和数据拦截观察总结得出,啰啰嗦嗦,勉强凑成一篇,会存在一些不正确之处,欢迎给予纠正。
在多次
五。
附录
MicrosoftExchangeActiveSync协议,简称EAS,分为folderrsync(同步文件夹目录,即邮箱内有哪几个文件夹)和sync(每个文件夹内有哪些文档)两部分。
某网友总结的协议一次回话大致示范:
Client:
synckey=0//第一次key为0
Server:
newsynckey=1235434//第一次返回新key
Client:
synckey=1235434//使用新key查询
Server:
newsynckey=1647645,data=*****//第一次查询,得到新key和数据
Client:
synckey=1647645
Server:
newsynckey=5637535,data=null//第二次查询,无新消息
Client:
synckey=5637535
Server:
newsynckey=8654542,data=****//第三次查询,增量同步
∙上页中的相邻请求都是隔固定时间的,如两分钟
∙客户端每次使用旧key标记自己的状态,服务端每次将新key和增量数据一起返回。
∙key是递增的,但不要求连续
∙请求的某个参数决定服务器是否立即返回
微信、手机QQ网络行为简析
作者:
wilbur | 2,551浏览 | 2013/05/08 9:
09下午
阿土对于微信和手机QQ的网络连通性分析
测试环境:
智能手机一部(打开wifi关闭gprs)—->linuxwifi热点—->公网
分析手段:
1.在linux上用tcpdump抓包,用wireshark分析抓到的数据
2.在linux上用iptables阻断特定流量,模拟网络故障,分别模拟了拦截udp53/tcp80/tcp8080/tcp14000/tcp全拦截等各种情况以及他们的组合
3.通过adbshell在手机内执行netstat了解手机网络链接情况
微信网络行为:
1.程序启动后,优先尝试DNS解析特定域名(,,,);
2.如果DNS查询不可用,程序转为使用hardcode的ip链接服务;
3.如果dns可用,返回的ip为根据ISP智能解析的结果,程序使用返回的ip链接服务;
4.程序仅在注册阶段使用https链接,内容不详;
5.程序使用tcp80/8080链接服务器,其中80为http协议,8080为未知协议;
6.80/8080两个端口同时或任何单独一个,均可提供服务;
7.80端口为短链接,8080为长链接,程序会优先使用8080端口;
8.没有使用udp传输数据;
9.当1-2次发送失败时,客户端会弹出提示“当前网络状况不好,是否提交反馈数据”,确认后客户端试图通过web提交反馈数据;
手机qq网络行为:
仅列出跟微信不同之处
1.尝试的域名不同:
,,,;
2.除了80/8080外,还有tcp14000,功能与8080相同;
3.程序会优先尝试80/8080,只有这两个不可用时,才尝试14000;
4.其余同微信;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 协议 简单 调研 笔记