Search in sources :

Example 1 with ControlTaintTagStack

use of edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack in project phosphor by gmu-swe.

the class ReflectionMasker method fixAllArgs.

@SuppressWarnings("rawtypes")
public static Object[] fixAllArgs(Object[] in, Constructor c, boolean isObjTags) {
    // System.out.println("Making constructo rcall to " + c);
    if (c != null && in != null && c.getParameterTypes().length != in.length) {
        Object[] ret = new Object[c.getParameterTypes().length];
        int j = 0;
        for (int i = 0; i < in.length; i++) {
            if (c.getParameterTypes()[j].isPrimitive()) {
                if (in[i] instanceof TaintedWithIntTag)
                    ret[j] = ((TaintedWithIntTag) in[i]).getPHOSPHOR_TAG();
                else if (in[i] instanceof TaintedWithObjTag)
                    ret[j] = ((TaintedWithObjTag) in[i]).getPHOSPHOR_TAG();
                else
                    ret[j] = 0;
                j++;
            } else if (c.getParameterTypes()[j] == Configuration.TAINT_TAG_OBJ_CLASS) {
                if (in[i] instanceof TaintedWithObjTag)
                    ret[j] = ((TaintedWithObjTag) in[i]).getPHOSPHOR_TAG();
                else
                    ret[j] = null;
                j++;
            } else if (LazyArrayIntTags.class.isAssignableFrom(c.getParameterTypes()[j])) {
                LazyArrayIntTags arr = ((LazyArrayIntTags) in[i]);
                if (arr == null) {
                    ret[j] = null;
                    j++;
                    ret[j] = null;
                    j++;
                } else {
                    ret[j] = arr.taints;
                    j++;
                    ret[j] = arr.getVal();
                    j++;
                }
                continue;
            } else if (LazyArrayObjTags.class.isAssignableFrom(c.getParameterTypes()[j])) {
                LazyArrayObjTags arr = ((LazyArrayObjTags) in[i]);
                if (arr == null) {
                    ret[j] = null;
                    j++;
                    ret[j] = null;
                    j++;
                } else {
                    ret[j] = arr.taints;
                    j++;
                    ret[j] = arr.getVal();
                    j++;
                }
                continue;
            }
            ret[j] = in[i];
            j++;
        }
        return ret;
    } else if (in == null && c.getParameterTypes().length == 1) {
        Object[] ret = new Object[1];
        ret[0] = null;
        return ret;
    } else if (in == null && c.getParameterTypes().length == 2) {
        Object[] ret = new Object[2];
        ret[0] = new ControlTaintTagStack();
        ret[1] = null;
        return ret;
    }
    return in;
}
Also used : ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) LazyArrayObjTags(edu.columbia.cs.psl.phosphor.struct.LazyArrayObjTags) TaintedWithIntTag(edu.columbia.cs.psl.phosphor.struct.TaintedWithIntTag) LazyArrayIntTags(edu.columbia.cs.psl.phosphor.struct.LazyArrayIntTags) TaintedWithObjTag(edu.columbia.cs.psl.phosphor.struct.TaintedWithObjTag)

Example 2 with ControlTaintTagStack

use of edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack in project phosphor by gmu-swe.

the class TaintPassingMV method visitVarInsn.

