Search in sources :

Example 6 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project quasar by puniverse.

the class QuasarInstrumentor method instrumentClass.

@VisibleForTesting
byte[] instrumentClass(ClassLoader loader, String className, InputStream is, boolean forceInstrumentation) throws IOException {
    className = className != null ? className.replace('.', '/') : null;
    byte[] cb = toByteArray(is);
    MethodDatabase db = getMethodDatabase(loader);
    if (className != null) {
        log(LogLevel.INFO, "TRANSFORM: %s %s", className, (db.getClassEntry(className) != null && db.getClassEntry(className).requiresInstrumentation()) ? "request" : "");
        // DEBUG
        if (EXAMINED_CLASS != null && className.startsWith(EXAMINED_CLASS)) {
            writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-1-preinstr.class", cb);
        // cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
        }
    } else {
        log(LogLevel.INFO, "TRANSFORM: null className");
    }
    // Phase 1, add a label before any suspendable calls, event API is enough
    final ClassReader r1 = new ClassReader(cb);
    final ClassWriter cw1 = new ClassWriter(r1, 0);
    final LabelSuspendableCallSitesClassVisitor ic1 = new LabelSuspendableCallSitesClassVisitor(cw1, db);
    r1.accept(ic1, 0);
    cb = cw1.toByteArray();
    // DEBUG
    if (EXAMINED_CLASS != null && className != null && className.startsWith(EXAMINED_CLASS)) {
        writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-2.class", cb);
    // cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
    }
    // Phase 2, instrument, tree API
    final ClassReader r2 = new ClassReader(cb);
    final ClassWriter cw2 = new DBClassWriter(db, r2);
    final ClassVisitor cv2 = (check && EXAMINED_CLASS == null) ? new CheckClassAdapter(cw2) : cw2;
    final InstrumentClass ic2 = new InstrumentClass(cv2, db, forceInstrumentation);
    try {
        r2.accept(ic2, ClassReader.SKIP_FRAMES);
        cb = cw2.toByteArray();
    } catch (final Exception e) {
        if (ic2.hasSuspendableMethods()) {
            error("Unable to instrument class " + className, e);
            throw e;
        } else {
            if (!MethodDatabase.isProblematicClass(className))
                log(LogLevel.DEBUG, "Unable to instrument class " + className);
            return null;
        }
    }
    // DEBUG
    if (EXAMINED_CLASS != null && className != null && className.startsWith(EXAMINED_CLASS)) {
        writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-4.class", cb);
    // cv1 = new TraceClassVisitor(cv, new PrintWriter(System.err));
    }
    // Phase 4, fill suspendable call offsets, event API is enough
    final OffsetClassReader r3 = new OffsetClassReader(cb);
    final ClassWriter cw3 = new ClassWriter(r3, 0);
    final SuspOffsetsAfterInstrClassVisitor ic3 = new SuspOffsetsAfterInstrClassVisitor(cw3, db);
    r3.accept(ic3, 0);
    cb = cw3.toByteArray();
    // DEBUG
    if (EXAMINED_CLASS != null) {
        if (className != null && className.startsWith(EXAMINED_CLASS))
            writeToFile(className.replace('/', '.') + "-" + new Date().getTime() + "-quasar-5-final.class", cb);
        if (check) {
            ClassReader r4 = new ClassReader(cb);
            ClassVisitor cv4 = new CheckClassAdapter(new TraceClassVisitor(null), true);
            r4.accept(cv4, 0);
        }
    }
    return cb;
}
Also used : TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) Date(java.util.Date) ClassWriter(org.objectweb.asm.ClassWriter) TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) CheckClassAdapter(org.objectweb.asm.util.CheckClassAdapter) ClassReader(org.objectweb.asm.ClassReader) VisibleForTesting(co.paralleluniverse.common.util.VisibleForTesting)

Example 7 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project quasar by puniverse.

the class JavaAgent method crazyClojureOnceDisable.

public static byte[] crazyClojureOnceDisable(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    if (!Boolean.parseBoolean(System.getProperty("co.paralleluniverse.pulsar.disableOnce", "false")))
        return classfileBuffer;
    final ClassReader cr = new ClassReader(classfileBuffer);
    final ClassWriter cw = new ClassWriter(cr, 0);
    final ClassVisitor cv = new ClassVisitor(ASMAPI, cw) {

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) {

                @Override
                public void visitLdcInsn(Object cst) {
                    if (cst instanceof String && cst.equals("once")) {
                        super.visitLdcInsn("once$disabled-by-pulsar");
                    } else
                        super.visitLdcInsn(cst);
                }
            };
        }
    };
    cr.accept(cv, 0);
    return cw.toByteArray();
}
Also used : ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 8 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project dex2jar by pxb1988.

the class InitOut method collect.

