Search in sources :

Example 6 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class Walker method outAGotoStatement.

public void outAGotoStatement(AGotoStatement node) {
    String targetLabel = (String) mProductions.removeLast();
    UnitBox box = Jimple.v().newStmtBox(null);
    Unit branch = Jimple.v().newGotoStmt(box);
    addBoxToPatch(targetLabel, box);
    mProductions.addLast(branch);
}
Also used : UnitBox(soot.UnitBox) Unit(soot.Unit)

Example 7 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class DavaBody method copy_Body.

/*
	 *  Copy and patch a GrimpBody so that it can be used to output Java.
	 */
private void copy_Body(Body body) {
    if (!(body instanceof GrimpBody))
        throw new RuntimeException("You can only create a DavaBody from a GrimpBody!");
    GrimpBody grimpBody = (GrimpBody) body;
    /*
		 *  Import body contents from Grimp.
		 */
    {
        HashMap<Switchable, Switchable> bindings = new HashMap<Switchable, Switchable>();
        HashMap<Unit, Unit> reverse_binding = new HashMap<Unit, Unit>();
        // Clone units in body's statement list
        for (Unit original : grimpBody.getUnits()) {
            Unit copy = (Unit) original.clone();
            // Add cloned unit to our unitChain.
            getUnits().addLast(copy);
            // Build old <-> new map to be able to patch up references to other units
            // within the cloned units. (these are still refering to the original
            // unit objects).
            bindings.put(original, copy);
            reverse_binding.put(copy, original);
        }
        // patch up the switch statments
        for (Unit u : getUnits()) {
            Stmt s = (Stmt) u;
            if (s instanceof TableSwitchStmt) {
                TableSwitchStmt ts = (TableSwitchStmt) s;
                TableSwitchStmt original_switch = (TableSwitchStmt) reverse_binding.get(u);
                ts.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
                LinkedList<Unit> new_target_list = new LinkedList<Unit>();
                int target_count = ts.getHighIndex() - ts.getLowIndex() + 1;
                for (int i = 0; i < target_count; i++) new_target_list.add((Unit) bindings.get(original_switch.getTarget(i)));
                ts.setTargets(new_target_list);
            }
            if (s instanceof LookupSwitchStmt) {
                LookupSwitchStmt ls = (LookupSwitchStmt) s;
                LookupSwitchStmt original_switch = (LookupSwitchStmt) reverse_binding.get(u);
                ls.setDefaultTarget((Unit) bindings.get(original_switch.getDefaultTarget()));
                Unit[] new_target_list = new Unit[original_switch.getTargetCount()];
                for (int i = 0; i < original_switch.getTargetCount(); i++) new_target_list[i] = (Unit) (bindings.get(original_switch.getTarget(i)));
                ls.setTargets(new_target_list);
                ls.setLookupValues(original_switch.getLookupValues());
            }
        }
        // Clone locals.
        for (Local original : grimpBody.getLocals()) {
            Local copy = Dava.v().newLocal(original.getName(), original.getType());
            getLocals().add(copy);
            // Build old <-> new mapping.
            bindings.put(original, copy);
        }
        // Patch up references within units using our (old <-> new) map.
        for (UnitBox box : getAllUnitBoxes()) {
            Unit newObject, oldObject = box.getUnit();
            // it's clone.
            if ((newObject = (Unit) bindings.get(oldObject)) != null)
                box.setUnit(newObject);
        }
        // backpatch all local variables.
        for (ValueBox vb : getUseAndDefBoxes()) {
            if (vb.getValue() instanceof Local)
                vb.setValue((Value) bindings.get(vb.getValue()));
        }
        // clone the traps
        for (Trap originalTrap : grimpBody.getTraps()) {
            Trap cloneTrap = (Trap) originalTrap.clone();
            Unit handlerUnit = (Unit) bindings.get(originalTrap.getHandlerUnit());
            cloneTrap.setHandlerUnit(handlerUnit);
            cloneTrap.setBeginUnit((Unit) bindings.get(originalTrap.getBeginUnit()));
            cloneTrap.setEndUnit((Unit) bindings.get(originalTrap.getEndUnit()));
            getTraps().add(cloneTrap);
        }
    }
    /*
		 *  Add one level of indirection to "if", "switch", and exceptional control flow.
		 *  This allows for easy handling of breaks, continues and exceptional loops.
		 */
    {
        PatchingChain<Unit> units = getUnits();
        Iterator<Unit> it = units.snapshotIterator();
        while (it.hasNext()) {
            Unit u = it.next();
            Stmt s = (Stmt) u;
            if (s instanceof IfStmt) {
                IfStmt ifs = (IfStmt) s;
                JGotoStmt jgs = new JGotoStmt((Unit) units.getSuccOf(u));
                units.insertAfter(jgs, u);
                JGotoStmt jumper = new JGotoStmt((Unit) ifs.getTarget());
                units.insertAfter(jumper, jgs);
                ifs.setTarget((Unit) jumper);
            } else if (s instanceof TableSwitchStmt) {
                TableSwitchStmt tss = (TableSwitchStmt) s;
                int targetCount = tss.getHighIndex() - tss.getLowIndex() + 1;
                for (int i = 0; i < targetCount; i++) {
                    JGotoStmt jgs = new JGotoStmt((Unit) tss.getTarget(i));
                    units.insertAfter(jgs, tss);
                    tss.setTarget(i, (Unit) jgs);
                }
                JGotoStmt jgs = new JGotoStmt((Unit) tss.getDefaultTarget());
                units.insertAfter(jgs, tss);
                tss.setDefaultTarget((Unit) jgs);
            } else if (s instanceof LookupSwitchStmt) {
                LookupSwitchStmt lss = (LookupSwitchStmt) s;
                for (int i = 0; i < lss.getTargetCount(); i++) {
                    JGotoStmt jgs = new JGotoStmt((Unit) lss.getTarget(i));
                    units.insertAfter(jgs, lss);
                    lss.setTarget(i, (Unit) jgs);
                }
                JGotoStmt jgs = new JGotoStmt((Unit) lss.getDefaultTarget());
                units.insertAfter(jgs, lss);
                lss.setDefaultTarget((Unit) jgs);
            }
        }
        for (Trap t : getTraps()) {
            JGotoStmt jgs = new JGotoStmt((Unit) t.getHandlerUnit());
            units.addLast(jgs);
            t.setHandlerUnit((Unit) jgs);
        }
    }
    /*
		 *  Fix up the grimp representations of statements so they can be compiled as java.
		 */
    {
        for (Local l : getLocals()) {
            Type t = l.getType();
            if (t instanceof RefType) {
                RefType rt = (RefType) t;
                String className = rt.getSootClass().toString();
                String packageName = rt.getSootClass().getJavaPackageName();
                String classPackageName = packageName;
                if (className.lastIndexOf('.') > 0) {
                    // 0 doesnt make sense
                    classPackageName = className.substring(0, className.lastIndexOf('.'));
                }
                if (!packageName.equals(classPackageName))
                    throw new DecompilationException("Unable to retrieve package name for identifier. Please report to developer.");
                addToImportList(className);
            // addPackage(rt.getSootClass().getJavaPackageName());
            }
        }
        for (Unit u : getUnits()) {
            Stmt s = (Stmt) u;
            if (s instanceof IfStmt)
                javafy(((IfStmt) s).getConditionBox());
            else if (s instanceof ThrowStmt)
                javafy(((ThrowStmt) s).getOpBox());
            else if (s instanceof TableSwitchStmt)
                javafy(((TableSwitchStmt) s).getKeyBox());
            else if (s instanceof LookupSwitchStmt)
                javafy(((LookupSwitchStmt) s).getKeyBox());
            else if (s instanceof MonitorStmt)
                javafy(((MonitorStmt) s).getOpBox());
            else if (s instanceof DefinitionStmt) {
                DefinitionStmt ds = (DefinitionStmt) s;
                javafy(ds.getRightOpBox());
                javafy(ds.getLeftOpBox());
                if (ds.getRightOp() instanceof IntConstant)
                    ds.getRightOpBox().setValue(DIntConstant.v(((IntConstant) ds.getRightOp()).value, ds.getLeftOp().getType()));
            } else if (s instanceof ReturnStmt) {
                ReturnStmt rs = (ReturnStmt) s;
                if (rs.getOp() instanceof IntConstant)
                    rs.getOpBox().setValue(DIntConstant.v(((IntConstant) rs.getOp()).value, body.getMethod().getReturnType()));
                else
                    javafy(rs.getOpBox());
            } else if (s instanceof InvokeStmt)
                javafy(((InvokeStmt) s).getInvokeExprBox());
        }
    }
    /*
		 *  Convert references to "this" and parameters.
		 */
    {
        for (Unit u : getUnits()) {
            Stmt s = (Stmt) u;
            if (s instanceof IdentityStmt) {
                IdentityStmt ids = (IdentityStmt) s;
                Value ids_rightOp = ids.getRightOp();
                Value ids_leftOp = ids.getLeftOp();
                if ((ids_leftOp instanceof Local) && (ids_rightOp instanceof ThisRef)) {
                    Local thisLocal = (Local) ids_leftOp;
                    thisLocals.add(thisLocal);
                    thisLocal.setName("this");
                }
            }
            if (s instanceof DefinitionStmt) {
                DefinitionStmt ds = (DefinitionStmt) s;
                Value rightOp = ds.getRightOp();
                if (rightOp instanceof ParameterRef)
                    pMap.put(((ParameterRef) rightOp).getIndex(), ds.getLeftOp());
                if (rightOp instanceof CaughtExceptionRef)
                    caughtrefs.add((CaughtExceptionRef) rightOp);
            }
        }
    }
    /*
		 *  Fix up the calls to other constructors.  Note, this is seriously underbuilt.
		 */
    {
        for (Unit u : getUnits()) {
            Stmt s = (Stmt) u;
            if (s instanceof InvokeStmt) {
                InvokeStmt ivs = (InvokeStmt) s;
                Value ie = ivs.getInvokeExpr();
                if (ie instanceof InstanceInvokeExpr) {
                    InstanceInvokeExpr iie = (InstanceInvokeExpr) ie;
                    Value base = iie.getBase();
                    if ((base instanceof Local) && (((Local) base).getName().equals("this"))) {
                        SootMethodRef m = iie.getMethodRef();
                        String name = m.name();
                        if ((name.equals(SootMethod.constructorName)) || (name.equals(SootMethod.staticInitializerName))) {
                            if (constructorUnit != null)
                                throw new RuntimeException("More than one candidate for constructor found.");
                            constructorExpr = iie;
                            constructorUnit = (Unit) s;
                        }
                    }
                }
            }
        }
    }
}
Also used : InvokeStmt(soot.jimple.InvokeStmt) CaughtExceptionRef(soot.jimple.CaughtExceptionRef) HashMap(java.util.HashMap) Switchable(soot.util.Switchable) Unit(soot.Unit) AugmentedStmt(soot.dava.internal.asg.AugmentedStmt) JGotoStmt(soot.jimple.internal.JGotoStmt) IfStmt(soot.jimple.IfStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) InvokeStmt(soot.jimple.InvokeStmt) ThrowStmt(soot.jimple.ThrowStmt) IdentityStmt(soot.jimple.IdentityStmt) TableSwitchStmt(soot.jimple.TableSwitchStmt) MonitorStmt(soot.jimple.MonitorStmt) ReturnStmt(soot.jimple.ReturnStmt) RefType(soot.RefType) TableSwitchStmt(soot.jimple.TableSwitchStmt) Iterator(java.util.Iterator) IntConstant(soot.jimple.IntConstant) DIntConstant(soot.dava.internal.javaRep.DIntConstant) GrimpBody(soot.grimp.GrimpBody) IdentityStmt(soot.jimple.IdentityStmt) UnitBox(soot.UnitBox) PatchingChain(soot.PatchingChain) SootMethodRef(soot.SootMethodRef) JimpleLocal(soot.jimple.internal.JimpleLocal) Local(soot.Local) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) Trap(soot.Trap) MonitorStmt(soot.jimple.MonitorStmt) LinkedList(java.util.LinkedList) JGotoStmt(soot.jimple.internal.JGotoStmt) Type(soot.Type) RefType(soot.RefType) IntType(soot.IntType) IfStmt(soot.jimple.IfStmt) ParameterRef(soot.jimple.ParameterRef) DThisRef(soot.dava.internal.javaRep.DThisRef) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) ThrowStmt(soot.jimple.ThrowStmt) DefinitionStmt(soot.jimple.DefinitionStmt) ReturnStmt(soot.jimple.ReturnStmt)

