Search in sources :

Example 26 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class ThisInliner method internalTransform.

public void internalTransform(Body b, String phaseName, Map options) {
    // assure body is a constructor
    if (!b.getMethod().getName().equals("<init>"))
        return;
    // if the first invoke is a this() and not a super() inline the this()
    InvokeStmt invokeStmt = getFirstSpecialInvoke(b);
    if (invokeStmt == null)
        return;
    SpecialInvokeExpr specInvokeExpr = (SpecialInvokeExpr) invokeStmt.getInvokeExpr();
    if (specInvokeExpr.getMethod().getDeclaringClass().equals(b.getMethod().getDeclaringClass())) {
        // put locals from inlinee into container
        if (!specInvokeExpr.getMethod().hasActiveBody()) {
            specInvokeExpr.getMethod().retrieveActiveBody();
        }
        HashMap<Local, Local> oldLocalsToNew = new HashMap<Local, Local>();
        for (Local l : specInvokeExpr.getMethod().getActiveBody().getLocals()) {
            Local newLocal = (Local) l.clone();
            b.getLocals().add(newLocal);
            oldLocalsToNew.put(l, newLocal);
        }
        // find identity stmt of original method
        IdentityStmt origIdStmt = findIdentityStmt(b);
        HashMap<Stmt, Stmt> oldStmtsToNew = new HashMap<Stmt, Stmt>();
        // System.out.println("locals: "+b.getLocals());
        Chain<Unit> containerUnits = b.getUnits();
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            // handle identity stmts
            if (inlineeStmt instanceof IdentityStmt) {
                IdentityStmt idStmt = (IdentityStmt) inlineeStmt;
                if (idStmt.getRightOp() instanceof ThisRef) {
                    Stmt newThis = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), origIdStmt.getLeftOp());
                    containerUnits.insertBefore(newThis, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newThis);
                } else if (idStmt.getRightOp() instanceof CaughtExceptionRef) {
                    Stmt newInlinee = (Stmt) inlineeStmt.clone();
                    for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                        if (next.getValue() instanceof Local) {
                            next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                        }
                    }
                    containerUnits.insertBefore(newInlinee, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newInlinee);
                } else if (idStmt.getRightOp() instanceof ParameterRef) {
                    Stmt newParam = Jimple.v().newAssignStmt((Local) oldLocalsToNew.get(idStmt.getLeftOp()), specInvokeExpr.getArg(((ParameterRef) idStmt.getRightOp()).getIndex()));
                    containerUnits.insertBefore(newParam, invokeStmt);
                    oldStmtsToNew.put(inlineeStmt, newParam);
                }
            } else // from a constructor)
            if (inlineeStmt instanceof ReturnVoidStmt) {
                Stmt newRet = Jimple.v().newGotoStmt((Stmt) containerUnits.getSuccOf(invokeStmt));
                containerUnits.insertBefore(newRet, invokeStmt);
                System.out.println("adding to stmt map: " + inlineeStmt + " and " + newRet);
                oldStmtsToNew.put(inlineeStmt, newRet);
            } else {
                Stmt newInlinee = (Stmt) inlineeStmt.clone();
                for (ValueBox next : newInlinee.getUseAndDefBoxes()) {
                    if (next.getValue() instanceof Local) {
                        next.setValue((Local) oldLocalsToNew.get(next.getValue()));
                    }
                }
                containerUnits.insertBefore(newInlinee, invokeStmt);
                oldStmtsToNew.put(inlineeStmt, newInlinee);
            }
        }
        // handleTraps
        for (Trap t : specInvokeExpr.getMethod().getActiveBody().getTraps()) {
            System.out.println("begin: " + t.getBeginUnit());
            Stmt newBegin = oldStmtsToNew.get(t.getBeginUnit());
            System.out.println("end: " + t.getEndUnit());
            Stmt newEnd = oldStmtsToNew.get(t.getEndUnit());
            System.out.println("handler: " + t.getHandlerUnit());
            Stmt newHandler = oldStmtsToNew.get(t.getHandlerUnit());
            if (newBegin == null || newEnd == null || newHandler == null)
                throw new RuntimeException("couldn't map trap!");
            b.getTraps().add(Jimple.v().newTrap(t.getException(), newBegin, newEnd, newHandler));
        }
        // patch gotos
        for (Unit u : specInvokeExpr.getMethod().getActiveBody().getUnits()) {
            Stmt inlineeStmt = (Stmt) u;
            if (inlineeStmt instanceof GotoStmt) {
                System.out.println("inlinee goto target: " + ((GotoStmt) inlineeStmt).getTarget());
                ((GotoStmt) oldStmtsToNew.get(inlineeStmt)).setTarget(oldStmtsToNew.get(((GotoStmt) inlineeStmt).getTarget()));
            }
        }
        // remove original invoke
        containerUnits.remove(invokeStmt);
        // resolve name collisions
        LocalNameStandardizer.v().transform(b, "ji.lns");
    }
