2.18 Android插桩
2.18.1 动态代理
参考动态代理
2.18.2 编译 + AbstractProcessor实现
通过注解, 在编译时期使用AbstractProcessor
生成代码
2.18.3 ASM (字节码操控框架)
- Java类文件结构, 参考类文件结构
- 使用
// 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();
}
- 流程图