2.18 Android插桩

less than 1 minute read

2.18.1 动态代理

参考动态代理

2.18.2 编译 + AbstractProcessor实现

通过注解, 在编译时期使用AbstractProcessor生成代码

2.18.3 ASM (字节码操控框架)

  // 1. 继承ClassAdapter
  class AddSecurityCheckClassAdapter extends ClassAdapter {
    public AddSecurityCheckClassAdapter(ClassVisitor cv) {
      //Responsechain 的下一个 ClassVisitor,这里我们将传入 ClassWriter,
      // 负责改写后代码的输出
      super(cv);
    }

    public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
      MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
      MethodVisitor wrappedMv = mv;
      if (mv != null) {
        if (name.equals("operation")) {
          wrappedMv = new AddSecurityCheckMethodAdapter(mv);
        }
      }
      return wrappedMv;
    }
  }

  // 2. 继承MethodAdapter, 在operation首部插入方法
  class AddSecurityCheckMethodAdapter extends MethodAdapter {
    public AddSecurityCheckMethodAdapter(MethodVisitor mv) {
      super(mv);
    }

    // ClassReader读到方法首部时调用visitCode
    public void visitCode() {
      visitMethodInsn(Opcodes.INVOKESTATIC, "SecurityChecker", "checkSecurity", "()V");
    }
  }

  public static void main() throws Exception {
    ClassReader cr = new ClassReader("Account");
    ClassWrite cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassAdapter classAdapter = new AddSecurityCheckClassAdapter(cw);
    cr.accept(classAdapter, ClassReader.SKIP_DEBUG);
    byte[] data = cw.toByteArray();
    File file = new File("Account.class");
    FileOutputStream fout = new FileOutputStream(file);
    fout.write(data);
    fout.close();
  }

  • 流程图

流程图 参考ASM官网

参考