// System.out.println("locals: "+b.getLocals());
// System.out.println("units: "+b.getUnits());
}
Also used : InvokeStmt(soot.jimple.InvokeStmt) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) Local(soot.Local) Trap(soot.Trap) Unit(soot.Unit) GotoStmt(soot.jimple.GotoStmt) Stmt(soot.jimple.Stmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) InvokeStmt(soot.jimple.InvokeStmt) IdentityStmt(soot.jimple.IdentityStmt) ParameterRef(soot.jimple.ParameterRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) GotoStmt(soot.jimple.GotoStmt) IdentityStmt(soot.jimple.IdentityStmt)

Example 27 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class ClassRenamer method internalTransform.

@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
    if (isVerbose()) {
        logger.debug("Transforming Class Names...");
    }
    BodyBuilder.retrieveAllBodies();
    BodyBuilder.retrieveAllNames();
    final SootClass mainClass = getMainClassSafely();
    // iterate through application classes, rename classes with junk
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        final String className = sootClass.getName();
        if (sootClass.equals(mainClass) || oldToNewClassNames.containsValue(className) || soot.jbco.Main.getWeight(phaseName, className) == 0) {
            continue;
        }
        String newClassName = oldToNewClassNames.get(className);
        if (newClassName == null) {
            newClassName = getNewName(getPackageName(className), className);
        }
        sootClass.setName(newClassName);
        RefType crt = RefType.v(newClassName);
        crt.setSootClass(sootClass);
        sootClass.setRefType(crt);
        sootClass.setResolvingLevel(SootClass.BODIES);
        // will this fix dangling classes?
        // scene.addRefType(sootClass.getType());
        newNameToClass.put(newClassName, sootClass);
        if (isVerbose()) {
            logger.info("\tRenaming " + className + " to " + newClassName);
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
    if (isVerbose()) {
        logger.info("\r\tUpdating bytecode class references");
    }
    for (SootClass sootClass : Scene.v().getApplicationClasses()) {
        for (SootMethod sootMethod : sootClass.getMethods()) {
            if (!sootMethod.isConcrete()) {
                continue;
            }
            if (isVerbose()) {
                logger.info("\t\t" + sootMethod.getSignature());
            }
            Body aBody;
            try {
                aBody = sootMethod.getActiveBody();
            } catch (Exception e) {
                continue;
            }
            for (Unit u : aBody.getUnits()) {
                for (ValueBox vb : u.getUseAndDefBoxes()) {
                    Value v = vb.getValue();
                    if (v instanceof ClassConstant) {
                        ClassConstant constant = (ClassConstant) v;
                        RefType type = (RefType) constant.toSootType();
                        RefType updatedType = type.getSootClass().getType();
                        vb.setValue(ClassConstant.fromType(updatedType));
                    } else if (v instanceof Expr) {
                        if (v instanceof CastExpr) {
                            CastExpr castExpr = (CastExpr) v;
                            updateType(castExpr.getCastType());
                        } else if (v instanceof InstanceOfExpr) {
                            InstanceOfExpr instanceOfExpr = (InstanceOfExpr) v;
                            updateType(instanceOfExpr.getCheckType());
                        }
                    } else if (v instanceof Ref) {
                        updateType(v.getType());
                    }
                }
            }
        }
    }
    Scene.v().releaseActiveHierarchy();
    Scene.v().setFastHierarchy(new FastHierarchy());
}
Also used : SootClass(soot.SootClass) Unit(soot.Unit) InstanceOfExpr(soot.jimple.InstanceOfExpr) RefType(soot.RefType) FastHierarchy(soot.FastHierarchy) Ref(soot.jimple.Ref) Expr(soot.jimple.Expr) InstanceOfExpr(soot.jimple.InstanceOfExpr) CastExpr(soot.jimple.CastExpr) ValueBox(soot.ValueBox) Value(soot.Value) CastExpr(soot.jimple.CastExpr) SootMethod(soot.SootMethod) Body(soot.Body) ClassConstant(soot.jimple.ClassConstant)

