public static Unit insertAfter(SootMethod sootMethod, Unit insertedUnit, Unit originUnit) { Body b = sootMethod.retrieveActiveBody(); PatchingChain<Unit> units = b.getUnits(); units.insertAfter(insertedUnit, originUnit); return insertedUnit; }
private static List<Unit> searchIfStmts(Body b) { List<Unit> searchResult = new ArrayList<Unit>(); PatchingChain<Unit> statements = b.getUnits(); Iterator<Unit> unitIt = statements.iterator(); // iterate through the Units of the body while (unitIt.hasNext()) { Unit tempUnit = unitIt.next(); // if the unit is a "if statement" if (tempUnit instanceof soot.jimple.internal.JIfStmt) searchResult.add(tempUnit); } return searchResult; }
public static Stmt getFirstNonIdentityStmt(SootMethod sootMethod) { Stmt rtVal = null; Body b = sootMethod.retrieveActiveBody(); PatchingChain<Unit> units = b.getUnits(); for (Iterator<Unit> iter = units.iterator(); iter.hasNext(); ) { Stmt stmt = (Stmt) iter.next(); if (!(stmt instanceof IdentityStmt)) { rtVal = stmt; } } return rtVal; }
public static void main(String args[]) { // Set classPath String exemplePath = "/Users/gamyot/Documents/workspace/Soot_Exemples/src/"; String objectPath = "/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar"; String tracePath = "/Users/gamyot/Documents/workspace/SootInstrumenter/src/"; Scene.v().setSootClassPath(".:" + objectPath + ":" + exemplePath + ":" + tracePath); Scene.v().loadClassAndSupport("java.lang.Object"); Scene.v().loadClassAndSupport("java.lang.System"); // Set up the class we’re working with SootClass c = Scene.v().loadClassAndSupport("MyExemples.ExempleBasic"); c.setApplicationClass(); // Get methods Iterator<SootMethod> methodIterator = c.methodIterator(); while (methodIterator.hasNext()) methodList.add(methodIterator.next()); // Iterate through the method list for (SootMethod m : methodList) { Body body = m.retrieveActiveBody(); PatchingChain<Unit> unitList = body.getUnits(); // get the all the "if statements" Units List<Unit> ifStmtList = searchIfStmts(body); // for each "if statement" unit, instrument and add the instrumentation code right after for (Unit ifStmtUnit : ifStmtList) { // Chain<Unit> instrumentedChain = generateInstrumentationUnits(ifStmtUnit, body); // unitList.insertAfter(instrumentedChain, ifStmtUnit); Chain<Unit> testChain = generateInstrumentationUnits(ifStmtUnit, body); unitList.insertAfter(testChain, ifStmtUnit); } // Output all the units for this method on terminal String methodName = m.getName(); System.out.println( "____Method: \"" + methodName + "\"__________________________________________________"); LoadAndGenerate.printAllUnits(body); } try { LoadAndGenerate.outputClassToBinary(c); } catch (IOException e) { e.printStackTrace(); } }
/** * Returns basic block that contains the statement, or null. If id stmt, it looks in tag of first * non-id stmt. */ public static Block getBB(Stmt s) { Block bb; // 2010-02-26: return null when s == null if (s != null) { // move to first non-id stmt Stmt sNonId = s; if (sNonId instanceof IdentityStmt) { PatchingChain pchain = ProgramFlowGraph.inst().getContainingMethod(sNonId).retrieveActiveBody().getUnits(); do { sNonId = (Stmt) pchain.getSuccOf(sNonId); } while (sNonId instanceof IdentityStmt); } // retrieve basic block for non-id stmt StmtTag sTag = (StmtTag) sNonId.getTag(StmtTag.TAG_NAME); bb = sTag.getBasicBlock(); } else { bb = null; } return bb; }
public static void insertBefore(SootMethod sootMethod, Unit insertedUnit, Unit originUnit) { Body b = sootMethod.retrieveActiveBody(); PatchingChain<Unit> units = b.getUnits(); units.insertBefore(insertedUnit, originUnit); }
public boolean DoAnalysis(boolean verbose) { Stack<List<Set<SootClass>>> current_exception_sets = new Stack<List<Set<SootClass>>>(); { List<Set<SootClass>> exception_sets = new ArrayList<Set<SootClass>>(); exception_sets.add(method_exception_set); current_exception_sets.push(exception_sets); } PatchingChain<Unit> chain = body.getUnits(); Unit next = chain.getFirst(); int previous_class_count = method_exception_set.size(); for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry : trap_begin_exception_sets.entrySet()) { for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) { previous_class_count += tvp.w.size(); } } do { if (trap_begin_exception_sets.containsKey(next)) { List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_begin_exception_sets.get(next); List<Set<SootClass>> sets_to_add = new ArrayList<Set<SootClass>>(); for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { sets_to_add.add(tvp.w); } current_exception_sets.push(sets_to_add); } if (next instanceof InvokeStmt || next instanceof AssignStmt) { SootMethod callee = null; if (next instanceof AssignStmt) { if (((AssignStmt) next).getRightOp() instanceof InvokeExpr) { callee = ((InvokeExpr) ((AssignStmt) next).getRightOp()).getMethod(); } } else { callee = ((InvokeStmt) next).getInvokeExpr().getMethod(); } if (callee != null) { // invocation only Collection<SootClass> exception_classes; if (class_map.containsKey(callee.getDeclaringClass())) { assert class_map.get(callee.getDeclaringClass()).method_analysis.containsKey(callee); exception_classes = class_map .get(callee.getDeclaringClass()) .method_analysis .get(callee) .method_exception_set; } else { exception_classes = callee.getExceptions(); } for (SootClass exception_class : exception_classes) { for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { current_exception_set.add(exception_class); } } } } else if (next instanceof ThrowStmt) { assert chain.getPredOf(next) instanceof JInvokeStmt; assert ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr() instanceof SpecialInvokeExpr; assert ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()).getBase() instanceof JimpleLocal; assert ((JimpleLocal) ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()) .getBase()) .getType() instanceof RefType; SootClass exception_class = ((RefType) ((JimpleLocal) ((SpecialInvokeExpr) ((JInvokeStmt) chain.getPredOf(next)).getInvokeExpr()) .getBase()) .getType()) .getSootClass(); for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { current_exception_set.add(exception_class); } } if (trap_end_exception_sets.containsKey(next)) { List<TwoValuePair<Trap, Set<SootClass>>> tvps = trap_end_exception_sets.get(next); if (verbose) { for (Set<SootClass> current_exception_set : current_exception_sets.peek()) { if (current_exception_set.size() == 0) { for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { if (!tvp.v.getException().getName().equals("java.lang.RuntimeException")) System.out.println( "Warning: In " + method.toString() + ": Unncessary exception handler for catching " + tvp.v.getException().getName()); } } } } for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { Iterator<SootClass> i = tvp.w.iterator(); while (i.hasNext()) { SootClass exception_class = i.next(); if (tvp.v.getException() == exception_class) { // getting properly caught by the handler. i.remove(); } else { SootClass super_exception_class = exception_class; while (super_exception_class != null) { if (tvp.v.getException() == super_exception_class) { i.remove(); if (verbose && super_exception_class != exception_class && GetMostRestrictiveFormOfException(tvps, exception_class) == tvp.v.getException() && !super_exception_class.getName().equals("java.lang.RuntimeException")) { System.out.println( "Warning: In " + method.toString() + ": attempting to catch " + exception_class.getName() + " with " + super_exception_class.getName() + " Consider catching the most restrictive exception class"); } break; } try { super_exception_class = super_exception_class.getSuperclass(); } catch ( RuntimeException e) { // unfortunately soot doesn't have a specific exception class for "no // superclass for java.lang.Object" exception super_exception_class = null; } } } } } current_exception_sets.pop(); for (Set<SootClass> current_exception_set : current_exception_sets .peek()) { // This list iteration is not necessary if we are still making the // assumption that there's only one unique set that contains exception // classes if the range for traps are the same for (TwoValuePair<Trap, Set<SootClass>> tvp : tvps) { for (SootClass exception_class : tvp.w) { current_exception_set.add(exception_class); } } } } next = chain.getSuccOf(next); } while (next != null); int new_class_count = method_exception_set.size(); for (Map.Entry<Unit, List<TwoValuePair<Trap, Set<SootClass>>>> entry : trap_begin_exception_sets.entrySet()) { for (TwoValuePair<Trap, Set<SootClass>> tvp : entry.getValue()) { new_class_count += tvp.w.size(); } } return new_class_count != previous_class_count; }