Search in sources :

Example 51 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project Bookshelf by Darkhax-Minecraft.

the class TransformerEnchantmentHelper method transform.

public static byte[] transform(String name, String transformedName, byte[] classBytes) {
    final ClassNode clazz = ASMUtils.createClassFromByteArray(classBytes);
    final MethodNode method = METHOD_GET_ENCH_LEVEL.getMethodNode(clazz);
    final InsnList n1 = new InsnList();
    final LabelNode start = new LabelNode();
    n1.add(start);
    n1.add(new TypeInsnNode(Opcodes.NEW, "net/darkhax/bookshelf/events/EnchantmentModifierEvent"));
    n1.add(new InsnNode(Opcodes.DUP));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 0));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 1));
    n1.add(METHOD_INIT_EVENT.getMethodInsn(Opcodes.INVOKESPECIAL, false));
    n1.add(new VarInsnNode(Opcodes.ASTORE, 2));
    final LabelNode l1 = new LabelNode();
    n1.add(l1);
    n1.add(FIELD_EVENT_BUS.getFieldNode(Opcodes.GETSTATIC));
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_POST.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    n1.add(new InsnNode(Opcodes.POP));
    final LabelNode l2 = new LabelNode();
    n1.add(l2);
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_CANCELED.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    final LabelNode vanillaLogic = new LabelNode();
    n1.add(new JumpInsnNode(Opcodes.IFEQ, vanillaLogic));
    final LabelNode l4 = new LabelNode();
    n1.add(l4);
    n1.add(new VarInsnNode(Opcodes.ALOAD, 2));
    n1.add(METHOD_GET_LEVELS.getMethodInsn(Opcodes.INVOKEVIRTUAL, false));
    n1.add(new InsnNode(Opcodes.IRETURN));
    n1.add(vanillaLogic);
    method.instructions.insertBefore(method.instructions.getFirst(), n1);
    return ASMUtils.createByteArrayFromClass(clazz, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 52 with LabelNode

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

the class ASMBlock method applyLabels.

public ASMBlock applyLabels(InsnListSection list2) {
    if (labels.isEmpty()) {
        return new ASMBlock(list2);
    }
    Set<LabelNode> cFlowLabels1 = labels.values();
    Set<LabelNode> cFlowLabels2 = InsnComparator.getControlFlowLabels(list2);
    ASMBlock block = new ASMBlock(list2);
    HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
    for (int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
        AbstractInsnNode insn1 = list.get(i);
        if (!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
            i++;
            continue;
        }
        AbstractInsnNode insn2 = list2.get(k);
        if (!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
            k++;
            continue;
        }
        if (insn1.getOpcode() != insn2.getOpcode()) {
            throw new IllegalArgumentException("Lists do not match:\n" + list + "\n\n" + list2);
        }
        switch(insn1.getType()) {
            case LABEL:
                labelMap.put((LabelNode) insn1, (LabelNode) insn2);
                break;
            case JUMP_INSN:
                labelMap.put(((JumpInsnNode) insn1).label, ((JumpInsnNode) insn2).label);
                break;
        }
        i++;
        k++;
    }
    for (Entry<String, LabelNode> entry : labels.entrySet()) {
        block.labels.put(entry.getKey(), labelMap.get(entry.getValue()));
    }
    return block;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 53 with LabelNode

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

the class ASMBlock method mergeLabels.

/**
 * Pulls all common labels from other into this
 *
 * @return this
 */
public ASMBlock mergeLabels(ASMBlock other) {
    if (labels.isEmpty() || other.labels.isEmpty()) {
        return this;
    }
    // common labels, give them our nodes
    HashMap<LabelNode, LabelNode> labelMap = list.identityLabelMap();
    for (Entry<String, LabelNode> entry : other.labels.entrySet()) {
        LabelNode old = labels.get(entry.getKey());
        if (old != null) {
            labelMap.put(old, entry.getValue());
        }
    }
    HashSet<LabelNode> usedLabels = new HashSet<LabelNode>();
    for (AbstractInsnNode insn = other.list.list.getFirst(); insn != null; insn = insn.getNext()) {
        if (insn.getType() == LABEL) {
            usedLabels.add((LabelNode) insn);
        }
    }
    replaceLabels(labelMap, usedLabels);
    return this;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 54 with LabelNode

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

the class ASMBlock method replaceLabels.

public void replaceLabels(Map<LabelNode, LabelNode> labelMap, Set<LabelNode> usedLabels) {
    for (AbstractInsnNode insn : list) {
        switch(insn.getType()) {
            case LABEL:
                AbstractInsnNode insn2 = insn.clone(labelMap);
                if (// identity mapping
                insn2 == insn) {
                    continue;
                }
                if (usedLabels.contains(insn2)) {
                    throw new IllegalStateException("LabelNode cannot be a part of two InsnLists");
                }
                list.replace(insn, insn2);
                break;
            case JUMP_INSN:
            case FRAME:
            case LOOKUPSWITCH_INSN:
            case TABLESWITCH_INSN:
                list.replace(insn, insn.clone(labelMap));
        }
    }
    for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
        String key = labels.inverse().get(entry.getKey());
        if (key != null) {
            labels.put(key, entry.getValue());
        }
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode)

Example 55 with LabelNode

use of org.objectweb.asm.tree.LabelNode in project phosphor by gmu-swe.

the class TaintTrackingClassVisitor method visitMethod.

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if (name.equals("hashCode") && desc.equals("()I"))
        generateHashCode = false;
    if (name.equals("equals") && desc.equals("(Ljava/lang/Object;)Z"))
        generateEquals = false;
    superMethodsToOverride.remove(name + desc);
    if (name.equals("compareTo"))
        implementsComparable = false;
    if (name.equals("hasAnyTaints"))
        isProxyClass = true;
    // Hack needed for java 7 + integer->tostring fixes
    if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("toUnsignedString"))
        access = (access & ~Opcodes.ACC_PRIVATE) | Opcodes.ACC_PUBLIC;
    if (name.contains(TaintUtils.METHOD_SUFFIX)) {
        // Some dynamic stuff might result in there being weird stuff here
        return new MethodVisitor(Opcodes.ASM5) {
        };
    }
    if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethodFromOurAnalysis(className, name, desc)) {
        // if (TaintUtils.DEBUG_CALLS)
        // System.out.println("Skipping instrumentation for  class: " + className + " method: " + name + " desc: " + desc);
        String newName = name;
        String newDesc = desc;
        if (!name.contains("<") && 0 == (access & Opcodes.ACC_NATIVE))
            newName = name + TaintUtils.METHOD_SUFFIX_UNINST;
        else if (name.equals("<init>")) {
            newDesc = desc.substring(0, desc.indexOf(')')) + Type.getDescriptor(UninstrumentedTaintSentinel.class) + ")" + desc.substring(desc.indexOf(')') + 1);
        }
        newDesc = TaintUtils.remapMethodDescForUninst(newDesc);
        MethodVisitor mv = super.visitMethod(access, newName, newDesc, signature, exceptions);
        mv = new UninstTaintSentinalArgFixer(mv, access, newName, newDesc, desc);
        mv = new SpecialOpcodeRemovingMV(mv, ignoreFrames, className, fixLdcClass);
        MethodVisitor _mv = mv;
        NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
        mv = new UninstrumentedReflectionHidingMV(analyzer, className);
        mv = new UninstrumentedCompatMV(access, className, name, newDesc, signature, (String[]) exceptions, mv, analyzer, ignoreFrames);
        LocalVariableManager lvs = new LocalVariableManager(access, newDesc, mv, analyzer, _mv, generateExtraLVDebug);
        ((UninstrumentedCompatMV) mv).setLocalVariableSorter(lvs);
        final PrimitiveArrayAnalyzer primArrayAnalyzer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, null);
        lvs.setPrimitiveArrayAnalyzer(primArrayAnalyzer);
        lvs.disable();
        mv = lvs;
        final MethodVisitor cmv = mv;
        MethodNode wrapper = new MethodNode(Opcodes.ASM5, (isInterface ? access : access & ~Opcodes.ACC_ABSTRACT), name, desc, signature, exceptions) {

            public void visitEnd() {
                super.visitEnd();
                this.accept(cmv);
            }

            public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                // determine if this is going to be uninst, and then if we need to pre-alloc for its return :/
                if (Configuration.WITH_SELECTIVE_INST && Instrumenter.isIgnoredMethod(owner, name, desc)) {
                // uninst
                } else {
                    Type returnType = Type.getReturnType(desc);
                    Type newReturnType = TaintUtils.getContainerReturnType(returnType);
                    if (newReturnType != returnType && !(returnType.getSort() == Type.ARRAY))
                        primArrayAnalyzer.wrapperTypesToPreAlloc.add(newReturnType);
                }
                super.visitMethodInsn(opcode, owner, name, desc, itf);
            }
        };
        if (!name.equals("<clinit>"))
            methodsToMakeUninstWrappersAround.add(wrapper);
        return wrapper;
    }
    if (Configuration.WITH_ENUM_BY_VAL && className.equals("java/lang/Enum") && name.equals("clone"))
        return null;
    if (TaintUtils.DEBUG_CALLS || TaintUtils.DEBUG_FIELDS || TaintUtils.DEBUG_FRAMES || TaintUtils.DEBUG_LOCAL)
        System.out.println("Instrumenting " + name + "\n\n\n\n\n\n");
    if (Instrumenter.IS_KAFFE_INST && className.equals("java/lang/VMSystem"))
        access = access | Opcodes.ACC_PUBLIC;
    else if (Instrumenter.IS_HARMONY_INST && className.endsWith("java/lang/VMMemoryManager")) {
        access = access & ~Opcodes.ACC_PRIVATE;
        access = access | Opcodes.ACC_PUBLIC;
    } else if ((className.equals("java/lang/Integer") || className.equals("java/lang/Long")) && name.equals("getChars")) {
        access = access | Opcodes.ACC_PUBLIC;
    }
    String originalName = name;
    if (FIELDS_ONLY) {
        // || isAnnotation
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
    if (originalName.contains("$$INVIVO")) {
        name = name + "_orig";
    }
    // We will need to add shadow args for each parameter that is a primitive. Because that worked so well last time.
    Type[] argTypes = Type.getArgumentTypes(desc);
    LinkedList<Type> newArgTypes = new LinkedList<Type>();
    boolean isRewrittenDesc = false;
    for (Type t : argTypes) {
        if (t.getSort() == Type.ARRAY) {
            if (t.getElementType().getSort() != Type.OBJECT) {
                if (t.getDimensions() > 1) {
                    newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
                    isRewrittenDesc = true;
                    continue;
                } else {
                    newArgTypes.add(MultiDTaintedArray.getTypeForType(t));
                    isRewrittenDesc = true;
                }
            }
        } else if (t.getSort() != Type.OBJECT) {
            isRewrittenDesc = true;
            newArgTypes.add(Type.getType(Configuration.TAINT_TAG_DESC));
        }
        newArgTypes.add(t);
    }
    if (Configuration.IMPLICIT_TRACKING && !name.equals("<clinit>")) {
        isRewrittenDesc = true;
        newArgTypes.add(Type.getType(ControlTaintTagStack.class));
    }
    if (isRewrittenDesc && name.equals("<init>"))
        newArgTypes.add(Type.getType(TaintSentinel.class));
    // If we are rewriting the return type, also add a param to pass for pre-alloc
    Type oldReturnType = Type.getReturnType(desc);
    Type newReturnType = TaintUtils.getContainerReturnType(Type.getReturnType(desc));
    if ((oldReturnType.getSort() != Type.VOID && oldReturnType.getSort() != Type.OBJECT && oldReturnType.getSort() != Type.ARRAY)) {
        newArgTypes.add(newReturnType);
    }
    Type[] newArgs = new Type[newArgTypes.size()];
    newArgs = newArgTypes.toArray(newArgs);
    boolean requiresNoChange = !isRewrittenDesc && newReturnType.equals(Type.getReturnType(desc));
    MethodNode wrapper = new MethodNode(access, name, desc, signature, exceptions);
    if (!requiresNoChange && !name.equals("<clinit>") && !(name.equals("<init>") && !isRewrittenDesc))
        methodsToAddWrappersFor.add(wrapper);
    String newDesc = Type.getMethodDescriptor(newReturnType, newArgs);
    // System.out.println("olddesc " + desc + " newdesc " + newDesc);
    if ((access & Opcodes.ACC_NATIVE) == 0 && !methodIsTooBigAlready(name, desc)) {
        // not a native method
        if (!name.contains("<") && !requiresNoChange)
            name = name + TaintUtils.METHOD_SUFFIX;
        // if(className.equals("sun/misc/URLClassPath$JarLoader"))
        // System.out.println("\t\t:"+name+newDesc);
        MethodVisitor mv = super.visitMethod(access, name, newDesc, signature, exceptions);
        mv = new TaintTagFieldCastMV(mv);
        MethodVisitor rootmV = mv;
        mv = new SourceSinkTaintingMV(mv, access, className, name, newDesc, desc);
        // mv = new CheckMethodAdapter(mv);
        // mv = new SpecialOpcodeRemovingMV(mv,ignoreFrames, className);
        // mv = reflectionMasker;
        // PropertyDebug debug = new PropertyDebug(Opcodes.ASM4, mv, access, name, newDesc,className);
        MethodVisitor optimizer;
        optimizer = mv;
        // if (DO_OPT)
        // optimizer = new PopOptimizingMV(mv, access, className, name, newDesc, signature, exceptions);
        mv = new SpecialOpcodeRemovingMV(optimizer, ignoreFrames, className, fixLdcClass);
        // optimizer = new PopOptimizingMV(mv, access,className, name, newDesc, signature, exceptions);
        NeverNullArgAnalyzerAdapter analyzer = new NeverNullArgAnalyzerAdapter(className, access, name, newDesc, mv);
        // TODO - how do we handle directbytebuffers?
        mv = new StringTaintVerifyingMV(analyzer, (implementsSerializable || className.startsWith("java/nio/") || className.startsWith("java/io/BUfferedInputStream") || className.startsWith("sun/nio")), analyzer);
        ReflectionHidingMV reflectionMasker = new ReflectionHidingMV(mv, className, name, analyzer);
        PrimitiveBoxingFixer boxFixer = new PrimitiveBoxingFixer(access, className, name, desc, signature, exceptions, reflectionMasker, analyzer);
        LocalVariableManager lvs;
        TaintPassingMV tmv;
        MethodVisitor nextMV;
        {
            // ImplicitTaintRemoverMV implicitCleanup = new ImplicitTaintRemoverMV(access, className, name, desc, signature, exceptions, boxFixer, analyzer);
            tmv = new TaintPassingMV(boxFixer, access, className, name, newDesc, signature, exceptions, desc, analyzer, rootmV);
            tmv.setFields(fields);
            TaintAdapter custom = null;
            lvs = new LocalVariableManager(access, newDesc, tmv, analyzer, mv, generateExtraLVDebug);
            nextMV = lvs;
        }
        MethodArgReindexer mar = new MethodArgReindexer(nextMV, access, name, newDesc, desc, wrapper);
        TaintLoadCoercer tlc = new TaintLoadCoercer(className, access, name, desc, signature, exceptions, mar, ignoreFrames);
        PrimitiveArrayAnalyzer primitiveArrayFixer = new PrimitiveArrayAnalyzer(className, access, name, desc, signature, exceptions, tlc);
        NeverNullArgAnalyzerAdapter preAnalyzer = new NeverNullArgAnalyzerAdapter(className, access, name, desc, primitiveArrayFixer);
        MethodVisitor mvNext = preAnalyzer;
        mvNext = preAnalyzer;
        primitiveArrayFixer.setAnalyzer(preAnalyzer);
        boxFixer.setLocalVariableSorter(lvs);
        tmv.setArrayAnalyzer(primitiveArrayFixer);
        tmv.setLVOffset(mar.getNewArgOffset());
        tmv.setLocalVariableSorter(lvs);
        // i'm lazy. this guy will tell the LVS what return types to prealloc
        lvs.setPrimitiveArrayAnalyzer(primitiveArrayFixer);
        reflectionMasker.setLvs(lvs);
        // if(IS_RUNTIME_INST)
        // {
        // return mvNext;
        // }
        final MethodVisitor prev = mvNext;
        MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {

            @Override
            protected LabelNode getLabelNode(Label l) {
                if (!Configuration.READ_AND_SAVE_BCI)
                    return super.getLabelNode(l);
                if (!(l.info instanceof LabelNode)) {
                    l.info = new LabelNode(l);
                }
                return (LabelNode) l.info;
            }

            @Override
            public void visitEnd() {
                super.visitEnd();
                this.accept(prev);
            }
        };
        if (!isInterface && !originalName.contains("$$INVIVO"))
            this.myMethods.add(rawMethod);
        forMore.put(wrapper, rawMethod);
        if (Configuration.extensionMethodVisitor != null) {
            try {
                TaintAdapter custom = Configuration.extensionMethodVisitor.getConstructor(Integer.TYPE, String.class, String.class, String.class, String.class, String[].class, MethodVisitor.class, NeverNullArgAnalyzerAdapter.class, String.class, String.class).newInstance(access, className, name, desc, signature, exceptions, rawMethod, null, classSource, classDebug);
                custom.setFields(fields);
                custom.setSuperName(superName);
                return custom;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
        }
        return rawMethod;
    } else {
        // this is a native method. we want here to make a $taint method that will call the original one.
        final MethodVisitor prev = super.visitMethod(access, name, desc, signature, exceptions);
        MethodNode rawMethod = new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) {

            @Override
            public void visitEnd() {
                super.visitEnd();
                this.accept(prev);
            }
        };
        forMore.put(wrapper, rawMethod);
        return rawMethod;
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) Label(org.objectweb.asm.Label) UninstrumentedTaintSentinel(edu.columbia.cs.psl.phosphor.runtime.UninstrumentedTaintSentinel) MethodVisitor(org.objectweb.asm.MethodVisitor) MethodNode(org.objectweb.asm.tree.MethodNode) LinkedList(java.util.LinkedList) InvocationTargetException(java.lang.reflect.InvocationTargetException) ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Type(org.objectweb.asm.Type) NeverNullArgAnalyzerAdapter(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter)

Aggregations

LabelNode (org.objectweb.asm.tree.LabelNode)89 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)37 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)32 Label (org.objectweb.asm.Label)28 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)23 InsnList (org.objectweb.asm.tree.InsnList)22 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)21 InsnNode (org.objectweb.asm.tree.InsnNode)20 MethodNode (org.objectweb.asm.tree.MethodNode)19 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)17 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)16 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)15 ClassNode (org.objectweb.asm.tree.ClassNode)14 ClassReader (org.objectweb.asm.ClassReader)12 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)10 Type (org.objectweb.asm.Type)8 LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)8 LinkedList (java.util.LinkedList)6 ArrayList (java.util.ArrayList)5 LookupSwitchInsnNode (org.objectweb.asm.tree.LookupSwitchInsnNode)5