Frida0A - 拦截okhttp

各位读者你们好呀!有两个星期没有更新了,主要是懒癌犯了!

OkHttp

https://square.github.io/okhttp/

Okhttp 是一个网络框架,现在的Android应用基本都使用的是这个开源库了。

想要拦截 OkHttp,首先就要熟悉它的API和原理。这里就不展开了,可以查找一些文章或者自己看源码。

OkHttp的工作模式有点像 OSI 模型,它里面的拦截器就相当于一个层次。每个拦截器都负责两部分的工作:

  • 将请求进行封装,y = f(x)

  • 将返回结果解封装,y’ = f’(x)

以 BridgeInterceptor 为例:

  @Throws(IOException::class)
  override fun intercept(chain: Interceptor.Chain): Response {
    val userRequest = chain.request()
    val requestBuilder = userRequest.newBuilder()

    // ... 处理请求体

    val networkRequest = requestBuilder.build()
    val networkResponse = chain.proceed(networkRequest)

    cookieJar.receiveHeaders(networkRequest.url, networkResponse.headers)

    val responseBuilder =
      networkResponse.newBuilder()
        .request(networkRequest)

    // ... 处理响应体

    return responseBuilder.build()
  }

为了调试方便,OkHttp 里面还自带了一个日志拦截器:

https://github.com/square/okhttp/blob/368d53742e11f0e4ca0fc9b94b018337dff0dc68/okhttp-logging-interceptor/src/main/kotlin/okhttp3/logging/HttpLoggingInterceptor.kt

有了这个拦截器,就可以打印所有请求的请求体与响应体。

所以一个最简单的思路就是使用 frida 将这个日志拦截器添加到 okhttp 的实例对象里面就ok。

拦截OkHttp

这里有一篇文章,使用 frida 的 api 实现了一个拦截器,感觉有点蛋疼。

https://bbs.kanxue.com/thread-252129.htm

肯定是使用加载 dex 的方式会好些,找到所有OkHttpClient的实例对象,然后给他们加上拦截器:

// 加载包含logging-interceptor拦截器的DEX
Java.openClassFile("/data/local/tmp/xxxxx.dex").load();

// 获取日志拦截器类
const MyInterceptor = Java.use("com.xxxx.okhttp3Logging");
var MyInterceptorObj = MyInterceptor.$new();

// interceptors 是一个不可变集合,所以需要重新创建一个新的集合
Java.choose("okhttp3.OkHttpClient", {
    onMatch: function (instance) {
        console.log("1. found instance:", instance)
        console.log("2. instance.interceptors():", instance.interceptors().$className)
        console.log("3. instance._interceptors:", instance._interceptors.value.$className)
        //console.log("4. interceptors:",gson2.$new().toJson(instance.interceptors())) 
        console.log("5. interceptors:", Java.use("java.util.Arrays").toString(instance.interceptors().toArray()))
        var newInter = Java.use("java.util.ArrayList").$new();
        newInter.addAll(instance.interceptors());
        console.log("6. interceptors:", Java.use("java.util.Arrays").toString(newInter.toArray()));
        console.log("7. interceptors:", newInter.$className);
        newInter.add(MyInterceptorObj);
        newInter.add(curlInter);
        instance._interceptors.value = newInter;

    }, onComplete: function () {
        console.log("Search complete!")
    }
})

混淆处理

为了防止被快速逆向分析,部分 app 针对 okhttp 的代码进行了混淆。

有一个开源项目就是做了这个事情:

https://github.com/siyujie/OkHttpLogger-Frida

它里面的核心逻辑是对混淆类的寻找:

https://github.com/siyujie/okhttp_find

它寻找特征的方法也很简单粗暴。就是先去所有可能属于 okhttp 框架层的类中找到 OkHttpClient$Builder 内部类。该类的特征为有四个 List 类型的成员变量,其中两个有 final 修饰符,两个的列表类型为接口类型。一旦找到满足这个条件的类,就可以通过 getEnclosingClass 方法获取该类的外部类,也就定位到了关键类 OkHttpClient。然后顺藤摸瓜一直找下去。

感觉会有更好的方式,可以自己混淆一下代码观察下特征。

根据 README 的介绍来看:

  `find()`                                         检查是否使用了Okhttp & 是否可能被混淆 & 寻找okhttp3关键类及函数 
  `switchLoader(\"okhttp3.OkHttpClient\")`         参数:静态分析到的okhttpclient类名
  `hold()`                                         开启HOOK拦截
  `history()`                                      打印可重新发送的请求
  `resend(index)`                                  重新发送请求

这个库需要在一定程度上结合静态分析才能使用,当然如果 find 能找出来最好,只需要替换一下就行了。

二手的程序员

欢迎关注二手的程序员,这里主要分享逆向相关的知识。专注于完整系列,让知识不再碎片化。不定时更新,也欢迎关注我的博客:lyldalek.top

公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二手的程序员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值