Example 28 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class AbstractInvokeExpr method getUseBoxes.

@Override
public List<ValueBox> getUseBoxes() {
    if (argBoxes == null)
        return Collections.emptyList();
    List<ValueBox> list = new ArrayList<ValueBox>();
    Collections.addAll(list, argBoxes);
    for (ValueBox element : argBoxes) {
        list.addAll(element.getValue().getUseBoxes());
    }
    return list;
}
Also used : ValueBox(soot.ValueBox) ArrayList(java.util.ArrayList)

Example 29 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class LocalMustAliasAnalysis method trackableFields.

/**
 * Computes the set of {@link EquivalentValue}s of all field references that are used
 * in this method but not set by the method or any method transitively called by this method.
 */
private Set<Value> trackableFields() {
    Set<Value> usedFieldRefs = new HashSet<Value>();
    // add all field references that are in use boxes
    for (Unit unit : this.graph) {
        Stmt s = (Stmt) unit;
        List<ValueBox> useBoxes = s.getUseBoxes();
        for (ValueBox useBox : useBoxes) {
            Value val = useBox.getValue();
            if (val instanceof FieldRef) {
                FieldRef fieldRef = (FieldRef) val;
                if (fieldRef.getType() instanceof RefLikeType)
                    usedFieldRefs.add(new EquivalentValue(fieldRef));
            }
        }
    }
    // prune all fields that are written to
    if (!usedFieldRefs.isEmpty()) {
        if (!Scene.v().hasCallGraph()) {
            throw new IllegalStateException("No call graph found!");
        }
        CallGraph cg = Scene.v().getCallGraph();
        ReachableMethods reachableMethods = new ReachableMethods(cg, Collections.<MethodOrMethodContext>singletonList(container));
        reachableMethods.update();
        for (Iterator<MethodOrMethodContext> iterator = reachableMethods.listener(); iterator.hasNext(); ) {
            SootMethod m = (SootMethod) iterator.next();
            if (m.hasActiveBody() && // exclude static initializer of same class (assume that it has already been executed)
            !(m.getName().equals(SootMethod.staticInitializerName) && m.getDeclaringClass().equals(container.getDeclaringClass()))) {
                for (Unit u : m.getActiveBody().getUnits()) {
                    List<ValueBox> defBoxes = u.getDefBoxes();
                    for (ValueBox defBox : defBoxes) {
                        Value value = defBox.getValue();
                        if (value instanceof FieldRef) {
                            usedFieldRefs.remove(new EquivalentValue(value));
                        }
                    }
                }
            }
        }
    }
    return usedFieldRefs;
}
Also used : EquivalentValue(soot.EquivalentValue) FieldRef(soot.jimple.FieldRef) Unit(soot.Unit) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ReachableMethods(soot.jimple.toolkits.callgraph.ReachableMethods) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ValueBox(soot.ValueBox) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) MethodOrMethodContext(soot.MethodOrMethodContext) HashSet(java.util.HashSet)

Example 30 with ValueBox

use of soot.ValueBox in project soot by Sable.

the class StaticMethodBinder method internalTransform.

