java如何修改sdk代码,如何快速修改sdk jar包中的class文件

当遇到需要修改第三方SDK的类时,可以通过ASM工具快速修改jar包中的class文件。本文介绍了如何利用ASM Bytecode Outline插件生成字节码指令,替换特定方法,以解决SSL校验问题,实现网络请求的抓包分析。

有时候可能会遇到需要修改依赖jar包中某些类的某些方法的需求,比如有些第三方sdk会出现空指针等异常导致应用程序崩溃,但是想等第三方更新sdk来解决时间又来不及,我们可以修改class文件加个异常捕获来避免crash出现。

最近工作中遇到一个问题,需要抓包分析某个sdk的网络请求,经过一番折腾终于可以抓包了,但是发现网络请求总是提示ssl异常,去分析sdk的源码发现,改sdk使用okhttp进行网络请求,但是设置了很多https的校验条件,比如HostNameVerifier为strictMode。我们先来看下它是如何初始化OkHttpClient的:

private static final Builder a;

public static OkHttpClient CustomTrust(String var0) {

SSLSocketFactory var1 = null;

try {

InputStream var2 = (new Buffer()).writeUtf8(var0).inputStream();

SSLContext var3 = a(var2);

var1 = var3.getSocketFactory();

} catch (GeneralSecurityException var4) {

throw new RuntimeException(var4);

} catch (IOException var5) {

var5.printStackTrace();

}

return a.sslSocketFactory(var1).hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.STRICT_HOSTNAME_VERIFIER).build();

}

我们可以看到,主要是通过CustomTrust这个方法调用静态变量a进行构造的,a这里就是okhttp3.OkHttpClient.Builder类型。因此我们很容易想到我们不用关心CustomTrust方法内部进行了什么处理,如果我们使用asm去修改class字节码的方法去替换CustomTrust方法内容是不是就ok了?

51eaa7a614b9d02673a419d13b6852de.png

如果修改成以上代码是不是就行了。。。

关于asm的一些基础介绍这里就不赘述,现在只讲如何快速完成替换。以前曾经做过类似的工作,但那时候做的比较笨重,先研究各种java指令码,然后去构造指令码去操作,但是这个方法效率很低而且容易出错。studio有个非常好用的插件ASM Bytecode Outline 2017

83b06ed0d51d06c876ff0407c3785f97.png

有了这个工具,我们可以直接写一段我们要生成的代码,然后使用asm bytecode插件查看自动生成的字节码操作代码,找到对应的代码段,只需要copy & paste到正确的位置就行了。

我们先来看下插件生成的操作码指令

9c0295a8c456752d0f2d978428abc7d0.png

这里我们发现

51eaa7a614b9d02673a419d13b6852de.png

对应的asm操作代码是

mv.visitFieldInsn(Opcodes.GETSTATIC, "*/*/XX", "a", "Lokhttp3/OkHttpClient$Builder;");

mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "okhttp3/OkHttpClient$Builder", "build", "()Lokhttp3/OkHttpClient;", false);

mv.visitInsn(Opcodes.ARETURN);

因此我们在asm对应的MethodVisitor中进行对应的操作就行了:

static class MyMethodVisitor extends MethodVisitor {

String methodName;

public MyMethodVisitor(MethodVisitor mv, String methodName) {

super(Opcodes.ASM4, mv);

this.methodName = methodName;

}

@Override

public void visitCode() {

Log.d(TAG, "visitCode:" + methodName);

mv.visitFieldInsn(Opcodes.GETSTATIC, "*/XX", "a", "Lokhttp3/OkHttpClient$Builder;");

mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "okhttp3/OkHttpClient$Builder", "build", "()Lokhttp3/OkHttpClient;", false);

mv.visitInsn(Opcodes.ARETURN);

}

@Override

public void visitInsn(int opcode) {

super.visitInsn(opcode);

}

}

之后把生成的class文件重新打到jar中,之后就可以正常抓包了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值