@Override public void onResultsAvailable( IInfoflowCFG cfg, InfoflowResults results) { // Dump the results if (results == null) { print("No results found."); } else { for (ResultSinkInfo sink : results.getResults().keySet()) { print("Found a flow to sink " + sink + ", from the following sources:"); for (ResultSourceInfo source : results.getResults().get(sink)) { print("\t- " + source.getSource() + " (in " + cfg.getMethodOf(source.getSource()).getSignature() + ")"); if (source.getPath() != null && !source.getPath().isEmpty()) print("\t\ton Path " + source.getPath()); } } } }
@Override public IInfoflowCFG buildBiDirICFG(CallgraphAlgorithm callgraphAlgorithm){ if (callgraphAlgorithm == CallgraphAlgorithm.OnDemand) { // Load all classes on the classpath to signatures long beforeClassLoading = System.nanoTime(); OnTheFlyJimpleBasedICFG.loadAllClassesOnClassPathToSignatures(); logger.info("Class loading took {} seconds", (System.nanoTime() - beforeClassLoading) / 1E9); long beforeHierarchy = System.nanoTime(); Scene.v().getOrMakeFastHierarchy(); assert Scene.v().hasFastHierarchy(); logger.info("Hierarchy building took {} seconds", (System.nanoTime() - beforeHierarchy) / 1E9); long beforeCFG = System.nanoTime(); IInfoflowCFG cfg = new InfoflowCFG(new OnTheFlyJimpleBasedICFG(Scene.v().getEntryPoints())); logger.info("CFG generation took {} seconds", (System.nanoTime() - beforeCFG) / 1E9); return cfg; } return new InfoflowCFG(); }
@Override public IAbstractionPathBuilder createPathBuilder(int maxThreadNum, IInfoflowCFG icfg) { switch (pathBuilder) { case Recursive : return new RecursivePathBuilder(icfg, maxThreadNum, reconstructPaths); case ContextSensitive : return new ContextSensitivePathBuilder(icfg, maxThreadNum, reconstructPaths); case ContextInsensitive : return new ContextInsensitivePathBuilder(icfg, maxThreadNum, reconstructPaths); case ContextInsensitiveSourceFinder : return new ContextInsensitiveSourceFinder(icfg, maxThreadNum); case None: return new EmptyPathBuilder(); } throw new RuntimeException("Unsupported path building algorithm"); }
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; }
@Override public void onResultsAvailable( IInfoflowCFG cfg, InfoflowResults results) { // Dump the results if (results == null) { print("No results found."); } else { Test.cfg = cfg; Test.results = results; for (ResultSinkInfo sink : results.getResults().keySet()) { print("Found a flow to sink " + sink + ", from the following sources:"); for (ResultSourceInfo source : results.getResults().get(sink)) { print("\t- " + source.getSource() + " (in " + cfg.getMethodOf(source.getSource()).getSignature() + ")"); if (source.getPath() != null) print("\t\ton Path " + Arrays.toString(source.getPath())); } } } }
public JimpleStmtVisitorImpl(Set<SourceSinkDefinition> sources, List<Stmt> jimpleDataFlowStatements, List<AccessPath> accessPathPath, Set<Unit> targetUnits, IInfoflowCFG cfg, Table<List<Stmt>, Stmt, List<List<String>>> splitAPIElementInfos) { this.exprVisitor = new JimpleExprVisitorImpl(sources, this); this.jimpleDataFlowStatements = jimpleDataFlowStatements; this.accessPathPath = accessPathPath; this.targetUnits = targetUnits; this.cfg = cfg; this.splitAPIElementInfos = splitAPIElementInfos; this.smtPrograms = new HashSet<SMTProgram>(); //initial adding of a single SMTProgram currentSMTProgram = new SMTProgram(); smtPrograms.add(currentSMTProgram); }
public static Unit getPostDominatorOfUnit(IInfoflowCFG cfg, Unit dataFlowStatement) { Map<Unit, Set<ControlFlowPath>> controlFlowPathsAtUnit = new HashMap<Unit, Set<ControlFlowPath>>(); Set<ControlFlowPath> currentPaths = new HashSet<ControlFlowPath>(); Stack<Unit> worklist = new Stack<Unit>(); worklist.add(dataFlowStatement); while(!worklist.isEmpty()) { Unit currentUnit = worklist.pop(); if(currentUnit.hasTag(InstrumentedCodeTag.name)) { List<Unit> successors = cfg.getSuccsOf(currentUnit); for(Unit nextUnit : successors) { if(proceedWithNextUnit(currentUnit, nextUnit, currentPaths, controlFlowPathsAtUnit)) { worklist.push(nextUnit); } } continue; } SootMethod currentMethod = cfg.getMethodOf(currentUnit); //this is a kind of hack: We excluded exception-edges here and also keep in mind that ALL dominator-algorithms are intra-procedural MHGPostDominatorsFinder<Unit> postdominatorFinder = new MHGPostDominatorsFinder<Unit>(new BriefUnitGraph(currentMethod.retrieveActiveBody())); Unit immediatePostDominator = postdominatorFinder.getImmediateDominator(currentUnit); while(immediatePostDominator.hasTag(InstrumentedCodeTag.name)) { immediatePostDominator = postdominatorFinder.getImmediateDominator(immediatePostDominator); } return immediatePostDominator; } return null; }
private static IfStmt findConditionalStatementForBooleanUnit(IInfoflowCFG cfg, Unit booleanUnit) { Stack<Unit> worklist = new Stack<Unit>(); Set<Unit> processedUnits = new HashSet<Unit>(); worklist.add(booleanUnit); while(!worklist.isEmpty()) { Unit currentUnit = worklist.pop(); //in case of a loop or recursion if(processedUnits.contains(currentUnit)) continue; processedUnits.add(currentUnit); //skip our own instrumented code if(currentUnit.hasTag(InstrumentedCodeTag.name)) continue; //we reached the condition if(currentUnit instanceof IfStmt) { return (IfStmt)currentUnit; } SootMethod methodOfBooleanUnit = cfg.getMethodOf(booleanUnit); DirectedGraph<Unit> graph = cfg.getOrCreateUnitGraph(methodOfBooleanUnit); //Comment: Steven said it should always be a UnitGraph + he will implement a more convenient way in the near future :-) UnitGraph unitGraph = (UnitGraph)graph; SimpleLocalDefs defs = new SimpleLocalDefs(unitGraph); SimpleLocalUses uses = new SimpleLocalUses(unitGraph, defs); List<UnitValueBoxPair> usesOfCurrentUnit = uses.getUsesOf(booleanUnit); for(UnitValueBoxPair valueBoxPair : usesOfCurrentUnit) worklist.add(valueBoxPair.getUnit()); } return null; }
public AnalysisContext(IInfoflowCFG icfg, BackwardsInfoflowCFG bwicfg, AnalysisEdgeFunctions<V> edgeFunc, IDebugger<V> debugger) { this.icfg = icfg; this.bwicfg = bwicfg; this.debugger = debugger; this.edgeFunc = edgeFunc; }
public Analysis(AnalysisProblem<V> problem, IInfoflowCFG icfg) { this.edgeFunc = problem.edgeFunctions(); this.problem = problem; this.icfg = icfg; this.bwicfg = new BackwardsInfoflowCFG(icfg); this.debugger = new NullDebugger<V>(); }
public Analysis(AnalysisProblem<V> problem, IInfoflowCFG icfg, IDebugger<V> debugger) { this.edgeFunc = problem.edgeFunctions(); this.problem = problem; this.icfg = icfg; this.bwicfg = new BackwardsInfoflowCFG(icfg); this.debugger = debugger; }
public BoomerangContext(IInfoflowCFG icfg, IInfoflowCFG bwicfg, BoomerangOptions options) { this.icfg = icfg; this.bwicfg = bwicfg; this.debugger = options.getDebugger(); this.budgetInMilliSeconds = options.getTimeBudget(); WrappedSootField.TRACK_TYPE = options.getTrackType(); WrappedSootField.TRACK_STMT = options.getTrackStatementsInFields(); this.trackStaticFields = options.getTrackStaticFields(); FW_SUMMARIES = new Summaries(this); BW_SUMMARIES = new Summaries(this); querycache = new ResultCache(); }
public String withMethodOfAllocationSite(IInfoflowCFG cfg) { StringBuilder sb = new StringBuilder(); sb.append("{"); for (Pair<Unit, AccessGraph> k : keySet()) { sb.append(k.getO1() + " in " + cfg.getMethodOf(k.getO1())); sb.append("="); sb.append(get(k)); } sb.append("}"); return "AliasResults: " + sb.toString(); }
public InfoflowProblem(IInfoflowCFG icfg, ISourceSinkManager sourceSinkManager, IAliasingStrategy aliasingStrategy) { super(icfg, sourceSinkManager); this.aliasingStrategy = aliasingStrategy; this.implicitFlowAliasingStrategy = new ImplicitFlowAliasStrategy(icfg); this.aliasing = new Aliasing(aliasingStrategy, icfg); }
/** * Creates a new instance of the {@link ContextSensitivePathBuilder} class * @param icfg The interprocedural control flow graph * @param maxThreadNum The maximum number of threads to use * @param reconstructPaths True if the exact propagation path between source * and sink shall be reconstructed. */ public ContextSensitivePathBuilder(IInfoflowCFG icfg, int maxThreadNum, boolean reconstructPaths) { super(icfg, reconstructPaths); int numThreads = Runtime.getRuntime().availableProcessors(); this.executor = createExecutor(maxThreadNum == -1 ? numThreads : Math.min(maxThreadNum, numThreads)); }
/** * Creates a new instance of the {@link RecursivePathBuilder} class * @param maxThreadNum The maximum number of threads to use * @param reconstructPaths True if the exact propagation path between source * and sink shall be reconstructed. */ public RecursivePathBuilder(IInfoflowCFG icfg, int maxThreadNum, boolean reconstructPaths) { super(icfg, reconstructPaths); int numThreads = Runtime.getRuntime().availableProcessors(); this.executor = createExecutor(maxThreadNum == -1 ? numThreads : Math.min(maxThreadNum, numThreads)); }
/** * Creates a new instance of the {@link ContextSensitivePathBuilder} class * @param maxThreadNum The maximum number of threads to use * @param reconstructPaths True if the exact propagation path between source * and sink shall be reconstructed. */ public ContextInsensitivePathBuilder(IInfoflowCFG icfg, int maxThreadNum, boolean reconstructPaths) { super(icfg, reconstructPaths); int numThreads = Runtime.getRuntime().availableProcessors(); this.executor = createExecutor(maxThreadNum == -1 ? numThreads : Math.min(maxThreadNum, numThreads)); }
/** * Creates a new instance of the {@link ContextInsensitiveSourceFinder} class * @param icfg The interprocedural control flow graph * @param maxThreadNum The maximum number of threads to use */ public ContextInsensitiveSourceFinder(IInfoflowCFG icfg, int maxThreadNum) { super(icfg, false); int numThreads = Runtime.getRuntime().availableProcessors(); this.executor = createExecutor(maxThreadNum == -1 ? numThreads : Math.min(maxThreadNum, numThreads)); }
private void getMethodsForSeedsIncremental(SootMethod sm, Set<SootMethod> doneSet, List<SootMethod> seeds, IInfoflowCFG icfg) { assert Scene.v().hasFastHierarchy(); if (!sm.isConcrete() || !sm.getDeclaringClass().isApplicationClass() || !doneSet.add(sm)) return; seeds.add(sm); for (Unit u : sm.retrieveActiveBody().getUnits()) { Stmt stmt = (Stmt) u; if (stmt.containsInvokeExpr()) for (SootMethod callee : icfg.getCalleesOfCallAt(stmt)) getMethodsForSeedsIncremental(callee, doneSet, seeds, icfg); } }
/** * Creates a new instance of the {@link InterproceduralConstantValuePropagator} * class * @param icfg The interprocedural control flow graph to use */ public InterproceduralConstantValuePropagator(IInfoflowCFG icfg) { this.icfg = icfg; this.excludedMethods = null; this.sourceSinkManager = null; this.taintWrapper = null; }
public SMTPreparationPhase(IInfoflowCFG cfg, InfoflowResults results) { this.cfg = cfg; this.results = results; }
private void standardDataFlowToSMTConvertion(ResultSourceInfo dataFlow, IInfoflowCFG cfg, Set<ResultSourceInfo> preparedDataFlowsForSMT, Table<Stmt, Integer, Set<String>> splitInfos) { SMTConverter converter = new SMTConverter(sources); for(int i = 0; i < dataFlow.getPath().length; i++) { System.out.println("\t" + dataFlow.getPath()[i]); System.out.println("\t\t" + dataFlow.getPathAccessPaths()[i]); } converter.convertJimpleToSMT(dataFlow.getPath(), dataFlow.getPathAccessPaths(), targetUnits, cfg, splitInfos); dataFlowsToSMTPrograms.put(new DataFlowObject(dataFlow.getPath()), converter.getSmtPrograms()); //dynamic value information dynamicValueInfos.putAll(converter.getDynamicValueInfos()); converter.printProgramToCmdLine(); File z3str2Script = new File(FrameworkOptions.Z3SCRIPT_LOCATION); if(!z3str2Script.exists()) throw new RuntimeException("There is no z3-script available"); SMTExecutor smtExecutor = new SMTExecutor(converter.getSmtPrograms(), z3str2Script); Set<File> smtFiles = smtExecutor.createSMTFile(); Set<Object> values = new HashSet<Object>(); for(File smtFile : smtFiles) { String loggingPointValue = smtExecutor.executeZ3str2ScriptAndExtractLoggingPointValue(smtFile); if(loggingPointValue != null) { loggingPointValue = fixSMTSolverIntegerOutput(loggingPointValue, dataFlow.getPath()[0]); //SMT solver only returns hex-based UTF-8 values in some cases; we fixed this with our own hexToUnicode converter if(loggingPointValue != null && loggingPointValue.contains("\\x")) addAdditionalUnicodeValue(loggingPointValue, values); if(loggingPointValue != null) values.add(loggingPointValue); System.out.println(String.format("Extracted loggingpoint-value: %s", loggingPointValue)); } } System.out.println("####################################"); //add values to fuzzy-seed Stmt stmt = dataFlow.getSource(); CodePosition position = codePositionManager.getCodePositionForUnit(stmt); if(constantBasedValuesToFuzz.containsKey(position.getID())) constantBasedValuesToFuzz.get(position.getID()).addAll(values); else constantBasedValuesToFuzz.put(position.getID(), values); }
private void splitAPI_DataFlowtoSMTConvertion(ResultSourceInfo dataFlow, IInfoflowCFG cfg, Set<ResultSourceInfo> preparedDataFlowsForSMT, Table<Stmt, Integer, Set<String>> splitInfos) { SMTConverter converter = new SMTConverter(sources); for(int i = 0; i < dataFlow.getPath().length; i++) { System.out.println("\t" + dataFlow.getPath()[i]); System.out.println("\t\t" + dataFlow.getPathAccessPaths()[i]); } //we remove the first statement (split-API method) int n = dataFlow.getPath().length-1; Stmt[] reducedDataFlow = new Stmt[n]; System.arraycopy(dataFlow.getPath(), 1, reducedDataFlow, 0, n); //currently only possible if there is a constant index for the array if(hasConstantIndexAtArrayForSplitDataFlow(reducedDataFlow)) { String valueOfInterest = getValueOfInterestForSplitDataflow(reducedDataFlow); converter.convertJimpleToSMT(reducedDataFlow, dataFlow.getPathAccessPaths(), targetUnits, cfg, null); converter.printProgramToCmdLine(); File z3str2Script = new File(FrameworkOptions.Z3SCRIPT_LOCATION); if(!z3str2Script.exists()) throw new RuntimeException("There is no z3-script available"); SMTExecutor smtExecutor = new SMTExecutor(converter.getSmtPrograms(), z3str2Script); Set<File> smtFiles = smtExecutor.createSMTFile(); for(File smtFile : smtFiles) { String loggingPointValue = smtExecutor.executeZ3str2ScriptAndExtractValue(smtFile, valueOfInterest); if(loggingPointValue != null) { Stmt splitStmt = dataFlow.getPath()[0]; int index = getConstantArrayIndexForSplitDataFlow(reducedDataFlow); if(splitInfos.contains(splitStmt, index)) splitInfos.get(splitStmt, index).add(loggingPointValue); else { Set<String> values = new HashSet<String>(); values.add(loggingPointValue); splitInfos.put(splitStmt, index, values); } } System.out.println(loggingPointValue); } System.out.println("####################################"); } }
public IInfoflowCFG icfg() { return icfg; }
public IInfoflowCFG icfg() { return (IInfoflowCFG) icfg; }
public AliasFinder(IInfoflowCFG cfg, BoomerangOptions options) { this(cfg, new BackwardsInfoflowCFG(cfg), options); }
public AliasFinder(IInfoflowCFG cfg, BackwardsInfoflowCFG bwcfg, BoomerangOptions options) { this.context = new BoomerangContext(cfg, bwcfg, options); }
public BoomerangEfficiencyDebugger(IInfoflowCFG icfg) { this.icfg = icfg; }
public BoomerangContext(IInfoflowCFG icfg, IInfoflowCFG bwicfg) { this(icfg, bwicfg, new BoomerangOptions()); }
public IInfoflowCFG getIcfg() { return icfg; }
public PtsBasedAliasStrategy(IInfoflowCFG cfg) { super(cfg); }
public FlowSensitiveAliasStrategy(IInfoflowCFG cfg, IInfoflowSolver backwardsSolver) { super(cfg); this.bSolver = backwardsSolver; }
public Aliasing(IAliasingStrategy aliasingStrategy, IInfoflowCFG cfg) { this.aliasingStrategy = aliasingStrategy; this.cfg = cfg; }
public ImplicitFlowAliasStrategy(IInfoflowCFG cfg) { super(cfg); }
public AbstractBulkAliasStrategy(IInfoflowCFG cfg) { super(cfg); }
public AbstractAliasStrategy(IInfoflowCFG cfg) { this.cfg = cfg; }
public IInfoflowCFG interproceduralCFG() { return this.cfg; }
@Override public IInfoflowCFG interproceduralCFG() { return (IInfoflowCFG) super.interproceduralCFG(); }
InfoflowManager(IInfoflowSolver forwardSolver, IInfoflowCFG icfg) { this.forwardSolver = forwardSolver; this.icfg = icfg; }
public IInfoflowCFG getiCfg() { return iCfg; }