从麻花影视的抓包看app防http抓包方式

前一段时间看到一款比较不错的app,叫作麻花影视 java

感受很良心,并且上面居然有最新的电视剧的更新。因此想抓包看下能不能拿到这个app的视频来源。可是发现,链接上Charles以后,直接请求不到数据。android

结果挂上Charles以后居然界面没有数据而且 Toast 提示 请关闭代理重试bash

我能猜想到的引发这种现象的有两种状况:网络

  1. 证书不匹配,项目固定了证书,或者服务端对客户端证书进行了验证;
  2. 项目里面有代理检测

进一步猜想并测试,咱们再尝试一个别的代理。用手机上的app,packet capture 尝试一下结果居然能够访问,并且也可以抓到数据。因此猜想证书引发的可能性不大。app

而且它Toast 提示 请关闭代理重试。这一行提示出卖了他。说明他知道我挂了代理,那么它里面颇有可能进行了网络代理检测。并且用Charles抓包的时候,咱们根本没有抓到任何的请求,若是是证书固定的话,那么会在握手的时候出现错误。ide

网上搜一下如何判断当前wifi是否使用了代理的基本方法,都是下面这段代码:测试

public static boolean isWifiProxy() {
    final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    String proxyAddress;
    int proxyPort;
    if (IS_ICS_OR_LATER) {
        proxyAddress = System.getProperty("http.proxyHost");
        String portStr = System.getProperty("http.proxyPort");
        proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
    } else {
        proxyAddress = android.net.Proxy.getHost(context);
        proxyPort = android.net.Proxy.getPort(context);
    }
    return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}

复制代码

因此咱们找下他的app代码里面是否是有相关的特征值。jadx 全局搜索 System.getProperty("http.proxyHost");获得 com.mh.movie.core.app.i类里有以下代码:ui

//不就是特么这个方法吗、
    private boolean a(Context context) {
        CharSequence property;
        int parseInt;
        if ((VERSION.SDK_INT >= 14 ? 1 : null) != null) {
            property = System.getProperty("http.proxyHost");
            String property2 = System.getProperty("http.proxyPort");
            if (TextUtils.isEmpty(property2)) {
                property2 = "-1";
            }
            parseInt = Integer.parseInt(property2);
        } else {
            String host = Proxy.getHost(context);
            parseInt = Proxy.getPort(context);
            property = host;
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("proxyAddress : ");
        stringBuilder.append(property);
        stringBuilder.append(", port : ");
        stringBuilder.append(parseInt);
        Log.i("checkWifiProxy", stringBuilder.toString());
        if (TextUtils.isEmpty(property) || parseInt == -1) {
            return false;
        }
        return true;
    }
复制代码

直接用Xposed hook上的方法 ,而后返回false就好了,false代表没有是用代理:this

Class i = loadPackageParam.classLoader.loadClass("com.mh.movie.core.app.i");
 XposedHelpers.findAndHookMethod(i,
         "a",
         Context.class,
         new XC_MethodReplacement() {
             @Override
             protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                 return false;
             }
         });
复制代码

原本觉得事情到这里就结束了,可是,TMD、虽然能访问网络,可是抓不到包,抓不到包。。。。。why?spa

引用网上的一段话:对于一些经常使用的网络库,实际上是提供了咱们设置的代理的接口,咱们只须要将其设置成无代理的模式,它就不会去应用系统默认的代理了。

就拿比较经常使用的 OkHttp 来举例,在初始化的时候,就能够经过 proxy() 方法,为 OkHttp 设置一个代理。

OkHttpClient.Builder httpBuilder = OkHttpClient.Builder() 
                .addInterceptor(defaultInterceptor()) 
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS) 
                .writeTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS) 
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS)
                .proxy(Proxy.NO_PROXY) 
复制代码

为了处理比较完全,咱们直接经过Xposed hook OkHttpClient.Builder 的 proxy方法,而后取消掉这个设置PROXY的过程,让方法直接返回:

Class Builder = loadPackageParam.classLoader.loadClass("okhttp3.OkHttpClient$Builder");
Class Proxy = loadPackageParam.classLoader.loadClass("java.net.Proxy");
XposedHelpers.findAndHookMethod(Builder,
        "proxy",
        Proxy,
        new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
                return methodHookParam.thisObject;
            }
        });
复制代码

好了,到如今为止,能够经过Charles抓取他的API了。他的防抓包策略彻底能够用到咱们本身的项目里面,防止别人抓包。

总结一下,他这里的抓包防御总共有两处 1,检查是否是用了Http代理,若是是,那么客户端再也不发送网络请求; 2,经过Okhttp 设置默认代理,那么就不会走咱们的Charles代理了。

相关文章
相关标签/搜索