@SuppressWarnings("unused")
@Override
public void visitVarInsn(int opcode, int var) {
    // System.out.println(nextLoadisTracked +" " +Printer.OPCODES[opcode] + var +" - " + analyzer.locals.get(var) + "\t"+analyzer.locals);
    if (!nextLoadisTracked && opcode < 200) {
        if ((Configuration.IMPLICIT_LIGHT_TRACKING || Configuration.IMPLICIT_TRACKING) && opcode == Opcodes.ASTORE) {
            super.visitInsn(DUP);
            super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
            super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
        }
        if (opcode == Opcodes.ASTORE) {
            // System.out.println(analyzer.stackTagStatus);
            if (topCarriesTaint())
                throw new IllegalStateException();
        }
        super.visitVarInsn(opcode, var);
        switch(opcode) {
            case Opcodes.ILOAD:
            case Opcodes.FLOAD:
            case Opcodes.ALOAD:
                analyzer.stackTagStatus.set(analyzer.stack.size() - 1, analyzer.stack.get(analyzer.stack.size() - 1));
                break;
            case Opcodes.LLOAD:
            case Opcodes.DLOAD:
                analyzer.stackTagStatus.set(analyzer.stack.size() - 2, analyzer.stack.get(analyzer.stack.size() - 2));
                break;
        }
        return;
    }
    nextLoadisTracked = false;
    if (opcode == TaintUtils.NEVER_AUTOBOX) {
        System.out.println("Never autobox: " + var);
        varsNeverToForceBox.add(var);
        return;
    }
    // Following 2 special cases are notes left by the post-dominator analysis for implicit taint tracking
    if (opcode == TaintUtils.BRANCH_START) {
        branchStarting = var;
        branchDepth++;
        return;
    }
    if (opcode == TaintUtils.BRANCH_END) {
        branchDepth--;
        passthruMV.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
        // if(var > Byte.MAX_VALUE)
        // passthruMV.visitLdcInsn(var);
        // else
        // passthruMV.visitIntInsn(BIPUSH, var);
        passthruMV.visitVarInsn(ALOAD, taintTagsLoggedAtJumps[var]);
        passthruMV.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(ControlTaintTagStack.class), "pop", "(" + "Ledu/columbia/cs/psl/phosphor/struct/EnqueuedTaint;" + ")V", false);
        analyzer.clearLabels();
        return;
    }
    if (opcode == TaintUtils.ALWAYS_AUTOBOX && analyzer.locals.size() > var && analyzer.locals.get(var) instanceof String) {
        Type t = Type.getType((String) analyzer.locals.get(var));
        if (t.getSort() == Type.ARRAY && t.getElementType().getSort() != Type.OBJECT && lvs.varToShadowVar.containsKey(var)) {
            // System.out.println("Restoring " + var + " to be boxed");
            super.visitVarInsn(ALOAD, lvs.varToShadowVar.get(var));
            super.visitVarInsn(ASTORE, var);
        }
        return;
    }
    if (opcode == TaintUtils.ALWAYS_BOX_JUMP) {
        boxAtNextJump.add(var);
        return;
    }
    if (isIgnoreAllInstrumenting) {
        if (opcode != TaintUtils.FORCE_CTRL_STORE)
            super.visitVarInsn(opcode, var);
        return;
    }
    int shadowVar = -1;
    if (TaintUtils.DEBUG_LOCAL)
        System.out.println(this.name + " " + Printer.OPCODES[opcode] + " on " + var + " last arg" + lastArg + ", stack: " + analyzer.stackTagStatus);
    if (opcode == Opcodes.ASTORE && TaintUtils.DEBUG_FRAMES) {
        System.out.println(this.name + " ASTORE " + var + ", shadowvar contains " + lvs.varToShadowVar.get(var) + " oldvartype " + varTypes.get(var));
    }
    boolean boxIt = false;
    if ((Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) && !Configuration.WITHOUT_PROPOGATION) {
        switch(opcode) {
            case ISTORE:
            case FSTORE:
                super.visitInsn(SWAP);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                if (!Configuration.MULTI_TAINTING)
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(ILedu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)I", false);
                else {
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                }
                super.visitInsn(SWAP);
                break;
            case DSTORE:
            case LSTORE:
                super.visitInsn(DUP2_X1);
                super.visitInsn(POP2);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                if (!Configuration.MULTI_TAINTING)
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(ILedu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)I", false);
                else {
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                }
                super.visitInsn(DUP_X2);
                super.visitInsn(POP);
                break;
            case ASTORE:
                // if (!topOfStackIsNull()) {
                super.visitInsn(DUP);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                // }
                break;
            case TaintUtils.FORCE_CTRL_STORE:
                forceCtrlAdd.add(var);
                return;
        }
    }
    if (var == 0 && !isStatic) {
        // accessing "this" so no-op, die here so we never have to worry about uninitialized this later on.
        super.visitVarInsn(opcode, var);
        return;
    } else if (var < lastArg && TaintUtils.getShadowTaintType(paramTypes[var].getDescriptor()) != null) {
        // accessing an arg; remap it
        Type localType = paramTypes[var];
        if (TaintUtils.DEBUG_LOCAL)
            System.out.println(Arrays.toString(paramTypes) + ",,," + var);
        if (TaintUtils.getShadowTaintType(localType.getDescriptor()) != null)
            shadowVar = var - 1;
    } else {
        // not accessing an arg
        Object oldVarType = varTypes.get(var);
        if (lvs.varToShadowVar.containsKey(var))
            shadowVar = lvs.varToShadowVar.get(var);
        // System.out.println(Arrays.toString(paramTypes));
        if (oldVarType != null) {
            // In this case, we already have a shadow for this. Make sure that it's the right kind of shadow though.
            if (TaintUtils.DEBUG_LOCAL)
                System.out.println(name + Textifier.OPCODES[opcode] + " " + var + " old type is " + varTypes.get(var) + " shadow is " + shadowVar);
            // First: If we thought this was NULL before, but it's not NULL now (but instead another type), then update that.
            if (opcode == ALOAD && oldVarType == Opcodes.NULL && analyzer.locals.get(var) instanceof String) {
                varTypes.put(var, analyzer.locals.get(var));
            }
            if ((oldVarType == Opcodes.NULL || oldVarType instanceof String) && opcode != ASTORE && opcode != ALOAD) {
                // Went from a TYPE to a primitive.
                if (opcode == ISTORE || opcode == FSTORE || opcode == DSTORE || opcode == LSTORE)
                    varTypes.put(var, getTopOfStackObject());
                else
                    varTypes.put(var, Configuration.TAINT_TAG_STACK_TYPE);
                if (shadowVar > -1) {
                    while (shadowVar >= analyzer.locals.size()) {
                        analyzer.locals.add(Opcodes.TOP);
                    }
                    analyzer.locals.set(shadowVar, Configuration.TAINT_TAG_STACK_TYPE);
                    lvs.remapLocal(shadowVar, Type.getType(Configuration.TAINT_TAG_DESC));
                }
            } else if (oldVarType instanceof Integer && oldVarType != Opcodes.NULL && (opcode == ASTORE || opcode == ALOAD)) {
                // Went from primitive to TYPE
                if (opcode == ASTORE)
                    varTypes.put(var, getTopOfStackObject());
                else
                    varTypes.put(var, "Lunidentified;");
                if (shadowVar > -1) {
                    while (shadowVar >= analyzer.locals.size()) {
                        analyzer.locals.add(Opcodes.TOP);
                    }
                    // System.err.println("Setting the local type for " + shadowVar + analyzer.stack);
                    if (opcode == ASTORE) {
                        String shadow = TaintUtils.getShadowTaintType(getTopOfStackType().getDescriptor());
                        if (shadow == null) {
                            shadow = Configuration.TAINT_TAG_ARRAYDESC;
                            analyzer.locals.set(shadowVar, Opcodes.TOP);
                        } else if (shadow.equals(Configuration.TAINT_TAG_DESC))
                            analyzer.locals.set(shadowVar, Configuration.TAINT_TAG_STACK_TYPE);
                        else
                            analyzer.locals.set(shadowVar, shadow);
                        lvs.remapLocal(shadowVar, Type.getType(shadow));
                    } else {
                        lvs.remapLocal(shadowVar, Type.getType(Configuration.TAINT_TAG_ARRAYDESC));
                        analyzer.locals.set(shadowVar, Configuration.TAINT_TAG_ARRAYDESC);
                    }
                }
            }
            if (opcode == ASTORE && !topOfStackIsNull() && !oldVarType.equals(getTopOfStackObject())) {
                varTypes.put(var, getTopOfStackObject());
            }
        }
        if (shadowVar < 0) {
            // We don't have a shadowvar for this yet. Do we need one?
            if (opcode == ALOAD) {
                if (analyzer.locals.size() > var && analyzer.locals.get(var) instanceof String) {
                    Type localType = Type.getObjectType((String) analyzer.locals.get(var));
                    if (TaintUtils.isPrimitiveArrayType(localType)) {
                        lvs.varToShadowVar.put(var, lvs.newShadowLV(MultiDTaintedArray.getTypeForType(localType), var));
                        varTypes.put(var, Opcodes.NULL);
                        shadowVar = lvs.varToShadowVar.get(var);
                        if (shadowVar == analyzer.locals.size())
                            analyzer.locals.add(Opcodes.NULL);
                    }
                }
            } else if (opcode == ASTORE) {
                if (topCarriesTaint()) {
                    // That's easy.
                    if (getTopOfStackObject() == Opcodes.NULL) {
                        lvs.varToShadowVar.put(var, lvs.newShadowLV(Type.getType(Configuration.TAINT_TAG_ARRAYDESC), var));
                    } else
                        lvs.varToShadowVar.put(var, lvs.newShadowLV(MultiDTaintedArray.getTypeForType(getTopOfStackType()), var));
                    varTypes.put(var, getTopOfStackObject());
                    shadowVar = lvs.varToShadowVar.get(var);
                }
            } else {
                lvs.varToShadowVar.put(var, lvs.newShadowLV(Type.getType(Configuration.TAINT_TAG_DESC), var));
                varTypes.put(var, Configuration.TAINT_TAG_STACK_TYPE);
                shadowVar = lvs.varToShadowVar.get(var);
                if (opcode == ILOAD || opcode == FLOAD || opcode == DLOAD || opcode == LLOAD) {
                    if (shadowVar == analyzer.locals.size())
                        analyzer.locals.add(Configuration.TAINT_TAG_STACK_TYPE);
                }
            }
        }
        if (opcode == Opcodes.ASTORE && TaintUtils.DEBUG_FRAMES) {
            System.out.println("ASTORE " + var + ", shadowvar contains " + lvs.varToShadowVar.get(var));
        }
        if (shadowVar > -1 && TaintUtils.DEBUG_LOCAL) {
            System.out.println("using shadow " + shadowVar + "for " + var);
            System.out.println("LVS: " + analyzer.locals);
        }
    }
    if (shadowVar >= 0) {
        switch(opcode) {
            case Opcodes.ILOAD:
            case Opcodes.FLOAD:
            case Opcodes.LLOAD:
            case Opcodes.DLOAD:
                super.visitVarInsn((!Configuration.MULTI_TAINTING ? ILOAD : ALOAD), shadowVar);
                super.visitVarInsn(opcode, var);
                analyzer.setTopOfStackTagged();
                return;
            case Opcodes.ALOAD:
                if (TaintUtils.DEBUG_LOCAL)
                    System.out.println("PRE ALOAD " + var);
                if (TaintUtils.DEBUG_LOCAL)
                    System.out.println("Locals: " + analyzer.locals);
                Type localType = null;
                if (var >= analyzer.locals.size()) {
                    System.err.println(analyzer.locals);
                    System.err.println(className);
                    IllegalStateException ex = new IllegalStateException("Trying to load an arg (" + var + ") past end of analyzer locals");
                    throw ex;
                }
                localType = Type.getType(Configuration.TAINT_TAG_ARRAYDESC);
                if (analyzer.locals.get(var) == Opcodes.NULL) {
                    if (TaintUtils.DEBUG_LOCAL)
                        System.out.println("Ignoring shadow " + shadowVar + " on ALOAD " + var + " because var is null");
                    super.visitInsn(ACONST_NULL);
                    super.visitVarInsn(opcode, var);
                    analyzer.setTopOfStackTagged();
                    return;
                }
                if (analyzer.locals.get(var) instanceof Integer) {
                    System.out.println(className + "." + name);
                    System.out.println("ALOAD " + var + " but found " + analyzer.locals.get(var));
                    System.out.println(analyzer.locals);
                    throw new IllegalArgumentException();
                }
                if (analyzer.locals.get(var) instanceof Label) {
                    // this var is uninitilaized obj. def not an array or
                    // anythign we care about.
                    super.visitVarInsn(opcode, var);
                    return;
                }
                if (analyzer.locals.get(var) instanceof TaggedValue)
                    localType = Type.getType((String) ((TaggedValue) analyzer.locals.get(var)).v);
                else
                    localType = Type.getType((String) analyzer.locals.get(var));
                if (TaintUtils.DEBUG_LOCAL)
                    System.out.println("Pre ALOAD " + var + "localtype " + localType);
                if (localType.getSort() == Type.ARRAY && localType.getDimensions() == 1) {
                    switch(localType.getElementType().getSort()) {
                        case Type.ARRAY:
                        case Type.OBJECT:
                            super.visitVarInsn(opcode, var);
                            return;
                        default:
                            super.visitVarInsn(ALOAD, shadowVar);
                            super.visitVarInsn(opcode, var);
                            analyzer.setTopOfStackTagged();
                            if (TaintUtils.DEBUG_LOCAL)
                                System.out.println("POST ALOAD " + var);
                            if (TaintUtils.DEBUG_LOCAL)
                                System.out.println("Locals: " + analyzer.locals);
                            return;
                    }
                } else {
                    System.out.println(var + ", sahdow " + shadowVar);
                    super.visitVarInsn(opcode, var);
                    System.out.println(analyzer.stackTagStatus);
                    System.out.println(localType);
                    System.out.println(analyzer.locals.get(shadowVar));
                    throw new IllegalStateException("ALOAD " + var + "Shadow " + shadowVar);
                // return;
                }
            case Opcodes.ISTORE:
            case Opcodes.LSTORE:
            case Opcodes.FSTORE:
            case Opcodes.DSTORE:
                super.visitVarInsn(opcode, var);
                if (Configuration.MULTI_TAINTING) {
                    super.visitMethodInsn(Opcodes.INVOKESTATIC, Configuration.TAINT_TAG_INTERNAL_NAME, "copyTaint", "(" + Configuration.TAINT_TAG_DESC + ")" + Configuration.TAINT_TAG_DESC, false);
                }
                super.visitVarInsn((!Configuration.MULTI_TAINTING ? ISTORE : ASTORE), shadowVar);
                return;
            case Opcodes.ASTORE:
                Object stackEl = analyzer.stack.get(analyzer.stack.size() - 1);
                if (stackEl == Opcodes.NULL) {
                    super.visitVarInsn(ASTORE, shadowVar);
                    super.visitVarInsn(opcode, var);
                    if (TaintUtils.DEBUG_LOCAL)
                        System.out.println("stack top was null, now POST ASTORE " + var + ": stack is " + analyzer.stack + " lvs " + analyzer.locals);
                    return;
                }
                if (!(stackEl instanceof String)) {
                    super.visitVarInsn(opcode, var);
                    IllegalStateException ex = new IllegalStateException("Doing ASTORE but top of stack isn't a type, it's " + stackEl);
                    ex.printStackTrace();
                    return;
                }
                Type stackType = Type.getType((String) stackEl);
                // System.out.println("ASTORE " + var + ": stack is " + analyzer.stack + " StackType is " + stackType + " lvs " + analyzer.locals);
                if (stackType.getSort() == Type.ARRAY && stackType.getDimensions() == 1) {
                    switch(stackType.getElementType().getSort()) {
                        case Type.ARRAY:
                            super.visitVarInsn(opcode, var);
                            super.visitVarInsn(ASTORE, shadowVar);
                            if (TaintUtils.DEBUG_LOCAL)
                                System.out.println("POST ASTORE " + var + ": stack is " + analyzer.stack + " lvs " + analyzer.locals);
                            return;
                        case Type.OBJECT:
                            super.visitVarInsn(opcode, var);
                            if (TaintUtils.DEBUG_LOCAL)
                                System.out.println("POST ASTORE " + var + ": stack is " + analyzer.stack + " lvs " + analyzer.locals);
                            return;
                        default:
                            super.visitVarInsn(opcode, var);
                            super.visitVarInsn(ASTORE, shadowVar);
                            if (TaintUtils.DEBUG_LOCAL)
                                System.out.println("POST ASTORE " + var + ": stack is " + analyzer.stack + " lvs " + analyzer.locals);
                            return;
                    }
                }
                // System.out.println("Ignoring shadow, because top of stack is " + stackType);
                super.visitVarInsn(opcode, var);
                return;
            case Opcodes.RET:
                break;
        }
    } else {
        if (opcode == ASTORE && TaintUtils.isPrimitiveArrayType(getTopOfStackType())) {
            System.out.println("box astore " + var);
            registerTaintedArray();
            super.visitVarInsn(opcode, var);
        } else
            super.visitVarInsn(opcode, var);
        if (TaintUtils.DEBUG_LOCAL)
            System.out.println("(no shadow) POST " + opcode + " " + var + ": stack is " + analyzer.stack + " lvs " + analyzer.locals);
    }
}
Also used : ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Type(org.objectweb.asm.Type) TaggedValue(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue) Label(org.objectweb.asm.Label) OffsetPreservingLabel(edu.columbia.cs.psl.phosphor.instrumenter.asm.OffsetPreservingLabel)

