1. 为什么抓不到快手的包?聊聊QUIC这个“拦路虎”
如果你最近尝试过用Charles或者Fiddler去抓取快手App的网络请求,大概率会一脸懵:怎么除了几个零星的无用请求,核心的API数据一个都看不到?我之前也卡在这个问题上很久,一度怀疑是自己的代理设置错了,或者手机证书没装好。折腾了半天才发现,真正的“罪魁祸首”是QUIC协议。
简单来说,QUIC你可以把它理解成HTTP/2的“超级进化版”,由Google大力推动。它基于UDP协议,而不是我们熟悉的TCP。对我们抓包者而言,最要命的一点是:大多数传统的抓包工具(如Charles、Fiddler)默认只监听和解析TCP流量,对UDP上的QUIC协议束手无策。所以,当快手App使用QUIC与服务端通信时,你的抓包软件就像戴上了隔音耳塞,什么也听不见。
那快手为什么偏爱QUIC呢?从用户体验角度,QUIC确实厉害。它解决了TCP的一些老毛病,比如“队头阻塞”——一个数据包丢了,后面所有包都得等着。QUIC在连接建立速度(尤其是首次握手,0-RTT或1-RTT)、多路复用、前向纠错等方面优势明显,能让视频加载更快、直播更流畅。但对于我们做逆向分析、安全测试或者单纯想研究一下接口的人来说,这就成了一堵墙。
所以,我们的核心思路就从“如何抓QUIC包”转变为:能不能让快手不用QUIC,退回到我们熟悉的HTTPS(基于TCP)? 答案是肯定的。这就是“协议降级”的思路。快手Android版使用了Chromium的网络库Cronet,这个库是支持QUIC的,但它的行为可以通过配置来控制。我们的目标就是“骗过”快手,让它加载一个“禁用QUIC”的配置,从而乖乖地走HTTPS通道,这样流量就能被我们的代理工具轻松捕获了。
2. 核心武器:Xposed框架与Hook原理简介
要让一个App改变它既定的网络行为,我们不可能去修改它的安装包(那太麻烦且每次更新都要重做)。我们需要一种运行时动态修改其逻辑的方法,这就是Xposed框架的用武之地。你可以把Xposed理解成一个给Android系统开的“上帝模式”外挂。它允许我们在任何App(包括系统本身)的代码执行过程中,插入我们自己的代码片段,从而改变其原有的行为。
这个过程叫做“Hook”(挂钩)。想象一下,App的代码像一条预设好的流水线。Hook就是在流水线的某个关键工位,安插我们自己的“工人”。当程序执行流经过这个工位时,我们的工人可以先于、后于或者完全替代原来的工人进行操作,比如检查传递的“原料”(参数)、替换“产品”(返回值),甚至直接改变“生产工艺”(执行逻辑)。
在本次实战中,我们要Hook的目标,就是快手App中负责初始化Cronet网络引擎的那个方法。我们要在这个方法里,把原本可能包含"enable_quic":true的配置JSON字符串,替换成我们精心构造的、明确设置了"enable_quic":false的配置。这样,当Cronet库被初始化时,它读取到的指令就是“禁用QUIC”,从而自然降级到使用HTTPS。
准备工作很简单:你需要一台已经Root的Android手机或模拟器,并在上面安装好Xposed框架(或者它的衍生版本如EdXposed、LSPosed)。然后,你需要开发一个非常简单的Xposed模块。这个模块不需要任何界面,它的全部使命就是在快手App启动时,把我们写好的Hook代码“注射”进去。下面我会给出最精简的模块代码框架。
3. 寻找关键Hook点:深入Cronet配置的加载过程
这是整个过程中最需要耐心和技巧的一步。我们得找到快手App里,哪个类、哪个方法负责处理Cronet的配置信息。原始文章里直接给出了一个类名:j.e0.e0.f.e。但这是经过混淆的,不同版本快手的类名可能完全不同。所以,掌握寻找方法比记住这个类名更重要。
我常用的工具是Jadx-GUI,这是一个反编译APK的神器。把从手机里提取出来的快手APK文件拖进去,它会将字节码转换成可读性较高的Java代码。由于代码被混淆了,所有类名、方法名都变成了a.b.c.d这种无意义的字符串,直接搜索“quic”或“cronet”可能一无所获。
404



被折叠的 条评论
为什么被折叠?