Example 8 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class UnitGraph method buildUnexceptionalEdges.

/**
 * Utility method for <tt>UnitGraph</tt> constructors. It computes the edges
 * corresponding to unexceptional control flow.
 *
 * @param unitToSuccs
 *            A {@link Map} from {@link Unit}s to {@link List}s of
 *            {@link Unit}s. This is an ``out parameter''; callers must pass
 *            an empty {@link Map}. <tt>buildUnexceptionalEdges</tt> will
 *            add a mapping for every <tt>Unit</tt> in the body to a list of
 *            its unexceptional successors.
 *
 * @param unitToPreds
 *            A {@link Map} from {@link Unit}s to {@link List}s of
 *            {@link Unit}s. This is an ``out parameter''; callers must pass
 *            an empty {@link Map}. <tt>buildUnexceptionalEdges</tt> will
 *            add a mapping for every <tt>Unit</tt> in the body to a list of
 *            its unexceptional predecessors.
 */
protected void buildUnexceptionalEdges(Map<Unit, List<Unit>> unitToSuccs, Map<Unit, List<Unit>> unitToPreds) {
    Iterator<Unit> unitIt = unitChain.iterator();
    Unit currentUnit, nextUnit;
    nextUnit = unitIt.hasNext() ? (Unit) unitIt.next() : null;
    while (nextUnit != null) {
        currentUnit = nextUnit;
        nextUnit = unitIt.hasNext() ? (Unit) unitIt.next() : null;
        ArrayList<Unit> successors = new ArrayList<Unit>();
        if (currentUnit.fallsThrough()) {
            // Add the next unit as the successor
            if (nextUnit != null) {
                successors.add(nextUnit);
                List<Unit> preds = unitToPreds.get(nextUnit);
                if (preds == null) {
                    preds = new ArrayList<Unit>();
                    unitToPreds.put(nextUnit, preds);
                }
                preds.add(currentUnit);
            }
        }
        if (currentUnit.branches()) {
            for (UnitBox targetBox : currentUnit.getUnitBoxes()) {
                Unit target = targetBox.getUnit();
                // target it falls through to, so we screen for duplicates:
                if (!successors.contains(target)) {
                    successors.add(target);
                    List<Unit> preds = unitToPreds.get(target);
                    if (preds == null) {
                        preds = new ArrayList<Unit>();
                        unitToPreds.put(target, preds);
                    }
                    preds.add(currentUnit);
                }
            }
        }
        // Store away successors
        if (!successors.isEmpty()) {
            successors.trimToSize();
            unitToSuccs.put(currentUnit, successors);
        }
    }
}
Also used : UnitBox(soot.UnitBox) ArrayList(java.util.ArrayList) Unit(soot.Unit)