private List<ClassInfo> collect(File file) throws IOException {
    final List<ClassInfo> clzList = new ArrayList<ClassInfo>();
    final ClassVisitor collectVisitor = new ClassVisitor(ASM4) {

        private static final String ASSERTION_DISABLED_FIELD_NAME = "$assertionsDisabled";

        private static final String ENUM_VALUES_FIELD_NAME = "ENUM$VALUES";

        ClassInfo clz;

        boolean isEnum = false;

        Map<String, String> enumFieldMap = new HashMap<String, String>();

        @Override
        public void visitSource(String source, String debug) {
            if (initSourceNames && !clz.name.contains("$") && source.endsWith(".java")) {
                clz.suggestName = source.substring(0, source.length() - 5);
            }
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            clz.addMethod(access, name, desc);
            if (initEnumNames && isEnum && name.equals("<clinit>")) {
                final String thisDesc = "L" + clz.name + ";";
                return new MethodNode(ASM4, access, name, desc, signature, exceptions) {

                    @Override
                    public void visitEnd() {
                        if (this.instructions != null) {
                            int status = 0;
                            String eFieldName = null;
                            for (AbstractInsnNode p = this.instructions.getFirst(); p != null; p = p.getNext()) {
                                if (status == 0) {
                                    // init
                                    if (p.getOpcode() == NEW) {
                                        TypeInsnNode ti = (TypeInsnNode) p;
                                        if (thisDesc.equals(ti.desc)) {
                                            status = 1;
                                        }
                                    }
                                } else if (status == 1) {
                                    // find NEW
                                    if (p.getOpcode() == DUP) {
                                        status = 2;
                                    } else {
                                        status = 0;
                                    }
                                } else if (status == 2) {
                                    //find DUP
                                    if (p.getOpcode() == LDC) {
                                        LdcInsnNode ldc = (LdcInsnNode) p;
                                        if (ldc.cst instanceof String) {
                                            eFieldName = (String) ldc.cst;
                                            status = 3;
                                        } else {
                                            status = 0;
                                        }
                                    } else {
                                        status = 0;
                                    }
                                } else if (status == 3) {
                                    //find LDC
                                    if (p.getOpcode() == PUTSTATIC) {
                                        FieldInsnNode fin = (FieldInsnNode) p;
                                        if (fin.owner.equals(thisDesc) && fin.desc.equals(thisDesc)) {
                                            if (!fin.name.equals(eFieldName)) {
                                                enumFieldMap.put(fin.name, eFieldName);
                                            }
                                            eFieldName = null;
                                            status = 0;
                                        }
                                    }
                                }
                            }
                        }
                    }
                };
            }
            return null;
        }

        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            MemberInfo mi = clz.addField(access, name, desc);
            if (initEnumNames && isEnum && isPrivate(access) && isFinal(access) && isSynthetic(access) && !ENUM_VALUES_FIELD_NAME.equals(name) && ("[L" + clz.name + ";").equals(desc)) {
                mi.suggestName = ENUM_VALUES_FIELD_NAME;
            }
            if (initAssertionNames && isSynthetic(access) && isStatic(access) && !isPrivate(access) && !isPublic(access) && !isProtected(access) && desc.equals("Z") && !ASSERTION_DISABLED_FIELD_NAME.equals(name)) {
                mi.suggestName = ASSERTION_DISABLED_FIELD_NAME;
            }
            return null;
        }

        @Override
        public void visitEnd() {
            if (initEnumNames) {
                final String thisDesc = "L" + clz.name + ";";
                for (Map.Entry<String, String> e : enumFieldMap.entrySet()) {
                    String name = e.getKey();
                    String suggestName = e.getValue();
                    for (MemberInfo mi : clz.fields) {
                        if (isFinal(mi.access) && isStatic(mi.access) && mi.name.equals(name) && mi.desc.equals(thisDesc)) {
                            mi.suggestName = suggestName;
                        }
                    }
                }
            }
            clzList.add(clz);
            clz = null;
            isEnum = false;
            enumFieldMap.clear();
        }

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            this.clz = new ClassInfo(name);
            isEnum = isEnum(access);
        }
    };
    //        fileWalker.walk(file);
    return clzList;
}
Also used : ClassVisitor(org.objectweb.asm.ClassVisitor)

Example 9 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project dex2jar by pxb1988.

the class Dex2jarMultiThreadCmd method run0.

