免责声明
1、本贴仅作为技术讨论,本人不会利用以下技术盈利、或从事任何侵害该网站的行为。
2、如觉得此贴不妥,请联系本人将第一时间删除。
样本地址
aHR0cHM6Ly90di5xcS5jb20v
前言
大概是今年上半年,某视频TV端的软件就开始抓不到包,旧版的仍然能抓到。
使用sunny,抓包的时候发现,相比旧版的,新版多了许多UDP连接。
参考之前很多的app,猜测这是quic协议,根据**的习惯,找了找开源的项目。
发去年年底开源了一个叫做tquic项目

看样子多半就是quic协议了,毕竟它就喜欢这样干,参考trpc,tars。
既然已经猜到是quic,复盘友商成功案例,迭代旧有传统打法。
一、禁用UDP抓包
毕竟quic还是相对比较新的东西,大部分软件为了兼容旧版本,同时支持多种协议,毕竟TV很多还是安卓5。
参考下面用抓包软件来禁用udp。


二、hook请求信息
参考https://github.com/TencentCloud/libtquic-sdk/blob/main/src/android/TnetQuicRequest.java里面代码,
hook nativeSendRequest 看堆栈一步步往上找。
let TnetQuicRequest = Java.use("com.tencent.qqlive.modules.vb.tquic.impl.TnetQuicRequest");
TnetQuicRequest["sendRequest"].implementation = function (bArr, i10, z10) {
console.log(`TnetQuicRequest.sendRequest is called: bArr=${bArr}, i10=${i10}, z10=${z10}`);
let result = this["sendRequest"](bArr, i10, z10);
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
console.log(`TnetQuicRequest.sendRequest result=${result}`);
return result;
};
下面图中performRequest传入了request, headers和请求头,同样hook一下


let TQuicStack = Java.use("com.ktcp.tencent.volley.toolbox.TQuicStack");
TQuicStack["performRequest"].implementation = function (request, map) {
var url = request.getUrl();
var Headers = request.getHeaders();
var keys = Headers.keySet().toArray();
console.log("Request URL: " + url);
for (var i = 0; i
这里只hook了请求,响应是一样的就在下面几个函数。

三、hook降级
根据上面hook nativeSendRequest打印的堆栈信息,可以判断出app使用的是OKHttp,添加了拦截器。
参考https://juejin.cn/post/7308909489154015247,利用addInterceptor函数嵌入了tquic。

同样往上找堆栈,发现一个可疑函数selectHttpStack和chooseProtocol,尝试hook,同时抓包。

chooseProtocol返回2的时候就是tquic,无法抓包,为1时能够抓到。

直接hook返回1就行了
let MultiStackNetwork = Java.use("com.ktcp.tencent.volley.toolbox.MultiStackNetwork");
MultiStackNetwork["chooseProtocol"].implementation = function (request) {
return 1;
};

四、jce响应解析
在抓包过程中会发现,响应大多数是二进制,不是json。在请求参数里面有个jce,大部分修改为json能够返回json格式,下面图片中的接口,修改后仍然是二进制的。

4.1 jce是什么
jce 是一个类似于 pb 的二进制编码协议,最早是在腾讯 rpc 框架 tars 设计的,不过现在都统一为tars。
类似.proto文件,.jce/.tars文件是腾讯tars rpc框架的基础(现在又出一个trpc pb协议)。
目前 tars 支持 C++,Java,PHP,Nodejs,Go ;所以解析jce最简单方法还是直接把app里面代码扣出来调用。
4.2 .jce/.tars基本格式
参考官网文档
4.3 从java代码中还原.jce/.tars文件
建议自己先多看看官方文档,文档里面有点就不说了。
根据官方提供的示例
StatF.tars

StatMicMsgHead.java


两个文件对照看可以找到对应关系
[table]
[tr]
[td]java[/td]
[td].jce/.tars[/td]
[/tr]
[tr]
[td]true