Search in sources :

Example 41 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project presto by prestodb.

the class ClassInfoLoader method createClassInfoLoader.

public static ClassInfoLoader createClassInfoLoader(Iterable<ClassDefinition> classDefinitions, ClassLoader classLoader) {
    ImmutableMap.Builder<ParameterizedType, ClassNode> classNodes = ImmutableMap.builder();
    for (ClassDefinition classDefinition : classDefinitions) {
        ClassNode classNode = new ClassNode();
        classDefinition.visit(classNode);
        classNodes.put(classDefinition.getType(), classNode);
    }
    return new ClassInfoLoader(classNodes.build(), ImmutableMap.of(), classLoader, true);
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 42 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project sling by apache.

the class GenerateAdapterMetadataMojo method execute.

public void execute() throws MojoExecutionException, MojoFailureException {
    try {
        final Map<String, Object> descriptor = new HashMap<>();
        final AnnotationDB annotationDb = new AnnotationDB();
        annotationDb.scanArchives(buildOutputDirectory.toURI().toURL());
        final Set<String> annotatedClassNames = new HashSet<String>();
        addAnnotatedClasses(annotationDb, annotatedClassNames, Adaptable.class);
        addAnnotatedClasses(annotationDb, annotatedClassNames, Adaptables.class);
        for (final String annotatedClassName : annotatedClassNames) {
            getLog().info(String.format("found adaptable annotation on %s", annotatedClassName));
            final String pathToClassFile = annotatedClassName.replace('.', '/') + ".class";
            final File classFile = new File(buildOutputDirectory, pathToClassFile);
            final FileInputStream input = new FileInputStream(classFile);
            final ClassReader classReader;
            try {
                classReader = new ClassReader(input);
            } finally {
                input.close();
            }
            final ClassNode classNode = new ClassNode();
            classReader.accept(classNode, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
            @SuppressWarnings("unchecked") final List<AnnotationNode> annotations = classNode.invisibleAnnotations;
            for (final AnnotationNode annotation : annotations) {
                if (ADAPTABLE_DESC.equals(annotation.desc)) {
                    parseAdaptableAnnotation(annotation, classNode, descriptor);
                } else if (ADAPTABLES_DESC.equals(annotation.desc)) {
                    parseAdaptablesAnnotation(annotation, classNode, descriptor);
                }
            }
        }
        final File outputFile = new File(outputDirectory, fileName);
        outputFile.getParentFile().mkdirs();
        try (FileWriter writer = new FileWriter(outputFile);
            JsonWriter jsonWriter = Json.createWriter(writer)) {
            jsonWriter.writeObject(JsonSupport.toJson(descriptor));
        }
        addResource();
    } catch (IOException e) {
        throw new MojoExecutionException("Unable to generate metadata", e);
    } catch (JsonException e) {
        throw new MojoExecutionException("Unable to generate metadata", e);
    }
}
Also used : AnnotationDB(org.scannotation.AnnotationDB) JsonException(javax.json.JsonException) ClassNode(org.objectweb.asm.tree.ClassNode) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) HashMap(java.util.HashMap) FileWriter(java.io.FileWriter) IOException(java.io.IOException) JsonWriter(javax.json.JsonWriter) FileInputStream(java.io.FileInputStream) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) ClassReader(org.objectweb.asm.ClassReader) File(java.io.File) HashSet(java.util.HashSet)

Example 43 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project drill by apache.

the class ClassTransformer method getImplementationClass.