private void run0(String fileName, final ExecutorService executorService) throws IOException {
    // long baseTS = System.currentTimeMillis();
    String baseName = getBaseName(new File(fileName).toPath());
    Path currentDir = new File(".").toPath();
    Path file = currentDir.resolve(baseName + "-dex2jar.jar");
    final Path errorFile = currentDir.resolve(baseName + "-error.zip");
    System.err.println("dex2jar " + fileName + " -> " + file);
    final BaksmaliBaseDexExceptionHandler exceptionHandler = new BaksmaliBaseDexExceptionHandler();
    BaseDexFileReader reader = MultiDexFileReader.open(Files.readAllBytes(new File(fileName).toPath()));
    DexFileNode fileNode = new DexFileNode();
    try {
        reader.accept(fileNode, DexFileReader.SKIP_DEBUG | DexFileReader.IGNORE_READ_EXCEPTION);
    } catch (Exception ex) {
        exceptionHandler.handleFileException(ex);
        throw ex;
    }
    final FileSystem fs = createZip(file);
    final Path dist = fs.getPath("/");
    ClassVisitorFactory cvf = new ClassVisitorFactory() {

        @Override
        public ClassVisitor create(final String name) {
            return new ClassVisitor(Opcodes.ASM4, new ClassWriter(ClassWriter.COMPUTE_MAXS)) {

                @Override
                public void visitEnd() {
                    super.visitEnd();
                    ClassWriter cw = (ClassWriter) super.cv;
                    byte[] data;
                    try {
                        // FIXME handle 'java.lang.RuntimeException: Method code too large!'
                        data = cw.toByteArray();
                    } catch (Exception ex) {
                        System.err.println(String.format("ASM fail to generate .class file: %s", name));
                        exceptionHandler.handleFileException(ex);
                        return;
                    }
                    try {
                        Path dist1 = dist.resolve(name + ".class");
                        BaseCmd.createParentDirectories(dist1);
                        Files.write(dist1, data);
                    } catch (IOException e) {
                        exceptionHandler.handleFileException(e);
                    }
                }
            };
        }
    };
    new ExDex2Asm(exceptionHandler) {

        @Override
        public void convertDex(DexFileNode fileNode, final ClassVisitorFactory cvf) {
            if (fileNode.clzs != null) {
                final Map<String, Clz> classes = collectClzInfo(fileNode);
                final List<Future<?>> results = new ArrayList<>(fileNode.clzs.size());
                for (final DexClassNode classNode : fileNode.clzs) {
                    results.add(executorService.submit(new Runnable() {

                        @Override
                        public void run() {
                            convertClass(classNode, cvf, classes);
                        }
                    }));
                }
                executorService.submit(new Runnable() {

                    @Override
                    public void run() {
                        for (Future<?> result : results) {
                            try {
                                result.get();
                            } catch (InterruptedException | ExecutionException e) {
                                e.printStackTrace();
                            }
                        }
                        BaksmaliBaseDexExceptionHandler exceptionHandler1 = (BaksmaliBaseDexExceptionHandler) exceptionHandler;
                        if (exceptionHandler1.hasException()) {
                            exceptionHandler1.dump(errorFile, new String[0]);
                        }
                        try {
                            fs.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }.convertDex(fileNode, cvf);
}
Also used : Path(java.nio.file.Path) ClassVisitor(org.objectweb.asm.ClassVisitor) IOException(java.io.IOException) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter) DexClassNode(com.googlecode.d2j.node.DexClassNode) FileSystem(java.nio.file.FileSystem) DexFileNode(com.googlecode.d2j.node.DexFileNode) ClassVisitorFactory(com.googlecode.d2j.dex.ClassVisitorFactory) BaseDexFileReader(com.googlecode.d2j.reader.BaseDexFileReader) File(java.io.File) ExDex2Asm(com.googlecode.d2j.dex.ExDex2Asm)

Example 10 with ClassVisitor

use of org.objectweb.asm.ClassVisitor in project robovm by robovm.

the class InterfaceBuilderClassesPlugin method getCustomClass.

private String getCustomClass(URL url, Map<URL, String> customClassValuesCache) throws IOException {
    if (customClassValuesCache.containsKey(url)) {
        return customClassValuesCache.get(url);
    }
    class Visitor extends ClassVisitor {

        String customClass;

        Visitor() {
            super(Opcodes.ASM4);
        }

        @Override
        public AnnotationVisitor visitAnnotation(final String desc, boolean visible) {
            if (CUSTOM_CLASS.equals(desc)) {
                return new AnnotationVisitor(Opcodes.ASM4) {

                    public void visit(String name, Object value) {
                        customClass = (String) value;
                    }
                };
            }
            return super.visitAnnotation(desc, visible);
        }
    }
    Visitor visitor = new Visitor();
    new ClassReader(IOUtils.toByteArray(url)).accept(visitor, 0);
    customClassValuesCache.put(url, visitor.customClass);
    return visitor.customClass;
}
Also used : AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ClassVisitor(org.objectweb.asm.ClassVisitor) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor)

Aggregations

ClassVisitor (org.objectweb.asm.ClassVisitor)70 ClassReader (org.objectweb.asm.ClassReader)47 ClassWriter (org.objectweb.asm.ClassWriter)41 MethodVisitor (org.objectweb.asm.MethodVisitor)23 InputStream (java.io.InputStream)12 IOException (java.io.IOException)10 Type (org.objectweb.asm.Type)9 Test (org.junit.Test)7 File (java.io.File)6 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)6 FieldList (net.bytebuddy.description.field.FieldList)5 MethodList (net.bytebuddy.description.method.MethodList)5 TypeDescription (net.bytebuddy.description.type.TypeDescription)5 TypePool (net.bytebuddy.pool.TypePool)5 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)5 URL (java.net.URL)4 MethodDescription (net.bytebuddy.description.method.MethodDescription)4 FileOutputStream (java.io.FileOutputStream)3 Path (java.nio.file.Path)3 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)3