AsmActualCombat
- 項(xiàng)目地址:https://github.com/Peakmain/AsmActualCombat
- 使用文檔鏈接:https://github.com/Peakmain/AsmActualCombat/wiki
前言
相關(guān)文章系列
- Gradle 插件 + ASM 實(shí)戰(zhàn)——入門篇
- Gradle+ASM實(shí)戰(zhàn)——進(jìn)階篇
- Gradle+ASM實(shí)戰(zhàn)——隱私方法問題徹底解決之AsmActualCombat開源庫
- 隱私政策整改之Glide框架封裝
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ò)分析
- 目標(biāo):找到它們設(shè)置User-Agent代碼
- 源碼位置:https://github.com/Peakmain/AsmActualCombat/blob/master/plugin/src/main/groovy/com/peakmain/analytics/plugin/visitor/NetworkMethodCalledReplaceAdapter.groovy
- 我們在APP一般需要添加依賴
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