Example 3 with ControlTaintTagStack

use of edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack in project phosphor by gmu-swe.

the class NativeHelper method ensureIsUnBoxedImplicitTracking.

public static final Collection ensureIsUnBoxedImplicitTracking(Collection in) {
    if (in != null) {
        Collection tmp = null;
        for (Object o : in) {
            if (o != null && MultiDTaintedArrayWithObjTag.isPrimitiveBoxClass(o.getClass()) != null) {
                if (tmp == null) {
                    try {
                        tmp = (Collection) in.getClass().getConstructor().newInstance(null);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
                tmp.add$$PHOSPHORTAGGED(MultiDTaintedArrayWithObjTag.unboxRaw(o), new ControlTaintTagStack(), new TaintedBooleanWithObjTag());
            } else
                break;
        }
        if (tmp != null) {
            in.clear();
            tmp.add$$PHOSPHORTAGGED(tmp, new ControlTaintTagStack(), new TaintedBooleanWithObjTag());
        }
    }
    return in;
}
Also used : ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Collection(java.util.Collection) TaintedBooleanWithObjTag(edu.columbia.cs.psl.phosphor.struct.TaintedBooleanWithObjTag)

Example 4 with ControlTaintTagStack

use of edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack in project phosphor by gmu-swe.

the class TaintPassingMV method visitMaxs.

@Override
public void visitMaxs(int maxStack, int maxLocals) {
    if (rewriteLVDebug) {
        Label end = new Label();
        super.visitLabel(end);
    // Label thisFrameStart = new Label();
    // for(LocalVariableNode lv : lvsFromLastFrame)
    // {
    // lv.end = new LabelNode(thisFrameStart);
    // lv.accept(mv);
    // }
    // lvsFromLastFrame.clear();
    }
    if (Configuration.IMPLICIT_TRACKING && !arrayAnalyzer.hasFinally) {
        super.visitLabel(endLabel);
        super.visitLabel(popAllLabel);
        int maxLV = lvs.idxOfMasterControlLV;
        for (int i : taintTagsLoggedAtJumps) if (i > maxLV)
            maxLV = i;
        Object[] baseLvs = new Object[maxLV + 1];
        for (int i = 0; i < baseLvs.length; i++) baseLvs[i] = TOP;
        String ctrl = "edu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack";
        baseLvs[lvs.idxOfMasterControlLV] = ctrl;
        for (int i = 1; i < taintTagsLoggedAtJumps.length; i++) {
            baseLvs[taintTagsLoggedAtJumps[i]] = "edu/columbia/cs/psl/phosphor/struct/EnqueuedTaint";
        }
        super.visitFrame(F_NEW, baseLvs.length, baseLvs, 1, new Object[] { "java/lang/Throwable" });
        for (int i = 1; i < taintTagsLoggedAtJumps.length; i++) {
            passthruMV.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
            passthruMV.visitVarInsn(ALOAD, taintTagsLoggedAtJumps[i]);
            passthruMV.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(ControlTaintTagStack.class), "pop", "(" + "Ledu/columbia/cs/psl/phosphor/struct/EnqueuedTaint;" + ")V", false);
        }
        super.visitInsn(ATHROW);
    }
    super.visitMaxs(maxStack, maxLocals);
}
Also used : ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Label(org.objectweb.asm.Label) OffsetPreservingLabel(edu.columbia.cs.psl.phosphor.instrumenter.asm.OffsetPreservingLabel)

Example 5 with ControlTaintTagStack

use of edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack in project phosphor by gmu-swe.

the class TaintPassingMV method visitInsn.

@Override
public void visitInsn(int opcode) {
    // System.out.println(name+" "+PhosphorTextifier.MORE_OPCODES[opcode-200]);
    if (opcode == TaintUtils.CUSTOM_SIGNAL_1 || opcode == TaintUtils.CUSTOM_SIGNAL_2 || opcode == TaintUtils.CUSTOM_SIGNAL_3 || opcode == TaintUtils.LOOP_HEADER) {
        Configuration.taintTagFactory.signalOp(opcode, null);
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_0) {
        nextDupCopiesTaint0 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_1) {
        nextDupCopiesTaint1 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_2) {
        nextDupCopiesTaint2 = true;
        return;
    }
    if (opcode == TaintUtils.DUP_TAINT_AT_3) {
        nextDupCopiesTaint3 = true;
        return;
    }
    if (opcode == TaintUtils.TRACKED_LOAD) {
        nextLoadisTracked = true;
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.FORCE_CTRL_STORE) {
        // If there is anything on the stack right now, apply the current marker to it
        if (analyzer.stack.isEmpty() || topOfStackIsNull())
            return;
        Type onStack = getTopOfStackType();
        if (onStack.getSort() != Type.OBJECT && onStack.getSort() != Type.ARRAY) {
            if (onStack.getSize() == 1) {
                super.visitInsn(SWAP);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                super.visitInsn(SWAP);
            } else {
                super.visitInsn(DUP2_X1);
                super.visitInsn(POP2);
                super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTags", "(" + Configuration.TAINT_TAG_DESC + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)" + Configuration.TAINT_TAG_DESC, false);
                super.visitInsn(DUP_X2);
                super.visitInsn(POP);
            }
        } else {
            super.visitInsn(DUP);
            super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
            super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
        }
        return;
    }
    if (opcode == TaintUtils.RAW_INSN) {
        isRawInsns = !isRawInsns;
        return;
    }
    if (opcode == TaintUtils.IGNORE_EVERYTHING) {
        // System.err.println("VisitInsn is ignoreverything! in  " + name);
        // new Exception().printStackTrace();
        isIgnoreAllInstrumenting = !isIgnoreAllInstrumenting;
        isIgnoreEverything = !isIgnoreEverything;
        Configuration.taintTagFactory.signalOp(opcode, null);
        super.visitInsn(opcode);
        return;
    }
    if (opcode == TaintUtils.NO_TAINT_STORE_INSN) {
        isTaintlessArrayStore = true;
        return;
    }
    if (isIgnoreAllInstrumenting || isRawInsns) {
        super.visitInsn(opcode);
        return;
    }
    if (Configuration.IMPLICIT_TRACKING && !Configuration.WITHOUT_PROPOGATION) {
        switch(opcode) {
            // case LRETURN:
            case ATHROW:
                for (int i = 1; i < taintTagsLoggedAtJumps.length; i++) {
                    passthruMV.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    passthruMV.visitVarInsn(ALOAD, taintTagsLoggedAtJumps[i]);
                    passthruMV.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(ControlTaintTagStack.class), "pop", "(" + "Ledu/columbia/cs/psl/phosphor/struct/EnqueuedTaint;" + ")V", false);
                }
                break;
        }
    }
    switch(opcode) {
        case Opcodes.NOP:
            super.visitInsn(opcode);
            break;
        case Opcodes.ACONST_NULL:
            // System.out.println("NULL at" + curLabel);
            // System.out.println("NULL IN " + curLabel);
            super.visitInsn(opcode);
            if (nextLoadisTracked) {
                nextLoadisTracked = false;
                super.visitInsn(ACONST_NULL);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.ICONST_M1:
        case Opcodes.ICONST_0:
        case Opcodes.ICONST_1:
        case Opcodes.ICONST_2:
        case Opcodes.ICONST_3:
        case Opcodes.ICONST_4:
        case Opcodes.ICONST_5:
        case Opcodes.LCONST_0:
        case Opcodes.LCONST_1:
        case Opcodes.FCONST_0:
        case Opcodes.FCONST_1:
        case Opcodes.FCONST_2:
        case Opcodes.DCONST_0:
        case Opcodes.DCONST_1:
            if (nextLoadisTracked) {
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                    super.visitMethodInsn(INVOKEVIRTUAL, "edu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack", "copyTag", "()" + Configuration.TAINT_TAG_DESC, false);
                } else
                    super.visitInsn(Configuration.NULL_TAINT_LOAD_OPCODE);
                nextLoadisTracked = false;
                super.visitInsn(opcode);
                analyzer.setTopOfStackTagged();
            } else
                super.visitInsn(opcode);
            return;
        case Opcodes.LALOAD:
        case Opcodes.DALOAD:
        case Opcodes.IALOAD:
        case Opcodes.FALOAD:
        case Opcodes.BALOAD:
        case Opcodes.CALOAD:
        case Opcodes.SALOAD:
            Type taintType = Type.getType(Configuration.TAINT_TAG_DESC);
            boolean doingLoadWithIdxTaint = false;
            if (Configuration.ARRAY_INDEX_TRACKING && topCarriesTaint()) {
                if (nextLoadisTracked)
                    doingLoadWithIdxTaint = true;
                else {
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    analyzer.clearTopOfStackTagged();
                }
            }
            String elType = null;
            String elName = null;
            switch(opcode) {
                case Opcodes.LALOAD:
                    elName = "Long";
                    elType = "J";
                    break;
                case Opcodes.DALOAD:
                    elName = "Double";
                    elType = "D";
                    break;
                case Opcodes.IALOAD:
                    elName = "Int";
                    elType = "I";
                    break;
                case Opcodes.FALOAD:
                    elName = "Float";
                    elType = "F";
                    break;
                case Opcodes.BALOAD:
                    elName = "Byte";
                    // System.out.println("BALOAD " + analyzer.stack);
                    if (analyzer.stack.get(analyzer.stack.size() - (doingLoadWithIdxTaint ? 3 : 2)) instanceof Integer)
                        elType = "B";
                    else {
                        elType = Type.getType((String) analyzer.stack.get(analyzer.stack.size() - (doingLoadWithIdxTaint ? 3 : 2))).getElementType().getDescriptor();
                    }
                    break;
                case Opcodes.CALOAD:
                    elName = "Char";
                    elType = "C";
                    break;
                case Opcodes.SALOAD:
                    elName = "Short";
                    elType = "S";
                    break;
            }
            if (TaintUtils.DEBUG_FRAMES)
                System.out.println(name + desc + "PRE XALOAD " + elType + ": " + analyzer.stack + "; " + analyzer.locals);
            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - (doingLoadWithIdxTaint ? 3 : 2)) instanceof TaggedValue || nextLoadisTracked) {
                // TA A T I
                if (elType.equals("Z"))
                    elName = "Boolean";
                Type retType = Type.getObjectType("edu/columbia/cs/psl/phosphor/struct/Tainted" + elName + "With" + (Configuration.MULTI_TAINTING ? "Obj" : "Int") + "Tag");
                int prealloc = lvs.getPreAllocedReturnTypeVar(retType);
                super.visitVarInsn(ALOAD, prealloc);
                String methodName = "get";
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                }
                super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "edu/columbia/cs/psl/phosphor/struct/Lazy" + elName + "Array" + (Configuration.MULTI_TAINTING ? "Obj" : "Int") + "Tags", methodName, "(" + "[" + elType + (doingLoadWithIdxTaint ? Configuration.TAINT_TAG_DESC : "") + "I" + retType.getDescriptor() + (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING ? "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;" : "") + ")" + retType.getDescriptor(), false);
                if (nextLoadisTracked) {
                    super.visitInsn(DUP);
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
                    super.visitInsn(SWAP);
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "val", elType);
                    nextLoadisTracked = false;
                    analyzer.setTopOfStackTagged();
                } else {
                    super.visitFieldInsn(GETFIELD, retType.getInternalName(), "val", elType);
                }
            } else {
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.AALOAD:
            int lvForIdxtaint = -1;
            taintType = Type.getType(Configuration.TAINT_TAG_DESC);
            if (Configuration.ARRAY_INDEX_TRACKING && topCarriesTaint()) {
                super.visitInsn(SWAP);
                lvForIdxtaint = lvs.getTmpLV(taintType);
                super.visitVarInsn(taintType.getOpcode(ISTORE), lvForIdxtaint);
                analyzer.clearTopOfStackTagged();
            }
            // ?TA A I
            // System.out.println("AALOAD " + analyzer.stackTagStatus);
            Object arrayType = analyzer.stack.get(analyzer.stack.size() - 2);
            Type t = getTypeForStackType(arrayType);
            if (t.getDimensions() == 1 && t.getElementType().getDescriptor().startsWith("Ledu/columbia/cs/psl/phosphor/struct/Lazy")) {
                super.visitInsn(opcode);
                try {
                    retrieveTaintedArray("[" + (MultiDTaintedArray.getPrimitiveTypeForWrapper(Class.forName(t.getElementType().getInternalName().replace("/", ".")))));
                    if (!nextLoadisTracked) {
                        super.visitInsn(SWAP);
                        super.visitInsn(POP);
                    } else
                        analyzer.setTopOfStackTagged();
                    nextLoadisTracked = false;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else
                super.visitInsn(opcode);
            if (lvForIdxtaint >= 0) {
                super.visitInsn(DUP);
                super.visitVarInsn(taintType.getOpcode(ILOAD), lvForIdxtaint);
                super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                lvs.freeTmpLV(lvForIdxtaint);
            }
            break;
        case Opcodes.AASTORE:
            arrayType = analyzer.stack.get(analyzer.stack.size() - 1);
            t = getTypeForStackType(arrayType);
            // Type taintArrayType = getTypeForStackType(analyzer.stack.get(analyzer.stack.size() - 2));
            // System.out.println("AASTORE of " + arrayType + " ONTO ...");
            // System.out.println(analyzer.stack);
            // better look to see if we are storing a NULL into a multidemnsional array...
            boolean idxTainted = Configuration.ARRAY_INDEX_TRACKING && analyzer.stackTagStatus.get(analyzer.stack.size() - (topCarriesTaint() ? 1 : 0) - 2) instanceof TaggedValue;
            if (arrayType == Opcodes.NULL) {
                Object theArray = analyzer.stack.get(analyzer.stack.size() - 3 - (idxTainted ? 1 : 0));
                t = getTypeForStackType(theArray);
                // System.out.println(theArray);
                if (theArray != Opcodes.NULL && t.getElementType().getSort() != Type.OBJECT)
                    super.visitInsn(ACONST_NULL);
            }
            if (t.getSort() == Type.ARRAY && t.getElementType().getDescriptor().length() == 1) {
                // this is a multi-d array. make it work, even if it's nasty.
                if (!analyzer.isTopOfStackTagged()) {
                    super.visitTypeInsn(NEW, MultiDTaintedArray.getTypeForType(t).getInternalName());
                    super.visitInsn(DUP_X1);
                    super.visitInsn(SWAP);
                    super.visitMethodInsn(INVOKESPECIAL, MultiDTaintedArray.getTypeForType(t).getInternalName(), "<init>", "(" + t + ")V", false);
                    nextLoadisTracked = false;
                // analyzer.setTopOfStackTagged();
                } else
                    registerTaintedArray();
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitInsn(DUP);
                    super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                }
                if (idxTainted) {
                    // Array Taint Index Val
                    super.visitInsn(DUP2_X1);
                    // Array I V T I V
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    // Array I V T V
                    super.visitInsn(SWAP);
                    // Array  I V V T
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                }
                super.visitInsn(opcode);
            } else {
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitInsn(DUP);
                    super.visitVarInsn(ALOAD, lvs.getIdxOfMasterControlLV());
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsOnObject", "(Ljava/lang/Object;Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                }
                if (idxTainted) {
                    // Array T I V
                    super.visitInsn(DUP2_X1);
                    // Array I V T I V
                    super.visitInsn(SWAP);
                    super.visitInsn(POP);
                    // Array I V T V
                    super.visitInsn(SWAP);
                    // Array  I V V T
                    super.visitMethodInsn(INVOKESTATIC, Configuration.MULTI_TAINT_HANDLER_CLASS, "combineTagsInPlace", "(Ljava/lang/Object;" + Configuration.TAINT_TAG_DESC + ")V", false);
                }
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.IASTORE:
        case Opcodes.LASTORE:
        case Opcodes.FASTORE:
        case Opcodes.DASTORE:
        case Opcodes.BASTORE:
        case Opcodes.CASTORE:
        case Opcodes.SASTORE:
            // public static void XASTORE(int[] TArray, int[] Array, int idxTaint, int idx, int valTaint, int val) {
            int valStoreOpcode;
            int valLoadOpcode;
            Object beingStored = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - (opcode == LASTORE || opcode == DASTORE ? 2 : 1));
            int offsetToArray = 4;
            int ob = (opcode == LASTORE || opcode == DASTORE ? 2 : 1) + ((beingStored instanceof TaggedValue) ? 1 : 0) + 1;
            boolean tagIsTracked = Configuration.ARRAY_INDEX_TRACKING && analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - ob) instanceof TaggedValue;
            if (tagIsTracked)
                offsetToArray++;
            switch(opcode) {
                case Opcodes.LASTORE:
                    valStoreOpcode = LSTORE;
                    valLoadOpcode = LLOAD;
                    elType = "J";
                    offsetToArray++;
                    break;
                case Opcodes.DASTORE:
                    valStoreOpcode = DSTORE;
                    valLoadOpcode = DLOAD;
                    elType = "D";
                    offsetToArray++;
                    break;
                case Opcodes.IASTORE:
                    valStoreOpcode = ISTORE;
                    valLoadOpcode = ILOAD;
                    elType = "I";
                    break;
                case Opcodes.FASTORE:
                    valStoreOpcode = FSTORE;
                    valLoadOpcode = FLOAD;
                    elType = "F";
                    break;
                case Opcodes.BASTORE:
                    elType = "B";
                    if (beingStored instanceof TaggedValue) {
                        elType = Type.getType((String) analyzer.stack.get(analyzer.stack.size() - offsetToArray)).getElementType().getDescriptor();
                        if (elType.equals("Z"))
                            elName = "Boolean";
                    }
                    valStoreOpcode = ISTORE;
                    valLoadOpcode = ILOAD;
                    break;
                case Opcodes.CASTORE:
                    valLoadOpcode = ILOAD;
                    valStoreOpcode = ISTORE;
                    elType = "C";
                    break;
                case Opcodes.SASTORE:
                    valLoadOpcode = ILOAD;
                    valStoreOpcode = ISTORE;
                    elType = "S";
                    break;
                default:
                    valLoadOpcode = -1;
                    valStoreOpcode = -1;
                    elType = null;
            }
            if (TaintUtils.DEBUG_FRAMES) {
                System.out.println("XASTORE>>>" + elType);
                System.out.println(beingStored);
                System.out.println(analyzer.stackTagStatus);
                System.out.println(analyzer.stack);
            }
            if (!(beingStored instanceof TaggedValue)) {
                // System.out.println(offsetToArray);
                if (tagIsTracked) {
                    String typ = (String) analyzer.stack.get(analyzer.stack.size() - offsetToArray);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + elType + ")V", false);
                } else
                    super.visitInsn(opcode);
            } else if (analyzer.stackTagStatus.get(analyzer.stack.size() - offsetToArray) instanceof TaggedValue) {
                String typ = (String) analyzer.stack.get(analyzer.stack.size() - offsetToArray - 1);
                if (Configuration.IMPLICIT_TRACKING || Configuration.IMPLICIT_LIGHT_TRACKING) {
                    super.visitVarInsn(ALOAD, lvs.idxOfMasterControlLV);
                    if (tagIsTracked)
                        super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + Configuration.TAINT_TAG_DESC + elType + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                    else
                        super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + "I" + Configuration.TAINT_TAG_DESC + elType + "Ledu/columbia/cs/psl/phosphor/struct/ControlTaintTagStack;)V", false);
                } else if (tagIsTracked)
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + Configuration.TAINT_TAG_DESC + "I" + Configuration.TAINT_TAG_DESC + elType + ")V", false);
                else
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, typ, "set", "([" + elType + "I" + Configuration.TAINT_TAG_DESC + elType + ")V", false);
            } else {
                if (tagIsTracked)
                    throw new IllegalStateException(analyzer.stackTagStatus.toString());
                super.visitInsn(opcode);
            }
            isTaintlessArrayStore = false;
            break;
        case Opcodes.POP:
            if (topCarriesTaint()) {
                super.visitInsn(POP2);
                return;
            }
            super.visitInsn(opcode);
            return;
        case Opcodes.POP2:
            if (topCarriesTaint()) {
                super.visitInsn(POP2);
                if (topCarriesTaint())
                    super.visitInsn(POP2);
                else
                    super.visitInsn(POP);
                return;
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                super.visitInsn(POP);
                super.visitInsn(POP2);
            } else
                super.visitInsn(opcode);
            return;
        case Opcodes.DUP:
            if (nextDupCopiesTaint0 && nextDupCopiesTaint1) {
                super.visitInsn(Opcodes.DUP2);
            } else if (!nextDupCopiesTaint0 && nextDupCopiesTaint1) {
                super.visitInsn(DUP_X1);
                analyzer.stackTagStatus.set(analyzer.stack.size() - 3, analyzer.stack.get(analyzer.stack.size() - 3));
            } else if (nextDupCopiesTaint0 && !nextDupCopiesTaint1) {
                super.visitInsn(DUP);
                analyzer.stackTagStatus.set(analyzer.stack.size() - 1, analyzer.stack.get(analyzer.stack.size() - 1));
            } else {
                // TOP should never be tainted and reach here
                super.visitInsn(Opcodes.DUP);
            }
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2:
            Object topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
            // 0 1 -> 0 1 2 3
            if (getStackElementSize(topOfStack) == 1) {
                if (nextDupCopiesTaint0) {
                    int offset = 2;
                    if (topCarriesTaint())
                        offset++;
                    // 3, or 2?
                    Object secondOnStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - offset);
                    if (!(secondOnStack instanceof TaggedValue)) {
                        if (nextDupCopiesTaint1 && !nextDupCopiesTaint2 && !nextDupCopiesTaint3) {
                            // Dup the top 2 items, leaving a taint behind for the top item, the second item is not tainted
                            // A TB B -> A TB B A TB B
                            LocalVariableNode[] lvs = storeToLocals(3);
                            loadLV(2, lvs);
                            loadLV(1, lvs);
                            loadLV(0, lvs);
                            loadLV(2, lvs);
                            loadLV(1, lvs);
                            loadLV(0, lvs);
                            freeLVs(lvs);
                            return;
                        }
                        throw new IllegalStateException("Told to copy taint of second thing on stack but got " + secondOnStack);
                    }
                    if (getStackElementSize(secondOnStack) == 2)
                        // Should be true always or was invalid already
                        throw new UnsupportedOperationException();
                    if (nextDupCopiesTaint1) {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // 0, 1, 2, 3
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            } else {
                                // 0, 1, 2, !3
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                // loadLV(1, lvs);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                freeLVs(lvs);
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                                // 0, 1, !2, 3
                                throw new UnsupportedOperationException();
                            } else {
                                // 0,1,!2,!3
                                throw new UnsupportedOperationException();
                            }
                        }
                    } else {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // 0, !1, 2, 3
                                // AB CD -> A CD AB CD (Top)
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] lvs = storeToLocals(4);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            // System.out.println(analyzer.stackTagStatus);
                            } else {
                                // System.out.println("PRE " + analyzer.stack + analyzer.stackTagStatus);
                                if (topOfStack instanceof TaggedValue) {
                                    super.visitInsn(SWAP);
                                    super.visitInsn(POP);
                                }
                                // TA B -> TA B TA B
                                Type topType = getTypeForStackType(topOfStack);
                                int top = lvs.getTmpLV();
                                super.visitInsn(TaintUtils.IS_TMP_STORE);
                                super.visitVarInsn(topType.getOpcode(ISTORE), top);
                                // TA
                                super.visitInsn(DUP2);
                                // TA TA
                                super.visitVarInsn(topType.getOpcode(ILOAD), top);
                                // TA TA B
                                super.visitInsn(DUP_X2);
                                // AA BB AA BB
                                lvs.freeTmpLV(top);
                            // analyzer.setTopOfStackTagged();
                            // analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 3, new TaggedValue(secondOnStack));
                            // System.out.println("POST " + analyzer.stack + analyzer.stackTagStatus);
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                                throw new UnsupportedOperationException();
                            } else // 0,!1,!2,!3
                            {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else // !0
                {
                    if (nextDupCopiesTaint1) {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            } else {
                            // !0, 1,2,!3
                            }
                        }
                    } else // !0, !1
                    {
                        if (nextDupCopiesTaint2) {
                            if (nextDupCopiesTaint3) {
                                // !0, !1, 2, 3
                                // right here..
                                // T V T V -> V V T V T V
                                int v1 = lvs.getTmpLV();
                                super.visitVarInsn(ISTORE, v1);
                                int t1 = lvs.getTmpLV();
                                super.visitVarInsn(Configuration.TAINT_STORE_OPCODE, t1);
                                int v2 = lvs.getTmpLV();
                                super.visitVarInsn(ISTORE, v2);
                                int t2 = lvs.getTmpLV();
                                super.visitVarInsn(Configuration.TAINT_STORE_OPCODE, t2);
                                super.visitVarInsn(ILOAD, v2);
                                super.visitVarInsn(ILOAD, v1);
                                super.visitVarInsn(Configuration.TAINT_LOAD_OPCODE, t2);
                                super.visitVarInsn(ILOAD, v2);
                                super.visitVarInsn(Configuration.TAINT_LOAD_OPCODE, t1);
                                super.visitVarInsn(ILOAD, v1);
                                lvs.freeTmpLV(v1);
                                lvs.freeTmpLV(v2);
                                lvs.freeTmpLV(t1);
                                lvs.freeTmpLV(t2);
                                return;
                            } else {
                            // !0, !1, 2, !3
                            }
                        } else {
                            if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            } else {
                                // !0, !1, !2, !3
                                if (getStackElementSize(getTopOfStackObject()) == 2) {
                                    if (analyzer.isTopOfStackTagged())
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    else {
                                        super.visitInsn(opcode);
                                        return;
                                    }
                                } else {
                                    if (analyzer.isTopOfStackTagged())
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    if (analyzer.stackTagStatus.get(analyzer.stack.size() - 2) instanceof TaggedValue)
                                        throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                                    super.visitInsn(opcode);
                                    return;
                                }
                            }
                        }
                    }
                    throw new UnsupportedOperationException(Printer.OPCODES[opcode] + " " + analyzer.stackTagStatus + " - " + nextDupCopiesTaint0 + " " + nextDupCopiesTaint1 + " " + nextDupCopiesTaint2 + " " + nextDupCopiesTaint3);
                }
            } else // DUP2, top of stack is double
            {
                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                // System.out.println(topOfStack + ""+secondOnStack);
                if (nextDupCopiesTaint0) {
                    if (nextDupCopiesTaint1) {
                        // TVV -> TVVTVV
                        Type topType = getTypeForStackType(topOfStack);
                        int top = lvs.getTmpLV();
                        super.visitInsn(TaintUtils.IS_TMP_STORE);
                        super.visitVarInsn(topType.getOpcode(ISTORE), top);
                        // T
                        super.visitInsn(DUP);
                        // TT
                        super.visitVarInsn(topType.getOpcode(ILOAD), top);
                        analyzer.setTopOfStackTagged();
                        // TTVV
                        super.visitInsn(DUP2_X1);
                        // TVVTVV
                        lvs.freeTmpLV(top);
                    } else {
                        // TVV -> TVV VV
                        super.visitInsn(DUP2);
                        analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 2, analyzer.stack.get(analyzer.stack.size() - 2));
                    }
                } else {
                    if (nextDupCopiesTaint1) {
                        // TVV -> VVTVV
                        super.visitInsn(DUP2_X1);
                        analyzer.stackTagStatus.set(analyzer.stackTagStatus.size() - 5, analyzer.stack.get(analyzer.stack.size() - 5));
                    } else {
                        // VV -> VVVV
                        if (// should not be possible
                        topOfStack instanceof TaggedValue)
                            throw new UnsupportedOperationException();
                        super.visitInsn(DUP2);
                    }
                }
            // System.out.println("POST " + analyzer.stackTagStatus);
            }
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP_X1:
            // new Exception().printStackTrace();
            if (nextDupCopiesTaint0) {
                if (!nextDupCopiesTaint1)
                    throw new UnsupportedOperationException();
                // System.out.println("DUP_X1 " + analyzer.stackTagStatus);
                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                if (topOfStack instanceof TaggedValue) {
                    // There is a 1 word element at the top of the stack, we want to dup
                    // it and it's taint to go one under so that it's
                    // T V X T V
                    Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                    if (underThisOne instanceof TaggedValue) {
                        // X X T V -> T V X X T V
                        super.visitInsn(DUP2_X2);
                    } else {
                        // X T V -> T V X TV
                        super.visitInsn(DUP2_X1);
                    }
                } else {
                    Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                    if (underThisOne instanceof TaggedValue) {
                        // X X V -> V X X V
                        super.visitInsn(DUP_X2);
                    } else {
                        // X V -> V X V
                        super.visitInsn(DUP_X1);
                    }
                }
            } else if (nextDupCopiesTaint1) {
                Object underThisOne = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                if (underThisOne instanceof TaggedValue) {
                    // T1 V1 T2 V2 -> V2 T1 V1 T2 V2
                    DUPN_XU(1, 3);
                    analyzer.stackTagStatus.set(analyzer.stack.size() - 5, ((TaggedValue) underThisOne).v);
                } else {
                    super.visitInsn(DUP_X2);
                    Object o = analyzer.stack.get(analyzer.stack.size() - 4);
                    if (o instanceof TaggedValue)
                        o = ((TaggedValue) o).v;
                    // need to make sure we clear the tag status on that dude!
                    analyzer.stackTagStatus.set(analyzer.stack.size() - 4, o);
                // System.out.println(analyzer.stack);
                // System.out.println(analyzer.stackTagStatus);
                }
            } else if (topCarriesTaint()) {
                // analyzer.stackTagStatus.set(analyzer.stack.size() - 4, o);
                throw new UnsupportedOperationException();
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                super.visitInsn(DUP_X2);
            } else
                super.visitInsn(DUP_X1);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            // System.out.println("PSOT " + analyzer.stack + "; " + analyzer.stackTagStatus);
            break;
        case Opcodes.DUP_X2:
            // System.out.println("DUP_X2" + analyzer.stackTagStatus + nextDupCopiesTaint0 + nextDupCopiesTaint1);
            if (nextDupCopiesTaint0) {
                if (!nextDupCopiesTaint1) {
                    // 0, !1
                    // aka copythe taint under then delete it from top
                    System.out.println(analyzer.stackTagStatus);
                    throw new UnsupportedOperationException();
                } else {
                    // 0, 1
                    if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 3)) == 2) {
                        // With long/double under
                        if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
                            // Top 2 are tracked
                            DUPN_XU(2, 3);
                        else
                            // 2nd is not tracked.
                            DUPN_XU(2, 2);
                    } else {
                        // With 1word under
                        if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue)
                                DUPN_XU(2, 4);
                            else
                                DUPN_XU(2, 3);
                        } else {
                            // 2nd is not tracked.
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
                                DUPN_XU(2, 3);
                            else
                                super.visitInsn(DUP2_X2);
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    Object under = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3);
                    if (under == Opcodes.TOP) {
                        // Two byte word
                        throw new UnsupportedOperationException();
                    } else {
                        if (under instanceof TaggedValue) {
                            Object twoUnder = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5);
                            if (twoUnder instanceof TaggedValue) {
                                LocalVariableNode[] lvs = storeToLocals(6);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(5, lvs);
                                loadLV(4, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            } else {
                                // System.out.println("DUP_X2" + analyzer.stackTagStatus);
                                LocalVariableNode[] lvs = storeToLocals(5);
                                loadLV(0, lvs);
                                analyzer.clearTopOfStackTagged();
                                loadLV(4, lvs);
                                loadLV(3, lvs);
                                loadLV(2, lvs);
                                loadLV(1, lvs);
                                loadLV(0, lvs);
                                freeLVs(lvs);
                            }
                        } else {
                            // System.out.println(analyzer.stack);
                            Object twoUnder = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                            if (twoUnder instanceof TaggedValue) {
                                // 
                                DUPN_XU(1, 4);
                                // System.out.println(analyzer.stackTagStatus);
                                int off = analyzer.stack.size() - 6;
                                analyzer.stackTagStatus.set(off, analyzer.stack.get(off));
                            // throw new UnsupportedOperationException();
                            } else {
                                // TABTC -> CATB
                                DUPN_XU(1, 3);
                                int off = analyzer.stack.size() - 5;
                                analyzer.stackTagStatus.set(off, analyzer.stack.get(off));
                            }
                        }
                    }
                } else {
                    // Dont want to copy any taint
                    if (topCarriesTaint()) {
                        // Top has a tag, but we don't want to keep it
                        if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 2)) == 2) {
                            // With long/double under
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
                                // Top 2 are tracked
                                DUPN_XU(1, 4);
                            else
                                // 2nd is not tracked.
                                DUPN_XU(1, 3);
                        } else {
                            // With 1word under
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue)
                                    DUPN_XU(1, 5);
                                else
                                    DUPN_XU(1, 4);
                            } else {
                                // 2nd is not tracked.
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                    DUPN_XU(1, 4);
                                } else
                                    DUPN_XU(1, 3);
                            }
                        }
                    } else {
                        // What's under us?
                        if (analyzer.stack.get(analyzer.stack.size() - 2) == Opcodes.TOP) {
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                LocalVariableNode[] d = storeToLocals(3);
                                loadLV(0, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            } else
                                super.visitInsn(DUP_X2);
                        } else {
                            // 1 word under us. is it tagged?
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                    throw new UnsupportedOperationException();
                                } else {
                                    DUPN_XU(1, 3);
                                }
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else
                                super.visitInsn(DUP_X2);
                        }
                    }
                }
            }
            // System.out.println("post DUP_X2" + analyzer.stackTagStatus);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2_X1:
            // ABC -> BCABC (0 1 2 3 4)
            if (nextDupCopiesTaint0) {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0,1,!2,!3
                            // ATBTC -> TBTCABC
                            // 2 word?
                            topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                            if (getStackElementSize(topOfStack) == 2) {
                                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                                if (!(topOfStack instanceof TaggedValue))
                                    throw new UnsupportedOperationException("Top must be tagged for this");
                                Object secondOnStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                                if (secondOnStack instanceof TaggedValue) {
                                    // TATBB -> TBBTATBB
                                    throw new UnsupportedOperationException();
                                } else {
                                    // ATBB -> TBBATBB
                                    DUPN_XU(2, 1);
                                }
                            // throw new UnsupportedOperationException();
                            // System.out.println(analyzer.stackTagStatus);
                            } else {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            if (getTopOfStackType().getSize() == 2) {
                                // 0 !1 !2 3
                                // System.out.println(analyzer.stack);
                                LocalVariableNode[] d = storeToLocals(3);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(1, d);
                                loadLV(0, d);
                                // loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            } else {
                                // !0, !1, !2, 3
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        } else {
                            // DUP2_X1
                            if (topCarriesTaint()) {
                                if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                } else {
                                    // System.out.println(analyzer.stackTagStatus);
                                    super.visitInsn(SWAP);
                                    super.visitInsn(POP);
                                    analyzer.clearTopOfStackTagged();
                                    super.visitInsn(opcode);
                                    // throw new UnsupportedOperationException();
                                    return;
                                }
                            }
                            System.out.println(analyzer.stackTagStatus);
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,1,!2,!3
                            topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1);
                            if (getStackElementSize(topOfStack) == 2) {
                                // A TVV -> VV A T VV
                                super.visitInsn(DUP2_X2);
                                int idx = analyzer.stack.size() - 6;
                                analyzer.stackTagStatus.set(idx, analyzer.stack.get(idx));
                            } else {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                // System.out.println(analyzer.stackTagStatus);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0 +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            if (getTopOfStackType().getSize() == 2) {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(3);
                                // loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                // loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            } else {
                                // System.out.println(analyzer.stackTagStatus);
                                LocalVariableNode[] d = storeToLocals(4);
                                loadLV(2, d);
                                loadLV(0, d);
                                analyzer.clearTopOfStackTagged();
                                loadLV(3, d);
                                loadLV(2, d);
                                loadLV(1, d);
                                loadLV(0, d);
                                freeLVs(d);
                            // System.out.println(nextDupCopiesTaint0
                            // +","+nextDupCopiesTaint1+","+nextDupCopiesTaint2+","+nextDupCopiesTaint3);
                            // System.out.println(analyzer.stackTagStatus);
                            // throw new UnsupportedOperationException();
                            }
                        } else {
                            // !0,!1,!2,!3
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1) instanceof TaggedValue)
                                throw new UnsupportedOperationException();
                            else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
                                throw new UnsupportedOperationException();
                            else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                super.visitInsn(DUP2_X2);
                                return;
                            }
                            super.visitInsn(opcode);
                        }
                    }
                }
            }
            // // Z A B OR Z Z' A B?
            // if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 1)) == 2) {
            // // Have two-word el + 1 word taint on top
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
            // // Dup the top three words to be under the 2 words
            // // beneath them
            // DUPN_XU(2, 2);
            // } else {
            // // Dup the top three words to be under the word beneath
            // // them
            // DUPN_XU(2, 1);
            // }
            // } else {
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
            // // Both this and the guy under are tracked
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5) instanceof TaggedValue) {
            // DUPN_XU(4, 2);
            // } else
            // DUPN_XU(4, 1);
            // } else {
            // // Top is tracked, guy under isn't
            // if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
            // DUPN_XU(3, 2);
            // } else
            // DUPN_XU(3, 1);
            // 
            // }
            // }
            // 
            // if(topCarriesTaint())
            // {
            // if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 1)) == 2) {
            // if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue)
            // {
            // //Top is 2 words, then tag, then tagged value. Don't want to copy the tag under htough
            // DUPN_XU(2, 3);
            // }
            // else
            // {
            // //Top is 2 words tagged, then regular value
            // super.visitInsn(DUP2_X2);
            // }
            // }
            // else
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else
            // super.visitInsn(DUP2_X1);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.DUP2_X2:
            if (nextDupCopiesTaint0) {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // 0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // 0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // System.out.println("DUP2_X2 "+ analyzer.stackTagStatus);
                            if (getStackElementSize(getTopOfStackObject()) == 2) {
                                // ?A?BTC -> TC?A?BTC
                                topOfStack = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2);
                                // System.out.println(topOfStack);
                                Object second = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4);
                                if (getStackElementSize(second) == 2) {
                                    // ?AATC -> TC?AAC
                                    throw new UnsupportedOperationException();
                                } else {
                                    if (second instanceof TaggedValue) {
                                        Object third = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 6);
                                        if (third instanceof TaggedValue) {
                                            LocalVariableNode[] d = storeToLocals(6);
                                            loadLV(1, d);
                                            loadLV(0, d);
                                            loadLV(5, d);
                                            loadLV(4, d);
                                            loadLV(3, d);
                                            loadLV(2, d);
                                            loadLV(0, d);
                                            analyzer.clearTopOfStackTagged();
                                            freeLVs(d);
                                        } else {
                                            // ATBTC -> TCATBTC
                                            DUPN_XU(2, 3);
                                        }
                                    // System.out.println(analyzer.stackTagStatus);
                                    // throw new UnsupportedOperationException();
                                    } else {
                                        Object third = analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 5);
                                        if (third instanceof TaggedValue) {
                                            // ATBTC -> TCATBTC
                                            DUPN_XU(2, 3);
                                        } else
                                            throw new UnsupportedOperationException();
                                    // System.out.println(analyzer.stackTagStatus);
                                    // throw new UnsupportedOperationException();
                                    }
                                }
                            } else
                                throw new UnsupportedOperationException();
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,!1,!2,!3
                            throw new UnsupportedOperationException();
                        }
                    }
                }
            } else {
                if (nextDupCopiesTaint1) {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, 1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, 1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,1,!2,!3
                            if (getStackElementSize(getTopOfStackObject()) == 2) {
                                if (analyzer.stackTagStatus.get(analyzer.stack.size() - 2) instanceof TaggedValue) {
                                    // top 2 words, tagged
                                    if (getStackElementSize(analyzer.stack.get(analyzer.stack.size() - 4)) == 2) {
                                        throw new UnsupportedOperationException();
                                    } else {
                                        // ABTCC -> CCABTCC
                                        Object second = analyzer.stackTagStatus.get(analyzer.stack.size() - 4);
                                        if (second instanceof TaggedValue) {
                                            // System.out.println("D2X2" + analyzer.stackTagStatus);
                                            LocalVariableNode[] d = storeToLocals(6);
                                            loadLV(0, d);
                                            analyzer.clearTopOfStackTagged();
                                            loadLV(5, d);
                                            loadLV(4, d);
                                            loadLV(3, d);
                                            loadLV(2, d);
                                            loadLV(1, d);
                                            loadLV(0, d);
                                            freeLVs(d);
                                        // System.out.println("D2X2" + analyzer.stackTagStatus);
                                        // throw new UnsupportedOperationException();
                                        } else {
                                            Object third = analyzer.stackTagStatus.get(analyzer.stack.size() - 5);
                                            if (third instanceof TaggedValue) {
                                                DUPN_XU(1, 4);
                                                analyzer.stackTagStatus.set(analyzer.stack.size() - 8, analyzer.stack.get(analyzer.stack.size() - 8));
                                            } else {
                                                throw new UnsupportedOperationException();
                                            }
                                        }
                                    }
                                } else {
                                    throw new UnsupportedOperationException();
                                }
                            } else {
                                throw new UnsupportedOperationException();
                            }
                        }
                    }
                } else {
                    if (nextDupCopiesTaint2) {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, 2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0, !1, 2, !3
                            throw new UnsupportedOperationException();
                        }
                    } else {
                        if (nextDupCopiesTaint3) {
                            // !0, !1, !2, 3
                            throw new UnsupportedOperationException();
                        } else {
                            // !0,!1,!2,!3
                            if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                                throw new UnsupportedOperationException();
                            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 4) instanceof TaggedValue) {
                                DUPN_XU(2, 2);
                            } else {
                                super.visitInsn(DUP2_X2);
                            }
                        }
                    }
                }
            }
            // if(nextDupCopiesTaint0 || nextDupCopiesTaint1)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(topCarriesTaint())
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else if(analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue)
            // {
            // throw new UnsupportedOperationException();
            // }
            // else
            // super.visitInsn(DUP2_X2);
            nextDupCopiesTaint0 = false;
            nextDupCopiesTaint1 = false;
            nextDupCopiesTaint2 = false;
            nextDupCopiesTaint3 = false;
            break;
        case Opcodes.SWAP:
            if (topCarriesTaint() || analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 1) instanceof TaggedValue) {
                if (nextLoadisTracked) {
                    if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 3) instanceof TaggedValue) {
                        super.visitInsn(DUP2_X2);
                        super.visitInsn(POP2);
                    } else {
                        super.visitInsn(DUP2_X1);
                        super.visitInsn(POP2);
                    }
                } else {
                    super.visitInsn(DUP2_X1);
                    super.visitInsn(POP2);
                }
            } else if (analyzer.stackTagStatus.get(analyzer.stackTagStatus.size() - 2) instanceof TaggedValue) {
                // Top has no tag, second does
                super.visitInsn(DUP_X2);
                super.visitInsn(POP);
            } else
                super.visitInsn(SWAP);
            nextLoadisTracked = false;
            break;
        case Opcodes.FADD:
        case Opcodes.FREM:
        case Opcodes.FSUB:
        case Opcodes.FMUL:
        case Opcodes.FDIV:
            {
                if (!topCarriesTaint()) {
                    super.visitInsn(opcode);
                    break;
                } else {
                    Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                    analyzer.setTopOfStackTagged();
                }
            }
            break;
        case Opcodes.IADD:
        case Opcodes.ISUB:
        case Opcodes.IMUL:
        case Opcodes.IDIV:
        case Opcodes.IREM:
        case Opcodes.ISHL:
        case Opcodes.ISHR:
        case Opcodes.IUSHR:
        case Opcodes.IOR:
        case Opcodes.IAND:
        case Opcodes.IXOR:
            // System.out.println(Printer.OPCODES[opcode] + " "+ analyzer.stackTagStatus);
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.DADD:
        case Opcodes.DSUB:
        case Opcodes.DMUL:
        case Opcodes.DDIV:
        case Opcodes.DREM:
            {
                if (!topCarriesTaint()) {
                    super.visitInsn(opcode);
                    break;
                } else {
                    Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                    analyzer.setTopOfStackTagged();
                }
            }
            break;
        case Opcodes.LSHL:
        case Opcodes.LUSHR:
        case Opcodes.LSHR:
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.LSUB:
        case Opcodes.LMUL:
        case Opcodes.LADD:
        case Opcodes.LDIV:
        case Opcodes.LREM:
        case Opcodes.LAND:
        case Opcodes.LOR:
        case Opcodes.LXOR:
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.INEG:
        case Opcodes.FNEG:
        case Opcodes.LNEG:
        case Opcodes.DNEG:
        case Opcodes.I2L:
        case Opcodes.I2F:
        case Opcodes.I2D:
        case Opcodes.L2I:
        case Opcodes.L2F:
        case Opcodes.L2D:
        case Opcodes.F2I:
        case Opcodes.F2L:
        case Opcodes.F2D:
        case Opcodes.D2I:
        case Opcodes.D2L:
        case Opcodes.D2F:
        case Opcodes.I2B:
        case Opcodes.I2C:
        case Opcodes.I2S:
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            nextLoadisTracked = false;
            break;
        case Opcodes.LCMP:
        case Opcodes.DCMPL:
        case Opcodes.DCMPG:
        case Opcodes.FCMPL:
        case Opcodes.FCMPG:
            // System.out.println(Printer.OPCODES[opcode] + analyzer.stack + analyzer.stackTagStatus);
            if (!topCarriesTaint()) {
                super.visitInsn(opcode);
                break;
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
            }
            break;
        case Opcodes.DRETURN:
        case Opcodes.LRETURN:
            int retIdx = lvs.getPreAllocedReturnTypeVar(newReturnType);
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(DUP_X2);
            super.visitInsn(POP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "val", originalMethodReturnType.getDescriptor());
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
            super.visitVarInsn(ALOAD, retIdx);
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(ARETURN);
            break;
        case Opcodes.IRETURN:
        case Opcodes.FRETURN:
            // super.visitMethodInsn(INVOKESTATIC, TaintUtils.getContainerReturnType(originalMethodReturnType).getInternalName(), "valueOf", "(I" + originalMethodReturnType.getDescriptor() + ")"
            // + TaintUtils.getContainerReturnType(originalMethodReturnType).getDescriptor());
            retIdx = lvs.getPreAllocedReturnTypeVar(newReturnType);
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "val", originalMethodReturnType.getDescriptor());
            super.visitVarInsn(ALOAD, retIdx);
            super.visitInsn(SWAP);
            super.visitFieldInsn(PUTFIELD, newReturnType.getInternalName(), "taint", Configuration.TAINT_TAG_DESC);
            super.visitVarInsn(ALOAD, retIdx);
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(ARETURN);
            break;
        case Opcodes.ARETURN:
            Type onStack = getTopOfStackType();
            if (originalMethodReturnType.getSort() == Type.ARRAY) {
                if (onStack.getSort() == Type.OBJECT) {
                    super.visitInsn(opcode);
                    return;
                } else if (originalMethodReturnType.getDimensions() > 1 && (onStack.getSort() != Type.ARRAY || onStack.getElementType().getSort() == Type.OBJECT)) {
                    super.visitInsn(opcode);
                    return;
                }
                switch(originalMethodReturnType.getElementType().getSort()) {
                    case Type.INT:
                    case Type.LONG:
                    case Type.BOOLEAN:
                    case Type.BYTE:
                    case Type.CHAR:
                    case Type.DOUBLE:
                    case Type.FLOAT:
                    case Type.SHORT:
                        registerTaintedArray();
                        Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                        super.visitInsn(ARETURN);
                        break;
                    default:
                        Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                        super.visitInsn(opcode);
                }
            } else if (onStack.getSort() == Type.ARRAY && onStack.getDimensions() == 1 && onStack.getElementType().getSort() != Type.OBJECT) {
                registerTaintedArray();
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                super.visitInsn(opcode);
            } else {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                super.visitInsn(opcode);
            }
            break;
        case Opcodes.RETURN:
            Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
            super.visitInsn(opcode);
            break;
        case Opcodes.ARRAYLENGTH:
            if (nextLoadisTracked) {
                Configuration.taintTagFactory.stackOp(opcode, mv, lvs, this);
                analyzer.setTopOfStackTagged();
                nextLoadisTracked = false;
            } else
                super.visitInsn(opcode);
            break;
        case Opcodes.ATHROW:
            if (TaintUtils.DEBUG_FRAMES)
                System.out.println("ATHROW " + analyzer.stack);
            super.visitInsn(opcode);
            break;
        case Opcodes.MONITORENTER:
        case Opcodes.MONITOREXIT:
            // You can have a monitor on an array type. If it's a primitive array type, pop the taint off!
            // else if(getTopOfStackObject().equals("java/lang/Object"))
            // {
            // //never allow monitor to occur on a multid type
            // super.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(MultiDTaintedArray.class), "unbox1D", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
            // }
            super.visitInsn(opcode);
            break;
        case TaintUtils.FOLLOWED_BY_FRAME:
            super.visitInsn(opcode);
            break;
        default:
            super.visitInsn(opcode);
            throw new IllegalArgumentException();
    }
}
Also used : TaggedValue(edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode) ControlTaintTagStack(edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack) Type(org.objectweb.asm.Type)

Aggregations

ControlTaintTagStack (edu.columbia.cs.psl.phosphor.struct.ControlTaintTagStack)6 Type (org.objectweb.asm.Type)3 TaggedValue (edu.columbia.cs.psl.phosphor.instrumenter.analyzer.TaggedValue)2 OffsetPreservingLabel (edu.columbia.cs.psl.phosphor.instrumenter.asm.OffsetPreservingLabel)2 TaintedBooleanWithObjTag (edu.columbia.cs.psl.phosphor.struct.TaintedBooleanWithObjTag)2 Collection (java.util.Collection)2 Label (org.objectweb.asm.Label)2 LazyArrayIntTags (edu.columbia.cs.psl.phosphor.struct.LazyArrayIntTags)1 LazyArrayObjTags (edu.columbia.cs.psl.phosphor.struct.LazyArrayObjTags)1 TaintedWithIntTag (edu.columbia.cs.psl.phosphor.struct.TaintedWithIntTag)1 TaintedWithObjTag (edu.columbia.cs.psl.phosphor.struct.TaintedWithObjTag)1 LocalVariableNode (org.objectweb.asm.tree.LocalVariableNode)1