Example 9 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class HashChain method insertOnEdge.

/**
 * Inserts instrumentation in a manner such that the resulting control flow
 * graph (CFG) of the program will contain <code>toInsert</code> on an edge
 * that is defined by <code>point_source</code> and
 * <code>point_target</code>.
 *
 * @param toInsert
 *            instrumentation to be added in the Chain
 * @param point_src
 *            the source point of an edge in CFG
 * @param point_tgt
 *            the target point of an edge
 */
public void insertOnEdge(Collection<? extends E> toInsert, E point_src, E point_tgt) {
    if (toInsert == null)
        throw new RuntimeException("Bad idea! You tried to insert " + "a null object into a Chain!");
    // is null
    if (point_src == null && point_tgt != null) {
        ((Unit) point_tgt).redirectJumpsToThisTo((Unit) toInsert.iterator().next());
        insertBefore(toInsert, point_tgt);
        return;
    }
    // is null
    if (point_src != null && point_tgt == null) {
        insertAfter(toInsert, point_src);
        return;
    }
    // Throw an exception if both source and target is null
    if (point_src == null && point_tgt == null) {
        throw new RuntimeException("insertOnEdge failed! Both source and target points are null.");
    }
    // 2- Insert 'toInsert' after 'source' in Chain
    if (getSuccOf(point_src) == point_tgt) {
        List<UnitBox> boxes = ((Unit) point_src).getUnitBoxes();
        for (UnitBox box : boxes) {
            if (box.getUnit() == point_tgt) {
                box.setUnit((Unit) toInsert.iterator().next());
            }
        }
        insertAfter(toInsert, point_src);
        return;
    }
    // If the target is not right after the source in chain then,
    // 1- Redirect all jumps (if any) from 'source' to 'target', to
    // 'toInsert[0]'
    // (source->target) ==> (source->toInsert[0])
    // 1.1- if there are no jumps from source to target, then such an edge
    // does not exist. Throw an exception.
    // 2- Insert 'toInsert' before 'target' in Chain
    // 3- If required, add a 'goto target' statement so that no other edge
    // executes 'toInsert'
    boolean validEdgeFound = false;
    E originalPred = getPredOf(point_tgt);
    List<UnitBox> boxes = ((Unit) point_src).getUnitBoxes();
    for (UnitBox box : boxes) {
        if (box.getUnit() == point_tgt) {
            if (point_src instanceof GotoStmt) {
                box.setUnit((Unit) toInsert.iterator().next());
                insertAfter(toInsert, point_src);
                E goto_unit = (E) new JGotoStmt((Unit) point_tgt);
                if (toInsert instanceof List) {
                    List l = ((List) toInsert);
                    insertAfter(goto_unit, (E) l.get(l.size() - 1));
                } else
                    insertAfter(goto_unit, (E) toInsert.toArray()[toInsert.size() - 1]);
                return;
            }
            box.setUnit((Unit) toInsert.iterator().next());
            validEdgeFound = true;
        }
    }
    if (validEdgeFound) {
        insertBefore(toInsert, point_tgt);
        if (originalPred != point_src) {
            if (originalPred instanceof GotoStmt)
                return;
            E goto_unit = (E) new JGotoStmt((Unit) point_tgt);
            insertBefore(goto_unit, (E) toInsert.iterator().next());
        }
        return;
    }
    // The following code handles such scenarios.
    if (getSuccOf(point_src) instanceof GotoStmt) {
        if (((Unit) getSuccOf(point_src)).getUnitBoxes().get(0).getUnit() == point_tgt) {
            ((Unit) getSuccOf(point_src)).redirectJumpsToThisTo((Unit) toInsert.iterator().next());
            insertBefore(toInsert, getSuccOf(point_src));
            return;
        }
    }
    // Return an exception.
    throw new RuntimeException("insertOnEdge failed! No such edge found. The edge on which you want to insert an instrumentation is invalid.");
}
Also used : JGotoStmt(soot.jimple.internal.JGotoStmt) UnitBox(soot.UnitBox) GotoStmt(soot.jimple.GotoStmt) JGotoStmt(soot.jimple.internal.JGotoStmt) ArrayList(java.util.ArrayList) List(java.util.List) Unit(soot.Unit)