public Class<?> getImplementationClass(final QueryClassLoader classLoader, final TemplateClassDefinition<?> templateDefinition, final String entireClass, final String materializedClassName) throws ClassTransformationException {
    // unfortunately, this hasn't been set up at construction time, so we have to do it here
    final ScalarReplacementOption scalarReplacementOption = ScalarReplacementOption.fromString(optionManager.getOption(SCALAR_REPLACEMENT_VALIDATOR));
    try {
        final long t1 = System.nanoTime();
        final ClassSet set = new ClassSet(null, templateDefinition.getTemplateClassName(), materializedClassName);
        final byte[][] implementationClasses = classLoader.getClassByteCode(set.generated, entireClass);
        long totalBytecodeSize = 0;
        Map<String, Pair<byte[], ClassNode>> classesToMerge = Maps.newHashMap();
        for (byte[] clazz : implementationClasses) {
            totalBytecodeSize += clazz.length;
            final ClassNode node = AsmUtil.classFromBytes(clazz, ClassReader.EXPAND_FRAMES);
            if (!AsmUtil.isClassOk(logger, "implementationClasses", node)) {
                throw new IllegalStateException("Problem found with implementationClasses");
            }
            classesToMerge.put(node.name, Pair.of(clazz, node));
        }
        final LinkedList<ClassSet> names = Lists.newLinkedList();
        final Set<ClassSet> namesCompleted = Sets.newHashSet();
        names.add(set);
        while (!names.isEmpty()) {
            final ClassSet nextSet = names.removeFirst();
            if (namesCompleted.contains(nextSet)) {
                continue;
            }
            final ClassNames nextPrecompiled = nextSet.precompiled;
            final byte[] precompiledBytes = byteCodeLoader.getClassByteCodeFromPath(nextPrecompiled.clazz);
            final ClassNames nextGenerated = nextSet.generated;
            // keeps only classes that have not be merged
            Pair<byte[], ClassNode> classNodePair = classesToMerge.remove(nextGenerated.slash);
            final ClassNode generatedNode;
            if (classNodePair != null) {
                generatedNode = classNodePair.getValue();
            } else {
                generatedNode = null;
            }
            /*
         * TODO
         * We're having a problem with some cases of scalar replacement, but we want to get
         * the code in so it doesn't rot anymore.
         *
         *  Here, we use the specified replacement option. The loop will allow us to retry if
         *  we're using TRY.
         */
            MergedClassResult result = null;
            boolean scalarReplace = scalarReplacementOption != ScalarReplacementOption.OFF && entireClass.length() < MAX_SCALAR_REPLACE_CODE_SIZE;
            while (true) {
                try {
                    result = MergeAdapter.getMergedClass(nextSet, precompiledBytes, generatedNode, scalarReplace);
                    break;
                } catch (RuntimeException e) {
                    // if we had a problem without using scalar replacement, then rethrow
                    if (!scalarReplace) {
                        throw e;
                    }
                    // if we did try to use scalar replacement, decide if we need to retry or not
                    if (scalarReplacementOption == ScalarReplacementOption.ON) {
                        // option is forced on, so this is a hard error
                        throw e;
                    }
                    /*
             * We tried to use scalar replacement, with the option to fall back to not using it.
             * Log this failure before trying again without scalar replacement.
             */
                    logger.info("scalar replacement failure (retrying)\n", e);
                    scalarReplace = false;
                }
            }
            for (String s : result.innerClasses) {
                s = s.replace(FileUtils.separatorChar, '.');
                names.add(nextSet.getChild(s));
            }
            classLoader.injectByteCode(nextGenerated.dot, result.bytes);
            namesCompleted.add(nextSet);
        }
        // adds byte code of the classes that have not been merged to make them accessible for outer class
        for (Map.Entry<String, Pair<byte[], ClassNode>> clazz : classesToMerge.entrySet()) {
            classLoader.injectByteCode(clazz.getKey().replace(FileUtils.separatorChar, '.'), clazz.getValue().getKey());
        }
        Class<?> c = classLoader.findClass(set.generated.dot);
        if (templateDefinition.getExternalInterface().isAssignableFrom(c)) {
            logger.debug("Compiled and merged {}: bytecode size = {}, time = {} ms.", c.getSimpleName(), DrillStringUtils.readable(totalBytecodeSize), (System.nanoTime() - t1 + 500_000) / 1_000_000);
            return c;
        }
        throw new ClassTransformationException("The requested class did not implement the expected interface.");
    } catch (CompileException | IOException | ClassNotFoundException e) {
        throw new ClassTransformationException(String.format("Failure generating transformation classes for value: \n %s", entireClass), e);
    }
}
Also used : CompileException(org.codehaus.commons.compiler.CompileException) Pair(org.apache.commons.lang3.tuple.Pair) ClassNode(org.objectweb.asm.tree.ClassNode) ClassTransformationException(org.apache.drill.exec.exception.ClassTransformationException) IOException(java.io.IOException) Map(java.util.Map) MergedClassResult(org.apache.drill.exec.compile.MergeAdapter.MergedClassResult)

