美文网首页
一种新的修改字节码的思路

一种新的修改字节码的思路

作者: 轻微 | 来源:发表于2018-05-13 17:21 被阅读242次

博客地址: dim.red

0x00 前言

分析最近的 Crash , 排在前列基本是第三方SDK导致. 遇到这样的问题, 我们需要寻求官方的支持, 但是官方的支持总是来得比较晚. 在Android上, 第三方SDK一般是两种, 一种是jar, 一种是so. so的修改成本过大, 我们放弃它, 我们现在探讨对 jar 的修改.

0x02 问题

在之前 使用AOP来为第三方SDK打CALL 文章 我们使用 AOP 对第三方 SDK 的问题进行修复. 貌似能这样解决这个问题.
但是 AOP 存在局限性:
1、它不够直观. 定义的规则需要通过编译后才能确定.
2、学习成本较高.
3、可操作的范围不够大. 只能切方法.
例子:
在一些因素下,我们升级某个推送SDK版本. 但是发现有大量的NPE异常出现. 通过反编译 jar 定位问题.

  private Handler p = null;
  private void b() {
        if (this.p != null) {
            this.p.removeMessages(2);
        } else {
            this.p = new Handler(Looper.getMainLooper(), new com.xxx.b(this));
        }
        this.p.sendEmptyMessageDelayed(2, 3000L);
   }
  private void c() {
        if (this.p != null) {
            this.p.removeMessages(2);
            this.p = null;
        }
   }
  public void d(){
  ...
    // 代码块A  开始
    if(p != null){
      this.p.sendEmptyMessageDelayed(3, 3000L);
    }
    // 代码块A  结束
  ...
  }

异常发生在方法this.p.sendEmptyMessageDelayed(2, 3000L);.在一个判断空还会出现NPE, 说明这是一个多线程并发下的bug. 通过分析我们需要

  1. 对b c 方法使用synchronized 修饰
  2. 对代码块A 进行 synchronized(this) 包裹

在这种场景下使用AOP将费力不讨好.

0x03 解决方案

我们可以尝试使用一种更简单的方式来处理这件事情. 输入一个原始的 jar , 经过转换生成新的 jar.

  • 步骤1: 对 jar 中需要修改的 class 反编译成 java 文件.
  • 步骤2: 对 java 文件进行代码逻辑上的 bug fix.
  • 步骤3: 使用 javac 编译 java 文件成 class 文件.
  • 步骤4: 替换 jar 中对应的修改的 class 文件生成新的 jar 文件.

0x04 问题

Q : javac 编译失败.
A: 当你 java 调用的方法不在原有的 jar 中, 导致 javac 编译的时候找不到对应的方法,抛出异常.
解决方式:使用 asm 对 jar 中进行指令分析, 对指令 invokestatic, invokevirtual , invokeinterface , invokedynamic ( android 上可以忽略这个指令) 和 getfield , getstatic 指令的分析. 我们可以生成一个空的实现的jar , 来为 javac 编译提供环境支持.

Q : 内部类的问题.
A: 匿名内部的生成的规则是 外部类类名$Number. Number 是在源码中出现的位置. 当你新增和调整位置的时候会导致生成的类和之前的类不匹配. 解决方式. 在对外部类操作的时候, 直接对匿名内部类进行删除. 等 javac 命令的生成新的内部类直接替换进去.

0x05 改进

通过和 idea 结合提供一整套的解决方案.

相关文章

  • 一种新的修改字节码的思路

    博客地址: dim.red 0x00 前言 分析最近的 Crash , 排在前列基本是第三方SDK导致. 遇到这样...

  • 程序员练级攻略(2018):Java底层知识

    Java 字节码相关 首先,Java 最黑科技的玩法就是字节码编程,也就是动态修改或是动态生成 Java 字节码。...

  • 四、Java探针技术

    对于agent,是在vm启动,执行方法前,将字节码修改的服务代理。 对于javassist,是修改字节码具体实现。...

  • 可爱的字节码&修改

    1.为什么要修改字节码 字节码是java多平台运行的根本原因,程序运行的状态和结果都由字节码决定。所以控制了字节码...

  • spring aop源码实现分析

    AOP就是面向切面编程,我们可以从几个层面来实现AOP。 在编译器修改源代码,在运行期字节码加载前修改字节码或字节...

  • Java字节码修改 - javassist

    AOP的实现一般使用了动态代理和字节码修改,本文介绍使用javassist实现类的创建和修改 添加依赖 使用字节码...

  • ASM框架学习(三)-FieldVisitor和MethodVi

    简介 FiedVisitor是用来在访问类的域字节码过程中创建域或者修改域字节码信息的;MethodVisitor...

  • 史上最全的ASM原理解析与应用

    ASM简介 ASM是一个操作Java字节码类库,其操作的对象是字节码数据,处理字节码方式是“拆分-修改-合并”将....

  • Java Agent基本简介和使用

    javaagent简介 javaagent是一种能够在不影响正常编译的情况下,修改字节码。java作为一种强类型的...

  • 自定义Gradle插件

      最近在学习字节码插桩技术,利用字节码插桩技术,我们可以在编译时期对字节码进行修改,达到完成一些特殊需求,比如埋...

网友评论

      本文标题:一种新的修改字节码的思路

      本文链接:https://www.haomeiwen.com/subject/lgdldftx.html