protected void buildSimpleExceptionalEdges(Map unitToSuccs, Map unitToPreds) { for (Iterator<Trap> trapIt = body.getTraps().iterator(); trapIt.hasNext();) { Trap trap = trapIt.next(); Unit handler = trap.getHandlerUnit(); for (Iterator predIt = ((List) unitToPreds.get(trap.getBeginUnit())).iterator(); predIt.hasNext();) { Unit pred = (Unit) predIt.next(); addEdge(unitToSuccs, unitToPreds, pred, handler); } } } }
private boolean isExceptionHandlerBlock(Block aBlock) { Unit blockHead = aBlock.getHead(); for (Trap trap : mBody.getTraps()) { if (trap.getHandlerUnit() == blockHead) { return true; } } return false; }
/** Returns a set of units which lie inside the range of any trap. */ public static Set<Unit> getTrappedUnitsOf(Body b) { Set<Unit> trapsSet = new HashSet<Unit>(); Chain<Unit> units = b.getUnits(); for (Trap t : b.getTraps()) { Iterator<Unit> it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit())); while (it.hasNext()) { trapsSet.add(it.next()); } } return trapsSet; }
/** Returns the list of traps caught at Unit u in Body b. */ public static List<Trap> getTrapsAt(Unit unit, Body b) { List<Trap> trapsList = new ArrayList<Trap>(); Chain<Unit> units = b.getUnits(); for (Trap t : b.getTraps()) { Iterator<Unit> it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit())); while (it.hasNext()) { if (unit.equals(it.next())) { trapsList.add(t); } } } return trapsList; }
public boolean checkTraps(Unit u, Body b) { Iterator<Trap> it = b.getTraps().iterator(); while (it.hasNext()) { Trap t = it.next(); if (t.getBeginUnit() == u || t.getEndUnit() == u || t.getHandlerUnit() == u) { return true; } } return false; }
/** * Given a body and a unit handling an exception, returns the list of exception types possibly caught by the handler. */ public static List<RefType> getExceptionTypesOf(Unit u, Body body) { List<RefType> possibleTypes = new ArrayList<RefType>(); for (Trap trap : body.getTraps()) { if (trap.getHandlerUnit() == u) { possibleTypes.add(RefType.v(trap.getException().getName())); } } return possibleTypes; } }
/** * Adds a new trap to the given body only if the given trap is not empty * * @param b * The body to which to add the trap * @param newTrap * The trap to add * @param position * The position after which to insert the trap */ private void safeAddTrap(Body b, Trap newTrap, Trap position) { // Do not create any empty traps if (newTrap.getBeginUnit() != newTrap.getEndUnit()) { if (position != null) { b.getTraps().insertAfter(newTrap, position); } else { b.getTraps().add(newTrap); } } }
private List<Trap> getTrapsForUnit(Object o, Body b) { ArrayList<Trap> list = new ArrayList<Trap>(); Chain<Trap> traps = b.getTraps(); if (traps.size() != 0) { PatchingChain<Unit> units = b.getUnits(); Iterator<Trap> it = traps.iterator(); while (it.hasNext()) { Trap t = it.next(); Iterator<Unit> tit = units.iterator(t.getBeginUnit(), t.getEndUnit()); while (tit.hasNext()) { if (tit.next() == o) { list.add(t); break; } } } } return list; }
private void register_AreasOfProtection(SootMethod m) { if (registeredMethods.contains(m)) { return; } registeredMethods.add(m); if (m.hasActiveBody() == false) { return; } Body b = m.getActiveBody(); Chain stmts = b.getUnits(); Iterator trapIt = b.getTraps().iterator(); while (trapIt.hasNext()) { Trap t = (Trap) trapIt.next(); SootClass exception = t.getException(); Iterator sit = stmts.iterator(t.getBeginUnit(), stmts.getPredOf(t.getEndUnit())); while (sit.hasNext()) { Stmt s = (Stmt) sit.next(); HashSet<SootClass> handled = null; if ((handled = protectionSet.get(s)) == null) { handled = new HashSet<SootClass>(); protectionSet.put(s, handled); } if (handled.contains(exception) == false) { handled.add(exception); } } } }
/** * If exception e is caught at stmt s in body b, return the handler; otherwise, return null. */ static boolean isExceptionCaughtAt(SootClass e, Stmt stmt, Body b) { /* * Look through the traps t of b, checking to see if: - caught exception is e; - and, stmt lies between t.beginUnit and * t.endUnit */ Hierarchy h = new Hierarchy(); Iterator<Trap> trapsIt = b.getTraps().iterator(); while (trapsIt.hasNext()) { Trap t = trapsIt.next(); /* Ah ha, we might win. */ if (h.isClassSubclassOfIncluding(e, t.getException())) { Iterator<Unit> it = b.getUnits().iterator(t.getBeginUnit(), t.getEndUnit()); while (it.hasNext()) { if (stmt.equals(it.next())) { return true; } } } } return false; } }
/** * Method to compute the edges corresponding to exceptional control flow. * * @param unitToSuccs * A <code>Map</code> from {@link Unit}s to {@link List}s of <code>Unit</code>s. This is an “out * parameter”; <code>buildExceptionalEdges</code> will add a mapping for every <code>Unit</code> within the * scope of one or more {@link Trap}s to a <code>List</code> of the handler units of those <code>Trap</code>s. * * @param unitToPreds * A <code>Map</code> from <code>Unit</code>s to <code>List</code>s of <code>Unit</code>s. This is an “out * parameter”; <code>buildExceptionalEdges</code> will add a mapping for every <code>Trap</code> handler to * all the <code>Unit</code>s within the scope of that <code>Trap</code>. */ protected void buildExceptionalEdges(Map<Unit, List<Unit>> unitToSuccs, Map<Unit, List<Unit>> unitToPreds) { for (Trap trap : body.getTraps()) { Unit first = trap.getBeginUnit(); Unit last = unitChain.getPredOf(trap.getEndUnit()); Unit catcher = trap.getHandlerUnit(); for (Iterator<Unit> unitIt = unitChain.iterator(first, last); unitIt.hasNext();) { Unit trapped = unitIt.next(); addEdge(unitToSuccs, unitToPreds, trapped, catcher); } } } }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for (Iterator<Trap> trapIt = b.getTraps().snapshotIterator(); trapIt.hasNext();) { Trap t = trapIt.next(); Unit beginUnit; while (!isDexInstruction(beginUnit = t.getBeginUnit()) && t.getBeginUnit() != t.getEndUnit()) { t.setBeginUnit(b.getUnits().getSuccOf(beginUnit)); } // If the trap is empty, we remove it if (t.getBeginUnit() == t.getEndUnit()) { trapIt.remove(); } } }
/** * If exception e is caught at unit u in body b, return true; otherwise, return false. */ public static boolean isExceptionCaughtAt(SootClass e, Unit u, Body b) { /* * Look through the traps t of b, checking to see if: - caught exception is e; - and, unit lies between t.beginUnit and * t.endUnit */ Hierarchy h = Scene.v().getActiveHierarchy(); Chain<Unit> units = b.getUnits(); for (Trap t : b.getTraps()) { /* Ah ha, we might win. */ if (h.isClassSubclassOfIncluding(e, t.getException())) { Iterator<Unit> it = units.iterator(t.getBeginUnit(), units.getPredOf(t.getEndUnit())); while (it.hasNext()) { if (u.equals(it.next())) { return true; } } } } return false; }
public EnhancedUnitGraph(Body body) { super(body); // try2nop = new Hashtable<GuardedBlock, Unit>(); try2nop = new Hashtable<Unit, Unit>(); handler2header = new Hashtable<Unit, Unit>(); // there could be a maximum of traps.size() of nop // units added to the CFG plus potentially START/STOP nodes. int size = unitChain.size() + body.getTraps().size() + 2; unitToSuccs = new HashMap<Unit, List<Unit>>(size * 2 + 1, 0.7f); unitToPreds = new HashMap<Unit, List<Unit>>(size * 2 + 1, 0.7f); /* * Compute the head and tails at each phase because other phases might rely on them. */ buildUnexceptionalEdges(unitToSuccs, unitToPreds); addAuxiliaryExceptionalEdges(); buildHeadsAndTails(); handleExplicitThrowEdges(); buildHeadsAndTails(); handleMultipleReturns(); buildHeadsAndTails(); /** * Remove bogus heads (these are useless goto's) */ removeBogusHeads(); buildHeadsAndTails(); }
public void redirectTraps(Body b, Unit oldUnit, Unit newUnit) { Chain<Trap> traps = b.getTraps(); for (Trap trap : traps) { if (trap.getHandlerUnit() == oldUnit) { trap.setHandlerUnit(newUnit); } if (trap.getBeginUnit() == oldUnit) { trap.setBeginUnit(newUnit); } if (trap.getEndUnit() == oldUnit) { trap.setEndUnit(newUnit); } } }
/** * Gets two arbitrary overlapping traps in the given method body * * @param b * The body in which to look for overlapping traps * @return Two overlapping traps if they exist, otherwise null */ private TrapOverlap getNextOverlap(Body b) { for (Trap t1 : b.getTraps()) { // Look whether one of our trapped statements is the begin // statement of another trap for (Unit splitUnit = t1.getBeginUnit(); splitUnit != t1.getEndUnit(); splitUnit = b.getUnits().getSuccOf(splitUnit)) { for (Trap t2 : b.getTraps()) { if (t1 != t2 && (t1.getEndUnit() != t2.getEndUnit() || t1.getException() == t2.getException()) && t2.getBeginUnit() == splitUnit) { return new TrapOverlap(t1, t2, t2.getBeginUnit()); } } } } return null; }
@Override /** Verifies that the begin, end and handler units of each trap are in this body. */ public void validate(Body body, List<ValidationException> exception) { PatchingChain<Unit> units = body.getUnits(); for (Trap t : body.getTraps()) { if (!units.contains(t.getBeginUnit())) { exception.add(new ValidationException(t.getBeginUnit(), "begin not in chain" + " in " + body.getMethod())); } if (!units.contains(t.getEndUnit())) { exception.add(new ValidationException(t.getEndUnit(), "end not in chain" + " in " + body.getMethod())); } if (!units.contains(t.getHandlerUnit())) { exception.add(new ValidationException(t.getHandlerUnit(), "handler not in chain" + " in " + body.getMethod())); } } }
protected void internalTransform(Body b, String phaseName, Map<String, String> options) { if (b.getMethod().getName().indexOf("<clinit>") >= 0) { return; } int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature()); if (weight == 0) { return; } PatchingChain<Unit> units = b.getUnits(); Iterator<Unit> iter = units.snapshotIterator(); while (iter.hasNext()) { Unit u = (Unit) iter.next(); if (u instanceof PushInst) { SootField f = CollectConstants.constantsToFields.get(((PushInst) u).getConstant()); if (f != null && Rand.getInt(10) <= weight) { Unit get = Baf.v().newStaticGetInst(f.makeRef()); units.insertBefore(get, u); BodyBuilder.updateTraps(get, u, b.getTraps()); units.remove(u); updated++; } } } } }
protected boolean isExceptionCaught(Body b, Stmt s, RefType throwType) { if (hierarchy == null) { hierarchy = new FastHierarchy(); } Iterator it = b.getTraps().iterator(); while (it.hasNext()) { Trap trap = (Trap) it.next(); if (trap.getException().getType().equals(throwType) || hierarchy.isSubclass(throwType.getSootClass(), (trap.getException().getType()).getSootClass())) { if (isThrowInStmtRange(b, (Stmt) trap.getBeginUnit(), (Stmt) trap.getEndUnit(), s)) { return true; } } } return false; }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for (Trap t : b.getTraps()) { // If the first statement already catches the exception, we're fine if (isCaughtExceptionRef(t.getHandlerUnit())) { continue; } // Add the exception reference Local l = new LocalGenerator(b).generateLocal(t.getException().getType()); Stmt caughtStmt = Jimple.v().newIdentityStmt(l, Jimple.v().newCaughtExceptionRef()); b.getUnits().add(caughtStmt); b.getUnits().add(Jimple.v().newGotoStmt(t.getHandlerUnit())); t.setHandlerUnit(caughtStmt); } }