Gradle+ASM實(shí)戰(zhàn)——攔截網(wǎng)絡(luò)頭部之理論篇

AsmActualCombat

前言

相關(guān)文章系列
ASM文檔

需求背景

  • 上篇文章我們講了關(guān)于圖片加載獲取應(yīng)用自身獲取個人信息行為問題修復(fù)。其實(shí)還有其他的也會獲取User-Agent,如網(wǎng)絡(luò)行為,webView獲取User-Agent
  • webView解決方法就是不要調(diào)用下面方法
webSettings.getUserAgentString()
  • 網(wǎng)絡(luò)行為如果是自身的就比較簡單,一般情況來說,我們都是用OKhttp(Retrofit可以理解只是對okHttp的進(jìn)行封裝的架構(gòu)庫,底層還是OkHttp)去請求網(wǎng)絡(luò),那么直接去移除相關(guān)Header,或者直接設(shè)置一個通用的值如:Android即可
private static Interceptor addCommonParameterInterceptor() {
    return chain -> {
        Request originalRequest = chain.request();
     
        Request newRequest = originalRequest.newBuilder()
                .url(modifiedUrl.build()).removeHeader("User-Agent").addHeader("User-Agent",
                        "Android").build();
        return chain.proceed(newRequest);
    };
}
  • 還有的公司請求可能用的還是HttpUrlConnection,關(guān)于這個怎么攔截,大家往下看。
  • 我們今天主要講的是怎么去攔截第三方庫或者jar包的網(wǎng)絡(luò)請求,我們首先看幾張圖


    1.png

    2.png

    3.png
  • 上面三張圖分別是七牛云,高德,mob分享sdk三個庫的網(wǎng)絡(luò)請求,我們會發(fā)現(xiàn)他們在User-Agent中獲取應(yīng)用自身獲取個人信息行為(黃色區(qū)域)
  • 今天我們的目標(biāo)就是怎么把它替換成固定的值A(chǔ)ndroid或者刪除
  • 我們今天主要對七牛云進(jìn)行分析攔截,其它的基本大同小異

七牛云網(wǎng)絡(luò)網(wǎng)絡(luò)分析

implementation 'com.qiniu:qiniu-android-sdk:7.3.15'
  • 找到七牛云源碼的位置


    image.png
  • 我們可以一個個點(diǎn)哈,也可以看名字猜哈,我們可以直接看Client代碼
public Client(ProxyConfiguration proxy, int connectTimeout, int responseTimeout, UrlConverter converter, final Dns dns) {
    this.converter = converter;
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    //代碼省略
    builder.connectTimeout(connectTimeout, TimeUnit.SECONDS);
    builder.readTimeout(responseTimeout, TimeUnit.SECONDS);
    builder.writeTimeout(0, TimeUnit.SECONDS);
    httpClient = builder.build();

}

我們可以發(fā)現(xiàn)七牛云用的是okHttp哈,當(dāng)然這不是重點(diǎn),但是大家在做自己項(xiàng)目的時候,可以參考下大廠是怎么做的封裝的。

  • 既然是OkHttp,一定是通過request.addHeader方式,我們直接搜User-Agent
if (upToken != null) {
    requestBuilder.header("User-Agent", UserAgent.instance().getUa(upToken.accessKey));
} else {
    requestBuilder.header("User-Agent", UserAgent.instance().getUa("pandora"));
}
  • 還有其他幾個地方引用,代碼差不多,就貼上面兩個,我們會發(fā)現(xiàn),它們都是調(diào)用同一個方法UserAgent的getUa方法
  • 如果我們將UserAgent的getUa方法的返回值設(shè)為空字符串或者某個固定的值是不是就解決了
  • 我們直接在visitMethodInsn方法體中找到com.qiniu.android.http.UserAgent的getUa方法
void visitMethodInsn(int opcodeAndSource, String owner, String name, String descriptor, boolean isInterface) {
     String qi_niu_yun="com/qiniu/android/http/UserAgent"+"getUa"+"(Ljava/lang/String;)Ljava/lang/String;"
    String desc = owner + name + descriptor
    if(qi_niu_yun==desc){
       
    }
}
  • 找到方法之后在方法體通過super.visitMethodInsn替換成我們自己的方法
  • 自己設(shè)置類和方法:如下
package com.peakmain.sdk.utils.network;


/**
 * author :Peakmain
 * createTime:2022/6/14
 * mail:2726449200@qq.com
 * describe:
 */
public class UserAgent {

    public static String getUa(com.qiniu.android.http.UserAgent userAgent, String part) {
        return "";
    }
}

所以我們替換后的owner是:

public static final String OWNER_NEW_QI_NIU_HTTP_USER_AGENT = "com/peakmain/sdk/utils/network/UserAgent"

name:

public static final String NAME_QI_NIU_HTTP_USER_AGENT = "getUa"

desc

public static final String DESCRIPTOR_NEW_QI_NIU_HTTP_USER_AGENT = "(Lcom/qiniu/android/http/UserAgent;Ljava/lang/String;)Ljava/lang/String;"

這里解釋下,為什么要添加七牛云的UserAgent對象,因?yàn)槠吲T票旧慝@取User-Agent用的是UserAgent的非靜態(tài)方法,非靜態(tài)方法持有了UserAgent對象,所以我們需要將它消費(fèi)掉

  • 替換或的方法
void visitMethodInsn(int opcodeAndSource, String owner, String name, String descriptor, boolean isInterface) {
     String qi_niu_yun="com/qiniu/android/http/UserAgent"+"getUa"+"(Ljava/lang/String;)Ljava/lang/String;"
    String desc = owner + name + descriptor
    if(qi_niu_yun==desc){
        super.visitMethodInsn(Opcodes.INVOKESTATIC, OWNER_NEW_QI_NIU_HTTP_USER_AGENT, NAME_QI_NIU_HTTP_USER_AGENT,DESCRIPTOR_NEW_QI_NIU_HTTP_USER_AGENT, false)
    }else{
        super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface)
    }
}
  • 至此替換就完成了,代碼還是非常簡單的。

總結(jié)

  • 七牛云的網(wǎng)絡(luò)請求主要通過Okhttp去請求的,并且它們設(shè)置User-Agent用的是一個單例的UserAgent的getUa方法,我們只需要攔截這個方法并將其即可
  • 關(guān)于HttpUrlConnection的頭部攔截,大家可以直接將header清空,或者直接將header進(jìn)行替換。
  • 關(guān)于Mob它們的網(wǎng)絡(luò)請求,大家可以看NetworkHelper類即可


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容