private Collection<SootMethod> getMethodsForSeeds(IInfoflowCFG icfg) { List<SootMethod> seeds = new LinkedList<SootMethod>(); // If we have a callgraph, we retrieve the reachable methods. Otherwise, // we have no choice but take all application methods as an approximation if (Scene.v().hasCallGraph()) { List<MethodOrMethodContext> eps = new ArrayList<MethodOrMethodContext>(Scene.v().getEntryPoints()); ReachableMethods reachableMethods = new ReachableMethods(Scene.v().getCallGraph(), eps.iterator(), null); reachableMethods.update(); for (Iterator<MethodOrMethodContext> iter = reachableMethods.listener(); iter.hasNext();) seeds.add(iter.next().method()); } else { long beforeSeedMethods = System.nanoTime(); Set<SootMethod> doneSet = new HashSet<SootMethod>(); for (SootMethod sm : Scene.v().getEntryPoints()) getMethodsForSeedsIncremental(sm, doneSet, seeds, icfg); logger.info("Collecting seed methods took {} seconds", (System.nanoTime() - beforeSeedMethods) / 1E9); } return seeds; }
private Set<PathEdge<Unit, WrappedAccessGraph>> computeSeeds() { Set<PathEdge<Unit, WrappedAccessGraph>> seeds = new HashSet<>(); ReachableMethods rm = Scene.v().getReachableMethods(); QueueReader<MethodOrMethodContext> listener = rm.listener(); while (listener.hasNext()) { MethodOrMethodContext next = listener.next(); seeds.addAll(computeSeeds(next.method())); } return seeds; }
public MatcherTransition(State from, String methodMatcher, Parameter param, State to, Type type) { super(from, to); this.type = type; this.param = param; ReachableMethods methods = Scene.v().getReachableMethods(); QueueReader<MethodOrMethodContext> listener = methods.listener(); while (listener.hasNext()) { MethodOrMethodContext next = listener.next(); SootMethod method = next.method(); if (Pattern.matches(methodMatcher, method.getSignature())) { matchingMethods.add(method); } } }
private void analyzeRechableMethods(SootClass lifecycleElement, List<MethodOrMethodContext> methods) { ReachableMethods rm = new ReachableMethods(Scene.v().getCallGraph(), methods); rm.update(); // Scan for listeners in the class hierarchy Iterator<MethodOrMethodContext> reachableMethods = rm.listener(); while (reachableMethods.hasNext()) { SootMethod method = reachableMethods.next().method(); analyzeMethodForCallbackRegistrations(lifecycleElement, method); analyzeMethodForDynamicBroadcastReceiver(method); } }
public boolean mayHappenInParallel(CriticalSection tn1, CriticalSection tn2) { if(mhp == null) { if(optionLeaveOriginalLocks) return true; ReachableMethods rm = Scene.v().getReachableMethods(); if(!rm.contains(tn1.method) || !rm.contains(tn2.method)) return false; return true; } return mhp.mayHappenInParallel(tn1.method, tn2.method); }
@Override public void onAnalysisFinished(PathEdge<Unit, WrappedAccessGraph> seed, AnalysisSolver<TypestateDomainValue> solver) { ReachableMethods rm = Scene.v().getReachableMethods(); QueueReader<MethodOrMethodContext> listener = rm.listener(); while (listener.hasNext()) { MethodOrMethodContext next = listener.next(); SootMethod method = next.method(); if (!method.hasActiveBody()) continue; Collection<Unit> endPointsOf = solver.icfg().getEndPointsOf(method); for (Unit eP : endPointsOf) { Set<WrappedAccessGraph> localsAtEndPoint = new HashSet<>(); for (Cell<WrappedAccessGraph, WrappedAccessGraph, EdgeFunction<TypestateDomainValue>> cell : solver .getPathEdgesAt(eP)) { if (!cell.getRowKey().equals(InternalAnalysisProblem.ZERO)) { continue; } localsAtEndPoint.add(cell.getColumnKey()); } boolean escapes = false; for (WrappedAccessGraph ag : localsAtEndPoint) { if (BoomerangContext.isParameterOrThisValue(method, ag.getBase())) { escapes = true; } } if (!escapes) { Map<WrappedAccessGraph, TypestateDomainValue> resultAt = solver.resultsAt(eP); for (Entry<WrappedAccessGraph, TypestateDomainValue> fact : resultAt.entrySet()) { if (localsAtEndPoint.contains(fact.getKey())) { if (!fact.getValue().equals(solver.bottom())) endingPathsOfPropagation .put(method, fact.getKey().getDelegate(), fact.getValue()); } } } } } for (Cell<SootMethod, AccessGraph, TypestateDomainValue> res : endingPathsOfPropagation) { if (res.getValue().endsInErrorState()) { errorPathEdges.add(res); } } }
public void setReachableMethods( ReachableMethods rm ) { reachableMethods = rm; }
/** * 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; }
protected void getReachableMethodsFromThreads(Set<ThreadProperties> startedRunnables) { if(this.callGraph == null) { this.callGraph = Scene.v().getCallGraph(); } // Get reachable methods for all threads for(ThreadProperties threadProperties : startedRunnables) { Type classType = threadProperties.getRunnableType(); SootClass runnableClass = Scene.v().loadClassAndSupport(classType.toString()); for(SootMethod sootMethod : runnableClass.getMethods()) { // Only consider run() methods if(! (sootMethod.getDeclaration().equals("public void run()") || sootMethod.getDeclaration().equals("public static void main(java.lang.String[])"))) { continue; } threadProperties.setRunMethod(sootMethod); // Get directly reachable and transitive targets from this function ReachableMethods directTargets = new ReachableMethods(this.callGraph, new Targets(callGraph.edgesOutOf(sootMethod))); TransitiveTargets transitiveTargets = new TransitiveTargets(this.callGraph); Iterator<MethodOrMethodContext> transitiveIterator = transitiveTargets.iterator(sootMethod); while (transitiveIterator.hasNext()) { SootMethod transitiveTarget = (SootMethod) transitiveIterator.next(); // Show all target methods not in JDK if(!SusHelper.isPackageInJdk(SusHelper.getClassFromSignature(transitiveTarget.getSignature()))) { // This method is directly reachable from this run() if(directTargets.contains(transitiveTarget)) { threadProperties.addDirectReachableMethod(transitiveTarget); System.out.println(sootMethod + " may call " + transitiveTarget); } // This method is transitively reachable from this run() else { threadProperties.addTransitiveReachableMethod(transitiveTarget); System.out.println(sootMethod + " may reach " + transitiveTarget); } } } } } }
@Override public void print(PropagationSolver solver) { try { BufferedWriter writer = new BufferedWriter(new FileWriter(filePath)); String newLine = System.getProperty("line.separator"); List<MethodOrMethodContext> eps = new ArrayList<MethodOrMethodContext>(Scene.v().getEntryPoints()); ReachableMethods reachableMethods = new ReachableMethods(Scene.v().getCallGraph(), eps.iterator(), null); reachableMethods.update(); for (Iterator<MethodOrMethodContext> iter = reachableMethods.listener(); iter.hasNext();) { SootMethod ep = iter.next().method(); if (!ep.isConcrete() || !ep.hasActiveBody() // || ep.getName().contains("dummy") /* || Model.v().isExcludedClass(ep.getDeclaringClass().getName()) */) { continue; } writer.write(ep.getActiveBody() + newLine); writer.write("----------------------------------------------" + newLine); writer.write("At end of: " + ep.getSignature() + newLine); writer.write("Variables:" + newLine); writer.write("----------------------------------------------" + newLine); for (Unit ret : ep.getActiveBody().getUnits()) { for (Map.Entry<Value, BasePropagationValue> l : solver.resultsAt(ret).entrySet()) { Value symbol = l.getKey(); if (filter.filterOut(symbol)) { continue; } writer.write(symbol + " contains value " + l.getValue() + newLine); } writer.write("**" + ret + newLine); } } writer.close(); } catch (IOException e) { e.printStackTrace(); } }