protected void internalTransform(String phaseName, Map opts) {
    Filter instanceInvokesFilter = new Filter(new InstanceInvokeEdgesPred());
    SMBOptions options = new SMBOptions(opts);
    String modifierOptions = PhaseOptions.getString(opts, "allowed-modifier-changes");
    HashMap instanceToStaticMap = new HashMap();
    CallGraph cg = Scene.v().getCallGraph();
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    Iterator classesIt = Scene.v().getApplicationClasses().iterator();
    while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        LinkedList methodsList = new LinkedList();
        for (Iterator it = c.methodIterator(); it.hasNext(); ) {
            methodsList.add(it.next());
        }
        while (!methodsList.isEmpty()) {
            SootMethod container = (SootMethod) methodsList.removeFirst();
            if (!container.isConcrete())
                continue;
            if (!instanceInvokesFilter.wrap(cg.edgesOutOf(container)).hasNext())
                continue;
            JimpleBody b = (JimpleBody) container.getActiveBody();
            List<Unit> unitList = new ArrayList<Unit>();
            unitList.addAll(b.getUnits());
            Iterator<Unit> unitIt = unitList.iterator();
            while (unitIt.hasNext()) {
                Stmt s = (Stmt) unitIt.next();
                if (!s.containsInvokeExpr())
                    continue;
                InvokeExpr ie = s.getInvokeExpr();
                if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr)
                    continue;
                Iterator targets = new Targets(instanceInvokesFilter.wrap(cg.edgesOutOf(s)));
                if (!targets.hasNext())
                    continue;
                SootMethod target = (SootMethod) targets.next();
                if (targets.hasNext())
                    continue;
                if (!AccessManager.ensureAccess(container, target, modifierOptions))
                    continue;
                if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete())
                    continue;
                // Don't modify java.lang.Object
                if (target.getDeclaringClass() == Scene.v().getSootClass("java.lang.Object"))
                    continue;
                if (!instanceToStaticMap.containsKey(target)) {
                    List newParameterTypes = new ArrayList();
                    newParameterTypes.add(RefType.v(target.getDeclaringClass().getName()));
                    newParameterTypes.addAll(target.getParameterTypes());
                    // Check for signature conflicts.
                    String newName = target.getName() + "_static";
                    while (target.getDeclaringClass().declaresMethod(newName, newParameterTypes, target.getReturnType())) newName = newName + "_static";
                    SootMethod ct = Scene.v().makeSootMethod(newName, newParameterTypes, target.getReturnType(), target.getModifiers() | Modifier.STATIC, target.getExceptions());
                    target.getDeclaringClass().addMethod(ct);
                    methodsList.addLast(ct);
                    ct.setActiveBody((Body) target.getActiveBody().clone());
                    // Make the invoke graph take into account the
                    // newly-cloned body.
                    {
                        Iterator oldUnits = target.getActiveBody().getUnits().iterator();
                        Iterator newUnits = ct.getActiveBody().getUnits().iterator();
                        while (newUnits.hasNext()) {
                            Stmt oldStmt, newStmt;
                            oldStmt = (Stmt) oldUnits.next();
                            newStmt = (Stmt) newUnits.next();
                            Iterator edges = cg.edgesOutOf(oldStmt);
                            while (edges.hasNext()) {
                                Edge e = (Edge) edges.next();
                                cg.addEdge(new Edge(ct, newStmt, e.tgt(), e.kind()));
                                cg.removeEdge(e);
                            }
                        }
                    }
                    // Shift the parameter list to apply to the new this
                    // parameter.
                    // If the method uses this, then we replace
                    // the r0 := @this with r0 := @parameter0 & shift.
                    // Otherwise, just zap the r0 := @this.
                    {
                        Body newBody = ct.getActiveBody();
                        Chain units = newBody.getUnits();
                        Iterator unitsIt = newBody.getUnits().snapshotIterator();
                        while (unitsIt.hasNext()) {
                            Stmt st = (Stmt) unitsIt.next();
                            if (st instanceof IdentityStmt) {
                                IdentityStmt is = (IdentityStmt) st;
                                if (is.getRightOp() instanceof ThisRef) {
                                    units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), Jimple.v().newParameterRef(is.getRightOp().getType(), 0)));
                                } else {
                                    if (is.getRightOp() instanceof ParameterRef) {
                                        ParameterRef ro = (ParameterRef) is.getRightOp();
                                        ro.setIndex(ro.getIndex() + 1);
                                    }
                                }
                            }
                        }
                    }
                    instanceToStaticMap.put(target, ct);
                }
                SootMethod clonedTarget = (SootMethod) instanceToStaticMap.get(target);
                Value thisToAdd = ((InstanceInvokeExpr) ie).getBase();
                // Insert casts to please the verifier.
                if (options.insert_redundant_casts()) {
                    // The verifier will complain if targetUsesThis, and:
                    // the argument passed to the method is not the same
                    // type.
                    // For instance, Bottle.price_static takes a cost.
                    // Cost is an interface implemented by Bottle.
                    SootClass localType, parameterType;
                    localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
                    parameterType = target.getDeclaringClass();
                    if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                        Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                        b.getLocals().add(castee);
                        b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), s);
                        thisToAdd = castee;
                    }
                }
                // Now rebind the method call & fix the invoke graph.
                {
                    List newArgs = new ArrayList();
                    newArgs.add(thisToAdd);
                    newArgs.addAll(ie.getArgs());
                    StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr(clonedTarget.makeRef(), newArgs);
                    ValueBox ieBox = s.getInvokeExprBox();
                    ieBox.setValue(sie);
                    cg.addEdge(new Edge(container, s, clonedTarget));
                }
                // (If enabled), add a null pointer check.
                if (options.insert_null_checks()) {
                    boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), s, b);
                    /* Ah ha. Caught again! */
                    if (caught) {
                        /*
							 * In this case, we don't use throwPoint; instead,
							 * put the code right there.
							 */
                        Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), s);
                        b.getUnits().insertBefore(insertee, s);
                        // This sucks (but less than before).
                        ((IfStmt) insertee).setTarget(s);
                        ThrowManager.addThrowAfter(b, insertee);
                    } else {
                        Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(b);
                        b.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), s);
                    }
                }
                // Add synchronizing stuff.
                {
                    if (target.isSynchronized()) {
                        clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED);
                        SynchronizerManager.v().synchronizeStmtOn(s, b, (Local) ((InstanceInvokeExpr) ie).getBase());
                    }
                }
                // Resolve name collisions.
                LocalNameStandardizer.v().transform(b, phaseName + ".lns");
            }
        }
    }
}
Also used : Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) Stmt(soot.jimple.Stmt) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Hierarchy(soot.Hierarchy) InstanceInvokeEdgesPred(soot.jimple.toolkits.callgraph.InstanceInvokeEdgesPred) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) SMBOptions(soot.options.SMBOptions) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Targets(soot.jimple.toolkits.callgraph.Targets) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) ParameterRef(soot.jimple.ParameterRef) IfStmt(soot.jimple.IfStmt) Filter(soot.jimple.toolkits.callgraph.Filter) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge)

Aggregations

ValueBox (soot.ValueBox)58 Value (soot.Value)43 Local (soot.Local)36 Unit (soot.Unit)33 ArrayList (java.util.ArrayList)26 Type (soot.Type)20 Stmt (soot.jimple.Stmt)20 DefinitionStmt (soot.jimple.DefinitionStmt)17 InvokeExpr (soot.jimple.InvokeExpr)15 SootMethod (soot.SootMethod)13 RefType (soot.RefType)12 AssignStmt (soot.jimple.AssignStmt)11 IntConstant (soot.jimple.IntConstant)11 HashSet (java.util.HashSet)10 IntType (soot.IntType)10 SootClass (soot.SootClass)10 FieldRef (soot.jimple.FieldRef)10 HashMap (java.util.HashMap)9 LongType (soot.LongType)9 VoidType (soot.VoidType)9