Example usage for org.objectweb.asm.tree ClassNode ClassNode

List of usage examples for org.objectweb.asm.tree ClassNode ClassNode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree ClassNode ClassNode.

Prototype

public ClassNode() 

Source Link

Document

Constructs a new ClassNode .

Usage

From source file:net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (transformedName.equals("paulscode.sound.Source")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "removed", "Z", null, null)); // adding field 'public boolean removed;'

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);/*from ww w  .ja  va2 s .c  o  m*/
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.Library")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("removeSource") && m.desc.equals("(Ljava/lang/String;)V")) // trying to find paulscode.sound.Library.removeSource(String)
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException(
                    "Error processing " + transformedName + " - no removeSource method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") // searching for mySource.cleanup() node (line 1086)
                    && ((MethodInsnNode) insn).name.equals("cleanup")) {
                referenceNode = insn;
                break;
            }
        }

        if (referenceNode != null) {
            LabelNode after = (LabelNode) referenceNode.getNext();

            AbstractInsnNode beginning = referenceNode.getPrevious();

            int varIndex = ((VarInsnNode) beginning).var;

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // adding extra if (mySource.toStream)
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "toStream", "Z"));
            LabelNode elseNode = new LabelNode();
            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.IFEQ, elseNode)); // if fails (else) -> go to mySource.cleanup();

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // if (mySource.toStream) { mySource.removed = true; }
            method.instructions.insertBefore(beginning, new InsnNode(Opcodes.ICONST_1));
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.PUTFIELD, "paulscode/sound/Source", "removed", "Z"));

            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.GOTO, after)); // still inside if -> jump to sourceMap.remove( sourcename );

            method.instructions.insertBefore(beginning, elseNode);
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.StreamThread")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("run") && m.desc.equals("()V")) // trying to find paulscode.sound.StreamThread.run();
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException("Error processing " + transformedName + " - no run method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("java/util/ListIterator") // searching for 'src = iter.next();' node (line 110)
                    && ((MethodInsnNode) insn).name.equals("next")) {
                referenceNode = insn.getNext().getNext();
                break;
            }
        }

        if (referenceNode != null) {
            int varIndex = ((VarInsnNode) referenceNode).var;

            LabelNode after = (LabelNode) referenceNode.getNext();
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // add if(removed)
            method.instructions.insertBefore(after,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "removed", "Z"));
            method.instructions.insertBefore(after, new JumpInsnNode(Opcodes.IFEQ, after));

            // if the source has been marked as removed, clean it up and set the variable to null so it will be removed from the list
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // src.cleanup();
            method.instructions.insertBefore(after, new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                    "paulscode/sound/Source", "cleanup", "()V", false));
            method.instructions.insertBefore(after, new InsnNode(Opcodes.ACONST_NULL)); // src = null;
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ASTORE, varIndex));
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    }

    return basicClass;
}

From source file:net.minecraftforge.gradle.tasks.DeobfuscateJar.java

License:Open Source License

