private static String reachableSinksSources() { StringBuffer buf = new StringBuffer(); Set<Stmt> sinks = new HashSet<Stmt>(); Set<Stmt> sources = new HashSet<Stmt>(); for (SootMethod method : CollaspedCallGraph.v().getAllMethods()) { for (CallToTarget apiCall : CollaspedCallGraph.v().getAPICallTargets(method)) { if (API.v().hasSourceInfoKind(apiCall.getTarget()) && InfoKind.callsSensitiveSource(apiCall.getStmt())) { sources.add(apiCall.getStmt()); } if (API.v().hasSinkInfoKind(apiCall.getTarget()) && InfoKind.callsSensitiveSink(apiCall.getStmt())) { sinks.add(apiCall.getStmt()); } } } buf.append("Total reachable sink call statments: " + sinks.size() + "\n"); buf.append("Total reachable source call statements: " + sources.size() + "\n"); return buf.toString(); }
private static String infoFlowResults() { Hierarchy hierarchy = Scene.v().getActiveHierarchy(); SootClass throwable = Scene.v().getSootClass("java.lang.Throwable"); StringBuffer buf = new StringBuffer(); // count number of flows // have to map it down to invoke statement because of context // key is invoke of sink -> sources Map<InvokeExpr, Set<Stmt>> invokeToSourcesMem = new HashMap<InvokeExpr, Set<Stmt>>(); // key is invoke of sink -> sources Map<InvokeExpr, Set<Stmt>> invokeToSourcesRec = new HashMap<InvokeExpr, Set<Stmt>>(); // key is invoke of sink -> sources Map<InvokeExpr, Set<Stmt>> invokeToSourcesArgs = new HashMap<InvokeExpr, Set<Stmt>>(); // key is invoke of sink -> sources Map<InvokeExpr, Set<Stmt>> invokeToSourcesArgsPrecise = new HashMap<InvokeExpr, Set<Stmt>>(); for (Map.Entry<Method, List<Method>> block : RCFGToSSL.v().getSpec().getEventBlocks().entrySet()) { // only count events in src classes, not in libraries boolean inSrc = false; for (IAllocNode recNode : block.getKey().getReceiverAllocNodes()) { if (recNode.getType() instanceof RefType) { SootClass clz = ((RefType) recNode.getType()).getSootClass(); if (Project.v().isSrcClass(clz)) { inSrc = true; break; } } } if (!inSrc) continue; for (Method oe : block.getValue()) { if (oe.getSinkInfoKinds().size() > 0 && oe.getSourcesInfoKinds().size() > 0) { // only count sensitive sinks Stmt sinkInvoke = JimpleRelationships.v().getEnclosingStmt(oe.getInvokeExpr()); if (!InfoKind.callsSensitiveSink(sinkInvoke)) continue; // we have a sink with connected sources InvokeExpr ie = oe.getInvokeExpr(); // get args for (int i = 0; i < oe.getNumArgs(); i++) { Type formalArgType = oe.getActualArgType(i); // ignore method arguments that have a declared type of throwable or a subclass of // throwable if (formalArgType instanceof RefType && !((RefType) formalArgType).getSootClass().isInterface() && hierarchy.isClassSubclassOfIncluding( ((RefType) formalArgType).getSootClass(), throwable)) continue; for (Map.Entry<InfoKind, Set<Stmt>> flows : oe.getArgSourceInfoUnitsConservative(i).entrySet()) { for (Stmt source : flows.getValue()) { if (InfoKind.callsSensitiveSource(source)) { if (!invokeToSourcesArgs.containsKey(ie)) { invokeToSourcesArgs.put(ie, new HashSet<Stmt>()); } invokeToSourcesArgs.get(ie).add(source); } } } for (Map.Entry<InfoKind, Set<Stmt>> flows : oe.getArgSourceInfoUnitsPrecise(i).entrySet()) { for (Stmt source : flows.getValue()) { if (InfoKind.callsSensitiveSource(source)) { if (!invokeToSourcesArgsPrecise.containsKey(ie)) { invokeToSourcesArgsPrecise.put(ie, new HashSet<Stmt>()); } invokeToSourcesArgsPrecise.get(ie).add(source); } } } } // get receiver for (Map.Entry<InfoKind, Set<Stmt>> flows : oe.getReceiverSourceInfoUnits().entrySet()) { // ignore all non-critical flows for (Stmt source : flows.getValue()) { if (InfoKind.callsSensitiveSource(source)) { if (!invokeToSourcesRec.containsKey(ie)) { invokeToSourcesRec.put(ie, new HashSet<Stmt>()); } invokeToSourcesRec.get(ie).add(source); } } } // get method accesses for (Map.Entry<InfoKind, Set<Stmt>> flows : oe.getMethodInfoUnits().entrySet()) { // ignore all non-critical flows for (Stmt source : flows.getValue()) { if (InfoKind.callsSensitiveSource(source)) { if (!invokeToSourcesMem.containsKey(ie)) { invokeToSourcesMem.put(ie, new HashSet<Stmt>()); } invokeToSourcesMem.get(ie).add(source); } } } } } } // count number of flows int flowsIntoSinksArgs = 0; int flowsIntoSinksArgsPrecise = 0; int flowsIntoSinksMem = 0; int flowsIntoSinksRec = 0; try { for (Map.Entry<InvokeExpr, Set<Stmt>> sink : invokeToSourcesArgs.entrySet()) { flowsIntoSinksArgs += sink.getValue().size(); } for (Map.Entry<InvokeExpr, Set<Stmt>> sink : invokeToSourcesArgsPrecise.entrySet()) { flowsIntoSinksArgsPrecise += sink.getValue().size(); } for (Map.Entry<InvokeExpr, Set<Stmt>> sink : invokeToSourcesMem.entrySet()) { flowsIntoSinksMem += sink.getValue().size(); } for (Map.Entry<InvokeExpr, Set<Stmt>> sink : invokeToSourcesRec.entrySet()) { flowsIntoSinksRec += sink.getValue().size(); } } catch (Exception e) { } buf.append("Info Flow Time Sec: " + infoFlowTimeSec + "\n"); buf.append("Flows into sinks (Args): " + flowsIntoSinksArgs + "\n"); buf.append("Flows into sinks (Args, Precise): " + flowsIntoSinksArgsPrecise + "\n"); buf.append("Flows into sinks (Mem): " + flowsIntoSinksMem + "\n"); buf.append("Flows into sinks (Rec): " + flowsIntoSinksRec + "\n"); buf.append(reachableSinksSources()); return buf.toString(); }