package com.zfy.social.plugin; import com.zfy.social.plugin.extension.SocialExt; import com.zfy.social.plugin.lib.TransformX; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import java.util.function.Function; /** * CreateAt : 2020-01-20 * Describe : 访问 class 工具 * * @author chendong */ public class ClassVisitorImpl extends ClassVisitor implements Opcodes { public static Factory factory = new Factory(); static class Factory implements Function<ClassWriter, ClassVisitor> { @Override public ClassVisitor apply(ClassWriter classWriter) { return new ClassVisitorImpl(classWriter); } } private String className; private boolean isTargetClass; public ClassVisitorImpl(ClassVisitor classVisitor) { super(Opcodes.ASM5, classVisitor); } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); className = name; // System.out.println("ConfigInjectVisitor visit version = " + version // + ", access = " + access // + ", name = " + name // + ", signature = " + signature // + ", superName = " + superName // + ", interfaces = " + Arrays.toString(interfaces)); if (TransformX.isSubClass(superName, interfaces, "com/zfy/social/core/platform/AbsPlatform")) { System.out.println("是平台类的子类"); // isTargetClass = true; } if ("com/zfy/social/core/util/AsmUtil".equals(name)) { isTargetClass = true; System.out.println("找到 AsmUtil"); } } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); // System.out.println("ConfigInjectVisitor visitMethod " // + ", access = " + access // + ", name = " + name // + ", desc = " + desc // + ", signature = " + signature // + ", exceptions = " + exceptions); if (isTargetClass && "updateSocialOptions".equals(name)) { System.out.println("找到 AsmUtil updateSocialOptions"); SocialConfigMethodVisitorImpl visitor = new SocialConfigMethodVisitorImpl(methodVisitor); return visitor; } return methodVisitor; } @Override public void visitEnd() { super.visitEnd(); // System.out.println("ConfigInjectVisitor visitEnd "); } static class SocialPlatformMethodVisitorImpl extends MethodVisitor { public SocialPlatformMethodVisitorImpl(MethodVisitor mv) { super(Opcodes.ASM4, mv); } @Override public void visitCode() { mv.visitFieldInsn(Opcodes.GETSTATIC, "com/zfy/social/core/util/AsmUtil", "TAG", "Ljava/lang/String;"); mv.visitLdcInsn("register platform com.zfy.social.wx.WxPlatform$Factory"); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "android/util/Log", "e", "(Ljava/lang/String;Ljava/lang/String;)I", false); mv.visitInsn(Opcodes.POP); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn("com.zfy.social.wx.WxPlatform$Factory"); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/zfy/social/core/_SocialSdk", "registerPlatform", "(Ljava/lang/String;)V", false); super.visitCode(); } } static class SocialConfigMethodVisitorImpl extends MethodVisitor { public SocialConfigMethodVisitorImpl(MethodVisitor mv) { super(Opcodes.ASM4, mv); } @Override public void visitCode() { mv.visitLdcInsn("SocialSdk"); SocialExt socialExt = SocialPlugin.getSocialExt(); mv.visitLdcInsn("start init social sdk options " + socialExt.toString()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "android/util/Log", "e", "(Ljava/lang/String;Ljava/lang/String;)I", false); mv.visitInsn(Opcodes.POP); if (socialExt.wx.enable) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(socialExt.wx.appId); mv.visitLdcInsn(socialExt.wx.appSecret); mv.visitInsn(socialExt.wx.onlyAuthCode ? Opcodes.ICONST_1 : Opcodes.ICONST_0); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/zfy/social/core/SocialOptions$Builder", "wx", "(Ljava/lang/String;Ljava/lang/String;Z)Lcom/zfy/social/core/SocialOptions$Builder;", false); mv.visitInsn(Opcodes.POP); } if (socialExt.qq.enable) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(socialExt.qq.appId); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/zfy/social/core/SocialOptions$Builder", "qq", "(Ljava/lang/String;)Lcom/zfy/social/core/SocialOptions$Builder;", false); mv.visitInsn(Opcodes.POP); } if (socialExt.wb.enable) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(socialExt.wb.appId); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/zfy/social/core/SocialOptions$Builder", "wb", "(Ljava/lang/String;)Lcom/zfy/social/core/SocialOptions$Builder;", false); mv.visitInsn(Opcodes.POP); } if (socialExt.dd.enable) { mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitLdcInsn(socialExt.dd.appId); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/zfy/social/core/SocialOptions$Builder", "dd", "(Ljava/lang/String;)Lcom/zfy/social/core/SocialOptions$Builder;", false); mv.visitInsn(Opcodes.POP); } super.visitCode(); } @Override public void visitInsn(int opcode) { //判断RETURN if (opcode == Opcodes.RETURN) { //在这里插入代码 } super.visitInsn(opcode); } } }