Example 10 with UnitBox

use of soot.UnitBox in project soot by Sable.

the class DexReturnInliner method internalTransform.

@Override
protected void internalTransform(final Body body, String phaseName, Map<String, String> options) {
    Set<Unit> duplicateIfTargets = getFallThroughReturns(body);
    Iterator<Unit> it = body.getUnits().snapshotIterator();
    boolean mayBeMore = false;
    Unit last = null;
    do {
        mayBeMore = false;
        while (it.hasNext()) {
            Unit u = it.next();
            if (u instanceof GotoStmt) {
                GotoStmt gtStmt = (GotoStmt) u;
                if (isInstanceofReturn(gtStmt.getTarget())) {
                    Stmt stmt = (Stmt) gtStmt.getTarget().clone();
                    for (Trap t : body.getTraps()) for (UnitBox ubox : t.getUnitBoxes()) if (ubox.getUnit() == u)
                        ubox.setUnit(stmt);
                    while (!u.getBoxesPointingToThis().isEmpty()) u.getBoxesPointingToThis().get(0).setUnit(stmt);
                    // the cloned return stmt gets the tags of u
                    stmt.addAllTagsOf(u);
                    body.getUnits().swapWith(u, stmt);
                    mayBeMore = true;
                }
            } else if (u instanceof IfStmt) {
                IfStmt ifstmt = (IfStmt) u;
                Unit t = ifstmt.getTarget();
                if (isInstanceofReturn(t)) {
                    // once, otherwise we will end up with unused copies
                    if (duplicateIfTargets == null)
                        duplicateIfTargets = new HashSet<Unit>();
                    if (!duplicateIfTargets.add(t)) {
                        Unit newTarget = (Unit) t.clone();
                        body.getUnits().addLast(newTarget);
                        ifstmt.setTarget(newTarget);
                    }
                }
            } else if (isInstanceofReturn(u)) {
                // the original return stmt gets the tags of its predecessor
                if (last != null) {
                    u.removeAllTags();
                    u.addAllTagsOf(last);
                }
            }
            last = u;
        }
    } while (mayBeMore);
}
Also used : UnitBox(soot.UnitBox) IfStmt(soot.jimple.IfStmt) GotoStmt(soot.jimple.GotoStmt) Trap(soot.Trap) Unit(soot.Unit) GotoStmt(soot.jimple.GotoStmt) ReturnStmt(soot.jimple.ReturnStmt) Stmt(soot.jimple.Stmt) ReturnVoidStmt(soot.jimple.ReturnVoidStmt) IfStmt(soot.jimple.IfStmt)

Aggregations

UnitBox (soot.UnitBox)23 Unit (soot.Unit)16 ArrayList (java.util.ArrayList)9 Trap (soot.Trap)9 Value (soot.Value)8 HashMap (java.util.HashMap)5 Local (soot.Local)5 Iterator (java.util.Iterator)4 LabelNode (org.objectweb.asm.tree.LabelNode)4 GotoStmt (soot.jimple.GotoStmt)4 IntConstant (soot.jimple.IntConstant)4 ReturnStmt (soot.jimple.ReturnStmt)4 HashSet (java.util.HashSet)3 List (java.util.List)3 CaughtExceptionRef (soot.jimple.CaughtExceptionRef)3 IdentityStmt (soot.jimple.IdentityStmt)3 IfStmt (soot.jimple.IfStmt)3 ParameterRef (soot.jimple.ParameterRef)3 Stmt (soot.jimple.Stmt)3 ThisRef (soot.jimple.ThisRef)3