從麻花影視的抓包看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代理了。

相關文章
相關標籤/搜索