private byte[] stripSynthetics(String name, byte[] data) {
    ClassReader reader = new ClassReader(data);
    ClassNode node = new ClassNode();

    reader.accept(node, 0);/*from ww w . j  a v a  2 s  .com*/

    if ((node.access & Opcodes.ACC_ENUM) == 0 && !node.superName.equals("java/lang/Enum")
            && (node.access & Opcodes.ACC_SYNTHETIC) == 0) {
        // ^^ is for ignoring enums.

        for (FieldNode f : ((List<FieldNode>) node.fields)) {
            f.access = f.access & (0xffffffff - Opcodes.ACC_SYNTHETIC);
            //getLogger().lifecycle("Stripping field: "+f.name);
        }

        for (MethodNode m : ((List<MethodNode>) node.methods)) {
            m.access = m.access & (0xffffffff - Opcodes.ACC_SYNTHETIC);
            //getLogger().lifecycle("Stripping method: "+m.name);
        }
    }

    ClassWriter writer = new ClassWriter(0);
    node.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecraftforge.gradle.tasks.MergeJars.java

License:Open Source License

private void copyClass(ZipFile inJar, ZipEntry entry, ZipOutputStream outJar, boolean isClientOnly)
        throws IOException {
    ClassReader reader = new ClassReader(readEntry(inJar, entry));
    ClassNode classNode = new ClassNode();

    reader.accept(classNode, 0);/*from  w  w  w .  j  a  v  a 2s.c o m*/

    if (classNode.visibleAnnotations == null) {
        classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
    }
    classNode.visibleAnnotations.add(getSideAnn(isClientOnly));

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    byte[] data = writer.toByteArray();

    ZipEntry newEntry = new ZipEntry(entry.getName());
    if (outJar != null) {
        outJar.putNextEntry(newEntry);
        outJar.write(data);
    }
}

From source file:net.minecraftforge.gradle.tasks.MergeJars.java

License:Open Source License

private ClassNode getClassNode(byte[] data) {
    ClassReader reader = new ClassReader(data);
    ClassNode classNode = new ClassNode();
    reader.accept(classNode, 0);/*ww  w.j a  v  a  2s .  c om*/
    return classNode;
}

From source file:net.minecraftforge.gradle.user.patcherUser.forge.McVersionTransformer.java

License:Open Source License

@Override
public byte[] transform(byte[] data) {
    String mcVersion = Constants.resolveString(this.mcVersion);

    ClassReader reader = new ClassReader(data);
    ClassNode node = new ClassNode();

    reader.accept(node, 0);/*from   w w  w . j  a v a 2 s .  c o  m*/
    List<AnnotationNode> annots = node.visibleAnnotations;

    if (annots == null || annots.isEmpty()) // annotations
        return data;

    for (AnnotationNode mod : annots) {
        if (mod.desc.endsWith("fml/common/Mod;")) {
            int index = mod.values.indexOf("acceptedMinecraftVersions");
            if (index == -1) {
                mod.values.add("acceptedMinecraftVersions");
                mod.values.add("[" + mcVersion + "]");
            }

            break; // break out, im done. There cant be 2 @Mods in a file... can there?
        }
    }

    ClassWriter writer = new ClassWriter(0);
    node.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.ice.launch.transformers.AccessTransformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null || !modifiers.containsKey(transformedName)) {
        return bytes;
    }//from   w ww . j av  a 2  s  .co m

    ClassNode classNode = new ClassNode();
    ClassReader reader = new ClassReader(bytes);
    reader.accept(classNode, 0);

    for (Modifier m : modifiers.get(transformedName)) {
        if (m.isClass) { // Class
            classNode.access = m.transform(classNode.access);
        } else if (m.desc == null) { // Field
            for (FieldNode fieldNode : classNode.fields) {
                if (m.wildcard || fieldNode.name.equals(m.name)) {
                    fieldNode.access = m.transform(fieldNode.access);
                    if (!m.wildcard)
                        break;
                }
            }
        } else {
            List<MethodNode> overridable = null;

            for (MethodNode methodNode : classNode.methods) {
                if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) {
                    boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0;
                    methodNode.access = m.transform(methodNode.access);

                    // Constructors always use INVOKESPECIAL
                    // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL
                    // so that overridden methods will be called. Only need to scan this class, because obviously the method was private.
                    if (!methodNode.name.equals("<init>") && wasPrivate
                            && (methodNode.access & ACC_PRIVATE) == 0) {
                        if (overridable == null) {
                            overridable = new ArrayList<>(3);
                        }

                        overridable.add(methodNode);
                    }

                    if (!m.wildcard)
                        break;
                }
            }

            if (overridable != null) {
                for (MethodNode methodNode : classNode.methods) {
                    for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) {
                        AbstractInsnNode insn = itr.next();
                        if (insn.getOpcode() == INVOKESPECIAL) {
                            MethodInsnNode mInsn = (MethodInsnNode) insn;
                            for (MethodNode replace : overridable) {
                                if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) {
                                    mInsn.setOpcode(INVOKEVIRTUAL);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    ClassWriter writer = new ClassWriter(0);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.ice.launch.transformers.DeobfuscationTransformer.java

License:Open Source License

private String getFieldType(String owner, String name) {
    Map<String, String> fieldDescriptions = this.fieldDescriptions.get(owner);
    if (fieldDescriptions != null)
        return fieldDescriptions.get(name);

    byte[] bytes = getBytes(owner);
    if (bytes == null)
        return null;

    ClassReader reader = new ClassReader(bytes);
    ClassNode classNode = new ClassNode();
    reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

    String result = null;// ww w.jav a 2  s  .c o  m
    fieldDescriptions = Maps.newHashMapWithExpectedSize(classNode.fields.size());
    for (FieldNode fieldNode : classNode.fields) {
        fieldDescriptions.put(fieldNode.name, fieldNode.desc);
        if (fieldNode.name.equals(name)) {
            result = fieldNode.desc;
        }
    }

    this.fieldDescriptions.put(owner, fieldDescriptions);
    return result;
}

From source file:net.minecrell.quartz.launch.mappings.MappingsParser.java

License:MIT License

public static ClassNode loadClassStructure(ClassReader reader) {
    ClassNode classNode = new ClassNode();
    reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
    return classNode;
}

From source file:net.minecrell.quartz.launch.transformers.MappingTreeTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (basicClass == null) {
        return null;
    }//from   w w  w . j a  va  2  s . co  m

    if (!transform(name, transformedName)) {
        return basicClass;
    }

    ClassNode classNode = new ClassNode();
    ClassReader reader = new ClassReader(basicClass);
    reader.accept(classNode, readerFlags());

    transform(name, transformedName, classNode);

    ClassWriter writer = new ClassWriter(writerFlags());
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.quartz.mappings.transformer.context.SimpleTransformerContext.java

License:Open Source License

@Override
public ClassReader getTransformed(ClassReader reader) {
    if (reader == null) {
        return null;
    }// w  w w .j  a v  a 2s  . co  m

    String name = reader.getClassName();
    String transformedName = this.renamer.map(name);
    name = name.replace('/', '.');
    transformedName = transformedName.replace('/', '.');

    List<CoreClassTransformer> coreTransformers = new ArrayList<>(this.coreTransformers.size());

    int readerFlags = 0;
    int writerFlags = 0;

    for (CoreClassTransformer transformer : this.coreTransformers) {
        if (transformer.transform(name, transformedName)) {
            readerFlags |= transformer.readerFlags();
            writerFlags |= transformer.writerFlags();
            coreTransformers.add(transformer);
        }
    }

    List<TreeClassTransformer> treeTransformers = new ArrayList<>(this.treeTransformers.size());

    for (TreeClassTransformer transformer : this.treeTransformers) {
        if (transformer.transform(name, transformedName)) {
            readerFlags |= transformer.readerFlags();
            writerFlags |= transformer.writerFlags();
            treeTransformers.add(transformer);
        }
    }

    ClassWriter writer = new ClassWriter(writerFlags);
    ClassVisitor visitor;
    ClassNode classNode = null;

    if (!treeTransformers.isEmpty()) {
        classNode = new ClassNode();
        visitor = classNode;
    } else {
        visitor = writer;
    }

    for (CoreClassTransformer transformer : coreTransformers) {
        visitor = transformer.transform(name, transformedName, reader, visitor);
    }

    reader.accept(visitor, readerFlags);

    if (!treeTransformers.isEmpty()) {
        for (TreeClassTransformer transformer : treeTransformers) {
            classNode = transformer.transform(name, transformedName, classNode);
        }

        classNode.accept(writer);
    }

    return new ClassReader(writer.toByteArray());
}