Example 44 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project bytecode-viewer by Konloch.

the class BytecodeViewer method openFiles.

/**
     * Opens a file, optional if it should append to the recent files menu
     *
     * @param files       the file(s) you wish to open
     * @param recentFiles if it should append to the recent files menu
     */
public static void openFiles(final File[] files, boolean recentFiles) {
    if (recentFiles)
        for (File f : files) if (f.exists())
            BytecodeViewer.addRecentFile(f);
    BytecodeViewer.viewer.setIcon(true);
    update = true;
    Thread t = new Thread() {

        @Override
        public void run() {
            try {
                for (final File f : files) {
                    final String fn = f.getName();
                    if (!f.exists()) {
                        update = false;
                        showMessage("The file " + f.getAbsolutePath() + " could not be found.");
                    } else {
                        if (f.isDirectory()) {
                            FileContainer container = new FileContainer(f);
                            HashMap<String, byte[]> files = new HashMap<String, byte[]>();
                            boolean finished = false;
                            ArrayList<File> totalFiles = new ArrayList<File>();
                            totalFiles.add(f);
                            //f.getAbsolutePath().substring(0, f.getAbsolutePath().length()-f.getName().length());
                            String dir = f.getAbsolutePath();
                            while (!finished) {
                                boolean added = false;
                                for (int i = 0; i < totalFiles.size(); i++) {
                                    File child = totalFiles.get(i);
                                    if (child.listFiles() != null)
                                        for (File rocket : child.listFiles()) if (!totalFiles.contains(rocket)) {
                                            totalFiles.add(rocket);
                                            added = true;
                                        }
                                }
                                if (!added) {
                                    for (File child : totalFiles) if (child.isFile()) {
                                        String fileName = child.getAbsolutePath().substring(dir.length() + 1, child.getAbsolutePath().length()).replaceAll("\\\\", "\\/");
                                        files.put(fileName, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
                                    }
                                    finished = true;
                                }
                            }
                            container.files = files;
                            BytecodeViewer.files.add(container);
                        } else {
                            if (fn.endsWith(".jar") || fn.endsWith(".zip")) {
                                try {
                                    JarUtils.put(f);
                                } catch (final Exception e) {
                                    new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
                                    update = false;
                                }
                            } else if (fn.endsWith(".class")) {
                                try {
                                    byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
                                    String cafebabe = String.format("%02X%02X%02X%02X", bytes[0], bytes[1], bytes[2], bytes[3]);
                                    if (cafebabe.toLowerCase().equals("cafebabe")) {
                                        final ClassNode cn = JarUtils.getNode(bytes);
                                        FileContainer container = new FileContainer(f);
                                        container.files.put(cn.name + ".class", bytes);
                                        container.add(cn);
                                        BytecodeViewer.files.add(container);
                                    } else {
                                        showMessage(fn + ": Header does not start with CAFEBABE, ignoring.");
                                        update = false;
                                    }
                                } catch (final Exception e) {
                                    new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
                                    update = false;
                                }
                            } else if (fn.endsWith(".apk")) {
                                try {
                                    BytecodeViewer.viewer.setIcon(true);
                                    FileContainer container = new FileContainer(f);
                                    if (viewer.decodeAPKResources.isSelected()) {
                                        File decodedResources = new File(tempDir, MiscUtils.randomString(32) + ".apk");
                                        APKTool.decodeResources(f, decodedResources);
                                        container.files = JarUtils.loadResources(decodedResources);
                                    }
                                    container.files.putAll(JarUtils.loadResources(f));
                                    String name = getRandomizedName() + ".jar";
                                    File output = new File(tempDir, name);
                                    if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
                                        Dex2Jar.dex2Jar(f, output);
                                    else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
                                        Enjarify.apk2Jar(f, output);
                                    for (ClassNode classNode : JarUtils.loadClasses(output)) {
                                        container.add(classNode);
                                    }
                                    BytecodeViewer.viewer.setIcon(false);
                                    BytecodeViewer.files.add(container);
                                } catch (final Exception e) {
                                    new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
                                }
                                return;
                            } else if (fn.endsWith(".dex")) {
                                try {
                                    BytecodeViewer.viewer.setIcon(true);
                                    FileContainer container = new FileContainer(f);
                                    String name = getRandomizedName() + ".jar";
                                    File output = new File(tempDir, name);
                                    if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
                                        Dex2Jar.dex2Jar(f, output);
                                    else if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
                                        Enjarify.apk2Jar(f, output);
                                    for (ClassNode classNode : JarUtils.loadClasses(output)) {
                                        container.add(classNode);
                                    }
                                    BytecodeViewer.viewer.setIcon(false);
                                    BytecodeViewer.files.add(container);
                                } catch (final Exception e) {
                                    new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
                                }
                                return;
                            } else {
                                HashMap<String, byte[]> files = new HashMap<String, byte[]>();
                                byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
                                files.put(f.getName(), bytes);
                                FileContainer container = new FileContainer(f);
                                container.files = files;
                                BytecodeViewer.files.add(container);
                            }
                        }
                    }
                }
            } catch (final Exception e) {
                new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
            } finally {
                BytecodeViewer.viewer.setIcon(false);
                if (update)
                    try {
                        MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
                    } catch (java.lang.NullPointerException e) {
                    }
            }
        }
    };
    t.start();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) HashMap(java.util.HashMap) ExceptionUI(the.bytecode.club.bytecodeviewer.api.ExceptionUI) ArrayList(java.util.ArrayList) ExceptionUI(the.bytecode.club.bytecodeviewer.api.ExceptionUI)

Example 45 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project bytecode-viewer by Konloch.

the class CommandLineInput method executeCommandLine.

public void executeCommandLine() {
    try {
        File input = new File(parsed.getOptionValue("i"));
        File output = new File(parsed.getOptionValue("o"));
        String target = parsed.getOptionValue("t");
        Decompiler use = null;
        if (parsed.getOptionValue("decompiler") == null) {
            System.out.println("You can define another decompiler by appending -decompiler \"name\", by default procyon has been set.");
            use = Decompiler.PROCYON;
        } else if ((use = Decompiler.getByName(parsed.getOptionValue("decompiler"))) == null) {
            System.out.println("Decompiler not found. By default Procyon has been set.");
            use = Decompiler.PROCYON;
        }
        System.out.println("Decompiling " + input.getAbsolutePath() + " with " + use.getName());
        BytecodeViewer.openFiles(new File[] { input }, false);
        String containerName = BytecodeViewer.files.get(0).name;
        Thread.sleep(5 * 1000);
        if (target.equalsIgnoreCase("all")) {
            use.decompileToZip(output.getAbsolutePath());
        } else {
            try {
                ClassNode cn = BytecodeViewer.getClassNode(containerName, target);
                byte[] bytes = BytecodeViewer.getClassBytes(containerName, target);
                String contents = use.decompileClassNode(cn, bytes);
                FileUtils.write(output, contents, "UTF-8", false);
            } catch (Exception e) {
                new ExceptionUI(e);
            }
        }
        System.out.println("Finished.");
        System.out.println("Bytecode Viewer CLI v" + BytecodeViewer.version + " by @Konloch - http://bytecodeviewer.com");
        System.exit(0);
    } catch (Exception e) {
        new ExceptionUI(e);
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) Decompiler(the.bytecode.club.bytecodeviewer.decompilers.Decompiler) ExceptionUI(the.bytecode.club.bytecodeviewer.api.ExceptionUI) File(java.io.File)

Aggregations

ClassNode (org.objectweb.asm.tree.ClassNode)117 ClassReader (org.objectweb.asm.ClassReader)58 MethodNode (org.objectweb.asm.tree.MethodNode)42 ClassWriter (org.objectweb.asm.ClassWriter)28 IOException (java.io.IOException)14 FieldNode (org.objectweb.asm.tree.FieldNode)12 ArrayList (java.util.ArrayList)11 List (java.util.List)11 Test (org.junit.Test)10 ZipEntry (java.util.zip.ZipEntry)8 Method (java.lang.reflect.Method)7 FileInputStream (java.io.FileInputStream)6 InputStream (java.io.InputStream)6 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)6 AnnotationNode (org.objectweb.asm.tree.AnnotationNode)6 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)6 CheckClassAdapter (org.objectweb.asm.util.CheckClassAdapter)6 File (java.io.File)5 FileOutputStream (java.io.FileOutputStream)5 Label (org.objectweb.asm.Label)5