有时候可能会遇到需要修改依赖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了?

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

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

这里我们发现

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

被折叠的 条评论
为什么被折叠?



