微信安卓协议分析笔记

本文详细记录了微信安卓版的协议分析过程,从查阅资料、准备工作到客户端二次打包、网络抓包,最后深入进行协议解析,揭示了微信通信的秘密。
摘要由CSDN通过智能技术生成

一、查资料

        网上没找到SDK可以分析,关于微信安卓协议的文章也比较少,比较有用的是<微信交互协议和加密模式研究>,这篇论文里介绍了微信使用RSA2048与AES-CBC-128结合的加密算法以及使用protobuf编码格式传输数据;<微信协议简单调研笔记>帖子里提到微信使用长短链接结合的网络通讯方式以及基于sync key的消息同步机制;<基于TLS1.3的微信安全通信协议mmtls介绍>详细讲解了类似于https中TLS作用的mmtls协议;<微信安卓客户端逆向分析>通过举例拦截聊天记录详细演示了安卓微信客户端分析的过程.

二、准备工作

        工具除了安卓反编译常用打包解包软件以及查看java代码的软件,还可以用XSearch方便在大量smali汇编文件中快速搜索字符串,Wireshark用于抓包,Android Studio动态调试smali汇编代码,IDA静态分析so文件,WinHex用于编辑二进制文件.
       微信底层使用自家开源的跨平台通讯库mars,该库包含xlog模块,详尽记录了微信几乎所有主要函数调用流程,开启log可以极大地方便动态分析,研究mars库也有助于理解微信与服务器交互流程.
       由于mmtls无法中间人攻击,所以抓包无法获取短链接HTTP通讯的明文数据;考虑到兼容性微信允许在不使用mmtls的情况下通讯,所以关闭mmtls有助于协议分析.
       由于长链接含有包头不利于分析,考虑到稳定性微信允许在不使用长链接的情况下通讯,所以禁用长链接有利于协议分析.

三、二次打包客户端

        微信允许非官方签名的客户端运行,但是会校验签名并上报异常数据.最近因使用非官方客户端封号的风控策略越来越严格,运行二次打包客户端时要做好被封号准备,或者使用XP插件Hook代码,或者patch掉获取软件签名的代码或者禁掉上传异常数据的封包,总之这不是本文的重点.如果反编译工具直接打包失败,可以只重新编译dex文件,然后替换到原来的apk中.
       从mars库的Xlog文档中可以知道setConsoleLogOpen接口负责开启控制台log,在反汇编代码中搜索这句代码的调用"->setConsoleLogOpen",找到XLogSetup.smali文件直接修改Lcom/tencent/mars/xlog/Xlog;->setConsoleLogOpen的调用参数即开启log.搜索getLogLevel最终可以在Lcom/tencent/mm/sdk/platformtools/下面找到输出Log等级的定义,从6改为0即可打印所有等级的log.logcat里可以通过"MicroMsg""mars"两个tag来分别过滤java层和native层的log.
       运行开启Log的客户端,过滤tag为"mmtls"的日志,可以找到"Java_com_tencent_mars_mm_MMLogic_setMmtlsCtrlInfo"函数打印的log:
1
I/mars::mmext(12496): [com_tencent_mars_mm_MMLogic_Java2C.cc, Java_com_tencent_mars_mm_MMLogic_setMmtlsCtrlInfo, 299]:j_use_mmtls=1
       从函数名可以猜出这是java调用jni控制开启mmtls的接口,在反汇编代码中搜索";->setMmtlsCtrlInfo"找到调用的代码,修改参数为0关闭mmtls.
       从mars库中可以看出,长链接使用mars/stn/src/longlink.cc文件的LongLink::__RunConnect函数连接服务器,解压apk搜索字符串"longlink.cc"可知mars库编译出的文件为libwechatnetwork.so,在二进制文件中结合IDA patch掉该函数返回值可以禁用长链接;从mars文档也可以看出上层需要调用mars::stn::MakesureLonglinkConnected();启用长链接,在smali代码中搜索调用";->makesureLongLinkConnected"的代码注释掉也可关闭长链接.

四、抓包

        使用安卓模拟器或用手机连接电脑开启的wifi,运行二次打包处理的客户端,使用Wireshark工具即可抓到微信短链接的HTTP协议封包了.比如登录包可以抓到使用POST方法向/cgi-bin/micromsg-bin/manualauth 发送了1183字节长度的数据,数据是被加密的:


       <微信安卓客户端逆向分析>文章中提到数据是被libMMProtocalJni.so这个库加密的,使用IDA查看该库的jni接口:

可以看到"Java_com_tencent_mm_protocal_MMProtocalJni_pack"很可能是封包加密的接口,在smali反汇编代码中搜索调用该接口的代码"MMProtocalJni;->pack"如下:

根据log tag"RemoteReq"以及"reqToBuf using protobuf ok"可以猜测这里就是protobuf明文加密封包的地方.接下来可以使用AS在smali这句代码上下断点观察参数与返回值,如果配置调试环境有困难,可以在smali代码中插log将参数与返回值打印并保存下来,方便后面分析.其中第二个参数类型是PByteArray,这是自定义的类型,需要打印的字节数组为该对象的value成员变量;使用Log.d在控制台打印时默认有4000字节的长度限制,超过的部分无法输出,插入log时注意将长log拆分多行输出.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#参数1:logtag,参数2:需要打印的bytes
.method  public  static  logX(Ljava/lang/String;[B)V
     .locals 8
     .prologue
     if -eqz p1, :cond_1
     #如果参数p1是PByteArray,要取其成员变量value
     #iget-object v1, p1, Lcom/tencent/mm/pointers/PByteArray;->value:[B
     move-object v1, p1
    
  • 9
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ios and Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值