private ResultSourceInfo findDataFlowPathForSink(Stmt sinkStmt, Local sinkLokal, List<ResultSourceInfo> allDataFlows) { for(ResultSourceInfo singleFlow : allDataFlows){ Stmt[] statements = singleFlow.getPath(); AccessPath[] accessPath = singleFlow.getPathAccessPaths(); for(int i = 0; i < statements.length; i++) { Stmt currentStmt = statements[i]; if(currentStmt == sinkStmt) { if(accessPath[i].getPlainValue() == sinkLokal) return singleFlow; } else if(currentStmt instanceof AssignStmt) { AssignStmt assignStmt = (AssignStmt)currentStmt; Value lhs = assignStmt.getLeftOp(); if(lhs == sinkLokal) return singleFlow; } } } return null; }
private boolean hasConstantIndexAtArrayForSplitDataFlow(Stmt[] dataflow) { Stmt firstAssign = dataflow[0]; if(firstAssign instanceof AssignStmt) { AssignStmt ass = (AssignStmt)firstAssign; Value value = ass.getRightOp(); if(value instanceof ArrayRef) { ArrayRef aRef = (ArrayRef)value; Value index = aRef.getIndex(); if(index instanceof IntConstant) return true; } } else throw new RuntimeException("this should not happen - wrong assumption"); return false; }
private int getConstantArrayIndexForSplitDataFlow(Stmt[] dataflow) { Stmt firstAssign = dataflow[0]; if(firstAssign instanceof AssignStmt) { AssignStmt ass = (AssignStmt)firstAssign; Value value = ass.getRightOp(); if(value instanceof ArrayRef) { ArrayRef aRef = (ArrayRef)value; Value index = aRef.getIndex(); if(index instanceof IntConstant) return ((IntConstant) index).value; } } else throw new RuntimeException("this should not happen - wrong assumption"); return -1; }
private String fixSMTSolverIntegerOutput(String loggingPoint, Stmt stmt) { if(stmt.containsInvokeExpr()) { InvokeExpr inv = stmt.getInvokeExpr(); String metSig = inv.getMethod().getSignature(); if(metSig.equals("<android.telephony.TelephonyManager: java.lang.String getSimOperator()>") || metSig.equals("<android.telephony.TelephonyManager: java.lang.String getNetworkOperator()>") ) { String newLoggingPoint = ""; for(char c : loggingPoint.toCharArray()) { if(c < '0' || c > '9') { Random rand = new Random(); int num = rand.nextInt(10); newLoggingPoint += num; } else newLoggingPoint += c; } return newLoggingPoint; } } return loggingPoint; }
private boolean isSemanticallyCorrect(String loggingPoint, Stmt stmt) { if(loggingPoint == null) return false; if(stmt.containsInvokeExpr()) { InvokeExpr inv = stmt.getInvokeExpr(); String metSig = inv.getMethod().getSignature(); if(metSig.equals("<android.telephony.TelephonyManager: java.lang.String getSimOperator()>") || metSig.equals("<android.telephony.TelephonyManager: java.lang.String getNetworkOperator()>") ) { for(char c : loggingPoint.toCharArray()) { if(c < '0' || c > '9') return false; } } } return true; }
private AnalysisDecision getFileFormatFromDataflow(int codePosID ) { Unit unit = codePositionManager.getUnitForCodePosition(codePosID); if(unit instanceof Stmt) { Stmt stmt = (Stmt)unit; if(stmt.containsInvokeExpr()) { InvokeExpr inv = stmt.getInvokeExpr(); SootMethod sm = inv.getMethod(); Pair<Integer, Object> paramValue = retrieveCorrectFileInformation(sm); ServerResponse response = new ServerResponse(); response.setAnalysisName(getAnalysisName()); response.setResponseExist(true); response.setParamValues(Collections.singleton(paramValue)); AnalysisDecision finalDecision = new AnalysisDecision(); finalDecision.setAnalysisName(getAnalysisName()); finalDecision.setDecisionWeight(8); finalDecision.setServerResponse(response); return finalDecision; } else return noResults(); } else { return noResults(); } }
@Override public Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generate(Unit unit, Collection<SootMethod> calledMethod) { boolean matches = false; for (SootMethod method : calledMethod) { if (initialTrans.matches(method)) { matches = true; } } if (!matches) return Collections.emptySet(); if (unit instanceof Stmt && ((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph((Local) iie.getBase(), iie.getBase().getType()), new TransitionFunction(initialTrans))); return out; } return Collections.emptySet(); }
protected Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generateAtConstructor(Unit unit, Collection<SootMethod> calledMethod, MatcherTransition initialTrans) { boolean matches = false; for (SootMethod method : calledMethod) { if (initialTrans.matches(method)) { matches = true; } } if (!matches) return Collections.emptySet(); if (unit instanceof Stmt) { Stmt stmt = (Stmt) unit; if (stmt.containsInvokeExpr()) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iie.getBase() instanceof Local) { Local l = (Local) iie.getBase(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph(l, l.getType()), new TransitionFunction(initialTrans))); return out; } } } return Collections.emptySet(); }
protected Collection<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> generateThisAtAnyCallSitesOf(Unit unit, Collection<SootMethod> calledMethod, Set<SootMethod> hasToCall, MatcherTransition initialTrans) { for (SootMethod callee : calledMethod) { if (hasToCall.contains(callee)) { if (unit instanceof Stmt) { if (((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); Local thisLocal = (Local) iie.getBase(); Set<Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>> out = new HashSet<>(); out.add(new Pair<AccessGraph, EdgeFunction<TypestateDomainValue>>( new AccessGraph(thisLocal, thisLocal.getType()), new TransitionFunction(initialTrans))); return out; } } } } return Collections.emptySet(); }
private static void getUnitInBetween(UnitGraph ug, List<Unit>inBetween, Unit u) { for (Unit succ: ug.getSuccsOf(u)) { Stmt s = (Stmt)succ; if (inBetween.contains(succ)) { continue; } if (s.containsInvokeExpr()) { InvokeExpr ie = s.getInvokeExpr(); if (ie.getMethodRef().name().contains("restoreCallingIdentity")) { return; } } inBetween.add(succ); getUnitInBetween(ug, inBetween, succ); } }
private SootMethod hasGetInstanceMethod(SootClass sc) { String cname = sc.getName(); if (!(cname.startsWith("android") || cname.startsWith("com.android"))) return null; for (SootMethod sm: sc.getMethods()) { if (sm.isConcrete() && sm.getName().equals(("getInstance"))) { Body b = sm.retrieveActiveBody(); for (Unit u: b.getUnits()){ Stmt s = (Stmt)u; if (s.containsInvokeExpr()) { InvokeExpr ie = (InvokeExpr)s.getInvokeExpr(); String name = ie.getMethodRef().name(); if (name.equals("getService")) return sm; if (name.equals("getSystemService")) return sm; } } } } return null; }
private String getNameFromGetInstance(SootMethod sm) { Body b = sm.retrieveActiveBody(); for (Unit u: b.getUnits()){ Stmt s = (Stmt)u; if (s.containsInvokeExpr()) { InvokeExpr ie = (InvokeExpr)s.getInvokeExpr(); String name = ie.getMethodRef().name(); if (name.equals("getService")|| name.equals("getSystemService")) { List<Value> args = ie.getArgs(); int size = args.size(); Value v = args.get(size-1); if (v instanceof StringConstant) { StringConstant c = (StringConstant)v; return c.value; } else { throw new RuntimeException("error: expected constant string: "+ b); } } } } throw new RuntimeException("error: nothing found, expected constant string: "+ b); }
/** * To get a service (not to be confused with getSystemService) * @param b * @return */ public List<Unit> hasCallToGetSystem(Body b) { List<Unit> calls = new ArrayList<Unit>(); for (Unit u: b.getUnits()) { Stmt s = (Stmt)u; if (s.containsInvokeExpr()) { try { InvokeExpr ie = s.getInvokeExpr(); String mName = ie.getMethodRef().name(); //System.out.println("m : "+ ie.getMethodRef()); //System.out.println("mName: "+ mName); if (mName.equals("getService") && ie.getArgs().size() > 0) { calls.add(u); } } catch (Throwable t) { continue; } } } return calls; }
/** * To get a manager (not to be confused with getSystem) * * @param b * @return */ public List<Unit> hasCallToSystemServices(Body b) { List<Unit> calls = new ArrayList<Unit>(); for (Unit u : b.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { try { InvokeExpr ie = s.getInvokeExpr(); String mName = ie.getMethodRef().name(); // System.out.println("m : "+ ie.getMethodRef()); // System.out.println("mName: "+ mName); if (mName.equals("getSystemService")) { calls.add(u); } } catch (Throwable t) { continue; } } } return calls; }
/** * To get a service (not to be confused with getSystemService) * * @param b * @return */ public List<Unit> hasCallToService(Body b) { List<Unit> calls = new ArrayList<Unit>(); for (Unit u : b.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { try { InvokeExpr ie = s.getInvokeExpr(); String mName = ie.getMethodRef().name(); String cName = ie.getMethodRef().declaringClass().getName(); // System.out.println("m : "+ ie.getMethodRef()); // System.out.println("mName: "+ mName); if (mName.equals("getService") && cName.equals("android.os.ServiceManager")) { calls.add(u); } } catch (Throwable t) { continue; } } } return calls; }
@Override public Set<Object> computeArgumentValues(Argument argument, Unit callSite) { Stmt stmt = (Stmt) callSite; String classType = stmt.getInvokeExpr().getArg(argument.getArgnum()[0]).getType().toString(); if (classType.equals(BROADCAST_RECEIVER)) { List<SootClass> subclasses = Scene.v().getActiveHierarchy() .getSubclassesOf(Scene.v().getSootClass(BROADCAST_RECEIVER)); Set<Object> subclassStrings = new HashSet<>(); for (SootClass sootClass : subclasses) { subclassStrings.add(sootClass.getName()); } if (subclassStrings.size() == 0) { subclassStrings.add(BROADCAST_RECEIVER); } return subclassStrings; } return Collections.singleton((Object) classType); }
protected Set<Task> createTasks(Unit call) { Set<Task> newTasks = new HashSet<Task>(); Set<SootMethod> chaTargets = icfg.unitToCallees.getUnchecked(call); for (Iterator<SootMethod> iterator = chaTargets.iterator(); iterator.hasNext();) { SootMethod potentialTarget = iterator.next(); // If names match and target is not abstract if (potentialTarget.isAbstract() || !potentialTarget.getName().equals(((Stmt) call).getInvokeExpr().getMethod().getName())) { iterator.remove(); } } for (Layer l : Layer.values()) { AnalysisTask al = Layer.getAnalysisLayer(l, task, app, projectInformation); al.setAnalysisInfo(jumpFunctions, endSum, inc, icfg); Set<Task> tasks = al.createTasksForCall(call, chaTargets); newTasks.addAll(tasks); } return newTasks; }
public void add_AugmentedStmt( AugmentedStmt as) { Stmt s = as.get_Stmt(); aug_list.add( as); stmt_list.add( s); add_StmtBinding( s, as); if (as.bpreds.isEmpty()) bheads.add( as); if (as.cpreds.isEmpty()) cheads.add( as); if (as.bsuccs.isEmpty()) btails.add( as); if (as.csuccs.isEmpty()) ctails.add( as); check_List( as.bpreds, btails); check_List( as.bsuccs, bheads); check_List( as.cpreds, ctails); check_List( as.csuccs, cheads); }
@Test public void testGExitMonitorStmt() { Stmt s = Grimp.v().newExitMonitorStmt(StringConstant.v("test")); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedRep.add(utility.NULL_POINTER_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedCatch.add(utility.NULL_POINTER_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
@Override public Set<AccessGraph> getForwardValues(Stmt call, AccessGraph source, Value[] params){ //check some evaluated methods: //arraycopy: //arraycopy(Object src, int srcPos, Object dest, int destPos, int length) //Copies an array from the specified source array, beginning at the specified position, //to the specified position of the destination array. if(call.getInvokeExpr().getMethod().toString().contains("arraycopy")) if(params[0].equals(source.getBase()) && params[2] instanceof Local) { AccessGraph copied = source.deriveWithNewLocal((Local)params[2], source.getBaseType()); Set<AccessGraph> out = new HashSet<>(); out.add(source); out.add(copied); return out; } return Collections.emptySet(); }
public DavaFlowSet processASTStatementSequenceNode(ASTStatementSequenceNode node, DavaFlowSet input) { List<Object> statements = node.getStatements(); Iterator<Object> it = statements.iterator(); DavaFlowSet output = cloneFlowSet(input);// needed if there are no stmts while (it.hasNext()) { AugmentedStmt as = (AugmentedStmt) it.next(); Stmt s = as.get_Stmt(); /* * Since we are processing a list of statements the output of * previous is input of next */ output = process(s, output); if (DEBUG_STATEMENTS) { System.out.println("After Processing statement " + s + output.toString()); ; } } return output; }
@Ignore("Fails") @Test public void testJReturnVoidStmt() { Stmt s = Jimple.v().newReturnVoidStmt(); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
private void collect_constraints_1_2() { ConstraintCollector collector = new ConstraintCollector(this, true); for( Iterator<Unit> stmtIt = stmtBody.getUnits().iterator(); stmtIt.hasNext(); ) { final Stmt stmt = (Stmt) stmtIt.next(); if(DEBUG) { G.v().out.print("stmt: "); } collector.collect(stmt, stmtBody); if(DEBUG) { G.v().out.println(stmt); } } }
private SootMethod getOrCreateInitializer(SootClass sc, Set<SootField> alreadyInitialized) { SootMethod smInit; // Create a static initializer if we don't already have one smInit = sc.getMethodByNameUnsafe("<clinit>"); if (smInit == null) { smInit = new SootMethod("<clinit>", Collections.<Type>emptyList(), VoidType.v()); smInit.setActiveBody(Jimple.v().newBody(smInit)); sc.addMethod(smInit); smInit.setModifiers(Modifier.PUBLIC | Modifier.STATIC); } else { smInit.retrieveActiveBody(); // We need to collect those variables that are already initialized somewhere for (Unit u : smInit.getActiveBody().getUnits()) { Stmt s = (Stmt) u; for (ValueBox vb : s.getDefBoxes()) if (vb.getValue() instanceof FieldRef) alreadyInitialized.add(((FieldRef) vb.getValue()).getField()); } } return smInit; }
/** * Creates a new statement that throws a NullPointerException * @param body The body in which to create the statement * @param oldStmt The old faulty statement that shall be replaced with the * exception * @param lc The object for creating new locals */ private void createThrowStmt(Body body, Unit oldStmt, LocalCreation lc) { RefType tp = RefType.v("java.lang.NullPointerException"); Local lcEx = lc.newLocal(tp); SootMethodRef constructorRef = Scene.v().makeConstructorRef(tp.getSootClass(), Collections.singletonList((Type) RefType.v("java.lang.String"))); // Create the exception instance Stmt newExStmt = Jimple.v().newAssignStmt(lcEx, Jimple.v().newNewExpr(tp)); body.getUnits().insertBefore(newExStmt, oldStmt); Stmt invConsStmt = Jimple.v().newInvokeStmt(Jimple.v().newVirtualInvokeExpr(lcEx, constructorRef, Collections.singletonList(StringConstant.v( "Null throw statement replaced by Soot")))); body.getUnits().insertBefore(invConsStmt, oldStmt); // Throw the exception body.getUnits().swapWith(oldStmt, Jimple.v().newThrowStmt(lcEx)); }
@Ignore("Fails") @Test public void testGReturnStmt() { Stmt s = Grimp.v().newReturnStmt(IntConstant.v(1)); Set expectedRep = new ExceptionHashSet(utility.VM_ERRORS); expectedRep.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); assertTrue(ExceptionTestUtility.sameMembers(expectedRep, Collections.EMPTY_SET, unitAnalysis.mightThrow(s))); Set expectedCatch = new ExceptionHashSet(utility.VM_ERRORS_PLUS_SUPERTYPES); expectedCatch.add(utility.ILLEGAL_MONITOR_STATE_EXCEPTION); expectedCatch.add(utility.RUNTIME_EXCEPTION); expectedCatch.add(utility.EXCEPTION); assertEquals(expectedCatch, utility.catchableSubset(unitAnalysis.mightThrow(s))); }
/** * Gets the maximum number of registers needed by a single instruction in * the given list of instructions. * @param regsAlreadyReserved * @param insns * @param insnsStmtMap * @return */ private int getRegsNeeded(int regsAlreadyReserved, List<Insn> insns, Map<Insn, Stmt> insnsStmtMap) { int regsNeeded = regsAlreadyReserved; // we only need regs that weren't reserved yet for (int i = 0; i < insns.size(); i++) { Insn insn = insns.get(i); if (insn instanceof AddressInsn) { continue; // needs no regs/fitting } // first try to find a better opcode Insn fittingInsn = findFittingInsn(insn); if (fittingInsn != null) { // use the fitting instruction and continue with next one insns.set(i, fittingInsn); insnsStmtMap.put(fittingInsn, insnsStmtMap.get(insn)); insnsStmtMap.remove(insn); continue; } // no fitting instruction -> save if we need more registers int newRegsNeeded = insn.getMinimumRegsNeeded(); if (newRegsNeeded > regsNeeded) { regsNeeded = newRegsNeeded; } } return regsNeeded; }
/** * Array Length local for example a.length w/o brackets gets length * of array */ private soot.Local getSpecialArrayLengthLocal(polyglot.ast.Field field) { soot.Local localField; polyglot.ast.Receiver receiver = field.target(); if (receiver instanceof polyglot.ast.Local) { localField = getLocal((polyglot.ast.Local)receiver); } else if (receiver instanceof polyglot.ast.Expr){ localField = (soot.Local)base().createAggressiveExpr((polyglot.ast.Expr)receiver, false, false); } else { localField = generateLocal(receiver.type()); } soot.jimple.LengthExpr lengthExpr = soot.jimple.Jimple.v().newLengthExpr(localField); soot.Local retLocal = lg.generateLocal(soot.IntType.v()); soot.jimple.Stmt assign = soot.jimple.Jimple.v().newAssignStmt(retLocal, lengthExpr); body.getUnits().add(assign); Util.addLnPosTags(assign, field.position()); Util.addLnPosTags(lengthExpr.getOpBox(), field.target().position()); return retLocal; }
public static int getOutWordCount(Collection<Unit> units) { int outWords = 0; for (Unit u : units) { Stmt stmt = (Stmt) u; if (stmt.containsInvokeExpr()) { int wordsForParameters = 0; InvokeExpr invocation = stmt.getInvokeExpr(); List<Value> args = invocation.getArgs(); for (Value arg : args) { wordsForParameters += getDexWords(arg.getType()); } if (!invocation.getMethod().isStatic()) { wordsForParameters++; // extra word for "this" } if (wordsForParameters > outWords) { outWords = wordsForParameters; } } } return outWords; }
/** * @param args */ public static void main(String[] args) { PackManager.v().getPack("jtp").add(new Transform("jtp.fixedie", new BodyTransformer() { @Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for(Unit u: b.getUnits()) { Stmt s = (Stmt) u; if(s.containsInvokeExpr()) { InvokeExpr ie = s.getInvokeExpr(); if(FixedMethods.isFixed(ie)) { System.err.println("+++ "+ie); yes++; } else { System.err.println(" - "+ie); no++; } } } } })); soot.Main.main(args); System.err.println("+++ "+yes); System.err.println(" - "+no); }
@Override public Set<Abstraction> getTaintedValues(Stmt call, Abstraction source, Value[] params){ //check some evaluated methods: //arraycopy: //arraycopy(Object src, int srcPos, Object dest, int destPos, int length) //Copies an array from the specified source array, beginning at the specified position, //to the specified position of the destination array. if(call.getInvokeExpr().getMethod().toString().contains("arraycopy")) if(params[0].equals(source.getAccessPath().getPlainValue())) { Abstraction abs = source.deriveNewAbstraction(params[2], false, call, source.getAccessPath().getBaseType()); abs.setCorrespondingCallSite(call); return Collections.singleton(abs); } return Collections.emptySet(); }
private void collect_constraints_1_2() { ConstraintCollectorBV collector = new ConstraintCollectorBV(this, true); for( Iterator<Unit> stmtIt = stmtBody.getUnits().iterator(); stmtIt.hasNext(); ) { final Stmt stmt = (Stmt) stmtIt.next(); if(DEBUG) { G.v().out.print("stmt: "); } collector.collect(stmt, stmtBody); if(DEBUG) { G.v().out.println(stmt); } } }
@Override public void isParamVulnAndStore(SootMethod originMethod, Stmt originStmt, Value reachedValue) { //avoid sideeffect //constant already guaranteed by caller System.out.println(originStmt); String funcSig = originStmt.getInvokeExpr().getMethod().getSignature(); String valueString = reachedValue.toString(); if (evaluateResult(funcSig, valueString)) { if(DEBUG) { System.out.println("result found"); System.out.println("originstmt: " + originStmt + " reachedValue: " + reachedValue); } this.results.add(new Pair<>(originMethod, new Pair<>(originStmt, valueString))); } if(DEBUG) { if (reachedValue instanceof Constant || reachedValue instanceof StaticFieldRef) { System.out.println("originstmt: " + originStmt + " reachedValue: " + reachedValue); } } }
private void prepareHandlerPostDelayed(Body body, Stmt invokeStmt, SootMethodRef reportRef) { InvokeExpr expr = invokeStmt.getInvokeExpr(); Value oldValue = expr.getArg(1); Value newValue = LongConstant.v(2000L); expr.setArg(1, newValue); // Report the change InvokeStmt reportStmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr( reportRef, oldValue, newValue)); reportStmt.addTag(new InstrumentedCodeTag()); body.getUnits().insertAfter(reportStmt, invokeStmt); }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Check for calls to DexFile.loadClass for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Stmt stmt = (Stmt) unitIt.next(); if (stmt.hasTag(InstrumentedCodeTag.name)) continue; if (!(stmt instanceof AssignStmt)) continue; AssignStmt assignStmt = (AssignStmt) stmt; if (stmt.containsInvokeExpr()) { InvokeExpr iexpr = stmt.getInvokeExpr(); if (iexpr.getMethod() == methodDexFileLoadClass) { List<Value> args = new ArrayList<>(); args.add(((InstanceInvokeExpr) iexpr).getBase()); args.addAll(iexpr.getArgs()); InvokeExpr newLoadExpr = Jimple.v().newStaticInvokeExpr(methodOwnLoader.makeRef(), args); b.getUnits().swapWith(stmt, Jimple.v().newAssignStmt(assignStmt.getLeftOp(), newLoadExpr)); } } } }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Make a reference to the tracker method SootMethodRef ref = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CODE_POSITIONS), "setLastExecutedStatement", Collections.<Type>singletonList(IntType.v()), VoidType.v(), true); final String methodSig = b.getMethod().getSignature(); // Iterate over all the units and add a unit that sets the current // execution pointer int curLineNum = 0; for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Unit curUnit = unitIt.next(); // If we're still inside the IdentityStmt block, there's nothing to // instrument if (curUnit instanceof IdentityStmt || // If this unit was instrumented by another transformer, there's nothing to instrument curUnit.hasTag(InstrumentedCodeTag.name)) continue; // Get the current code positions CodePosition codePos = codePositionManager.getCodePositionForUnit(curUnit, methodSig, curLineNum++, ((Stmt) curUnit).getJavaSourceStartLineNumber()); Stmt setCodePosStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(ref, IntConstant.v(codePos.getID()))); setCodePosStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertAfter(setCodePosStmt, curUnit); } }
private void instrumentEachBranchAccess(Body body, Unit unit){ SootClass sootClass = Scene.v().getSootClass( UtilInstrumenter.JAVA_CLASS_FOR_PATH_INSTRUMENTATION); // Create the method invocation SootMethod createAndAdd = sootClass.getMethod("reportConditionOutcomeSynchronous", Collections.<Type>singletonList(BooleanType.v())); StaticInvokeExpr sieThen = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(1)); StaticInvokeExpr sieElse = Jimple.v().newStaticInvokeExpr( createAndAdd.makeRef(), IntConstant.v(0)); Unit sieThenUnit = Jimple.v().newInvokeStmt(sieThen); sieThenUnit.addTag(new InstrumentedCodeTag()); Unit sieElseUnit = Jimple.v().newInvokeStmt(sieElse); sieElseUnit.addTag(new InstrumentedCodeTag()); //treatment of target statement ("true"-branch) IfStmt ifStmt = (IfStmt)unit; Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(sieThenUnit.toString()); body.getUnits().insertBefore(sieThenUnit, targetStmt); NopStmt nop = Jimple.v().newNopStmt(); GotoStmt gotoNop = Jimple.v().newGotoStmt(nop); body.getUnits().insertBeforeNoRedirect(nop, targetStmt); body.getUnits().insertBeforeNoRedirect(gotoNop, sieThenUnit); } //treatment of "else"-branch body.getUnits().insertAfter(sieElseUnit, unit); }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { // Do not instrument methods in framework classes if (!canInstrumentMethod(b.getMethod())) return; // Create method references final SootMethodRef targetReachedRef = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CODE_POSITIONS), "reportTargetReachedSynchronous", Collections.<Type>emptyList(), VoidType.v(), true); // Iterate over the method and find calls to the target methods for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext(); ) { Stmt stmt = (Stmt) unitIt.next(); if(targetSignatures.contains(stmt)){ // Notify the server that the target was reached Stmt reachedStmt = Jimple.v().newInvokeStmt( Jimple.v().newStaticInvokeExpr(targetReachedRef)); reachedStmt.addTag(new InstrumentedCodeTag()); b.getUnits().insertBefore(reachedStmt, stmt); } } }
private void instrumentEachBranchAccess(Body body, IfStmt ifStmt){ String methodSignature = body.getMethod().getSignature(); String condition = ifStmt.getCondition().toString(); Unit generatedJimpleCodeForBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), StringConstant.v(condition), RefType.v("java.lang.String"), NullConstant.v() ); generatedJimpleCodeForBranch.addTag(new InstrumentedCodeTag()); Unit generatedJimpleCodeThenBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), NullConstant.v(), RefType.v("java.lang.String"), StringConstant.v("then branch") ); generatedJimpleCodeThenBranch.addTag(new InstrumentedCodeTag()); Unit generatedJimpleCodeElseBranch = UtilInstrumenter.makeJimpleStaticCallForPathExecution("logInfoAboutBranchAccess", RefType.v("java.lang.String"), StringConstant.v(methodSignature), RefType.v("java.lang.String"), NullConstant.v(), RefType.v("java.lang.String"), StringConstant.v("else branch") ); generatedJimpleCodeElseBranch.addTag(new InstrumentedCodeTag()); body.getUnits().insertBefore(generatedJimpleCodeForBranch, ifStmt); //treatment of target statement ("true"-branch) Stmt targetStmt = ifStmt.getTarget(); if(!branchTargetStmt.contains(targetStmt.toString())) { branchTargetStmt.add(generatedJimpleCodeThenBranch.toString()); body.getUnits().insertBefore(generatedJimpleCodeThenBranch, targetStmt); } //treatment of "else"-branch body.getUnits().insertAfter(generatedJimpleCodeElseBranch, ifStmt); }
@Override protected void internalTransform(String phaseName, Map<String, String> options) { // Make a reference to the registration method SootMethodRef ref = Scene.v().makeMethodRef( Scene.v().getSootClass(UtilInstrumenter.JAVA_CLASS_FOR_CRASH_REPORTING), "registerExceptionHandler", Collections.<Type>emptyList(), VoidType.v(), true); for (String sig : methodsToInstrument) { try{ SootMethod sm = Scene.v().grabMethod(sig); if(sm == null) continue; for (Iterator<Unit> unitIt = sm.getActiveBody().getUnits() .snapshotIterator(); unitIt.hasNext(); ) { Unit curUnit = unitIt.next(); // If we're still inside the IdentityStmt block, there's nothing to // instrument if (curUnit instanceof IdentityStmt) continue; // Put the registration in Stmt stmt = Jimple.v().newInvokeStmt(Jimple.v().newStaticInvokeExpr(ref)); stmt.addTag(new InstrumentedCodeTag()); sm.getActiveBody().getUnits().insertAfter(stmt, curUnit); break; } }catch(Exception ex) { ex.printStackTrace(); } } }