Search in sources :

Example 71 with ClassNode

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

the class AsmUtil method classFromBytes.

/**
 * Create a ClassNode from bytecode.
 *
 * @param classBytes the bytecode
 * @param asmReaderFlags flags for ASM; see {@link org.objectweb.asm.ClassReader#accept(org.objectweb.asm.ClassVisitor, int)}
 * @return the ClassNode
 */
public static ClassNode classFromBytes(final byte[] classBytes, final int asmReaderFlags) {
    final ClassNode classNode = new ClassNode(CompilationConfig.ASM_API_VERSION);
    final ClassReader classReader = new ClassReader(classBytes);
    classReader.accept(classNode, asmReaderFlags);
    return classNode;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassReader(org.objectweb.asm.ClassReader)

Example 72 with ClassNode

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

the class AsmUtil method logClassFromBytes.

/**
 * Write a class to the log.
 *
 * <p>Writes at level DEBUG.
 *
 * @param logTag a tag to print to the log
 * @param classBytes the class' bytecode
 * @param logger the logger to write to
 */
public static void logClassFromBytes(final Logger logger, final String logTag, final byte[] classBytes) {
    final ClassNode classNode = classFromBytes(classBytes, 0);
    logClass(logger, logTag, classNode);
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode)

Example 73 with ClassNode

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

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(DrillFileUtils.SEPARATOR_CHAR, '.');
                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(DrillFileUtils.SEPARATOR_CHAR, '.'), 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 74 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Galacticraft by micdoodle8.

the class InterfaceDependancyTransformer method transform.

@Override
public byte[] transform(String name, String tname, byte[] bytes) {
    if (bytes == null) {
        return null;
    }
    ClassNode cnode = ASMHelper.createClassNode(bytes);
    boolean hasDependancyInterfaces = false;
    if (cnode.visibleAnnotations != null) {
        for (AnnotationNode ann : cnode.visibleAnnotations) {
            if (ann.desc.equals(Type.getDescriptor(InterfaceDependancies.class))) {
                hasDependancyInterfaces = true;
                break;
            }
        }
    }
    if (!hasDependancyInterfaces) {
        return bytes;
    }
    hasDependancyInterfaces = false;
    for (Iterator<String> iterator = cnode.interfaces.iterator(); iterator.hasNext(); ) {
        try {
            Launch.classLoader.findClass(new ObfMapping(iterator.next()).toRuntime().javaClass());
        } catch (ClassNotFoundException cnfe) {
            iterator.remove();
            hasDependancyInterfaces = true;
        }
    }
    if (!hasDependancyInterfaces) {
        return bytes;
    }
    return ASMHelper.createBytes(cnode, 0);
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ObfMapping(codechicken.lib.asm.ObfMapping) AnnotationNode(org.objectweb.asm.tree.AnnotationNode)

Example 75 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Galacticraft by micdoodle8.

the class MCPDeobfuscationTransformer method injectCallback.

private byte[] injectCallback(byte[] bytes) {
    ClassNode cnode = ASMHelper.createClassNode(bytes);
    MethodNode mnode = ASMHelper.findMethod(new ObfMapping(cnode.name, "<clinit>", "()V"), cnode);
    mnode.instructions.insert(new MethodInsnNode(INVOKESTATIC, "codechicken/core/asm/MCPDeobfuscationTransformer", "loadCallback", "()V"));
    return ASMHelper.createBytes(cnode, 0);
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ObfMapping(codechicken.lib.asm.ObfMapping) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode)

Aggregations

ClassNode (org.objectweb.asm.tree.ClassNode)323 ClassReader (org.objectweb.asm.ClassReader)148 MethodNode (org.objectweb.asm.tree.MethodNode)120 ClassWriter (org.objectweb.asm.ClassWriter)70 IOException (java.io.IOException)44 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)37 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)34 InsnList (org.objectweb.asm.tree.InsnList)29 FieldNode (org.objectweb.asm.tree.FieldNode)28 ArrayList (java.util.ArrayList)27 Test (org.junit.Test)26 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)26 Label (org.objectweb.asm.Label)21 InputStream (java.io.InputStream)20 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)18 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)18 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)17 InsnNode (org.objectweb.asm.tree.InsnNode)17 Method (java.lang.reflect.Method)16 List (java.util.List)16