private void dumpTextGraph(SootMethod caller, PrintStream printStream, int level) { String indent = indentString(level); caller.getTags(); printStream.printf("%s %s\n", indent, caller.toString()); Iterator<Edge> iterator = callGraph.edgesOutOf(caller); callgraphSet.add(caller); // boolean appClass = caller.getDeclaringClass().isApplicationClass(); boolean systemApi = API.v().isSystemMethod(caller); /* printStream.printf("%s Declaring method %s: app %s\n", indent, caller.toString(), systemApi? "False": "True"); */ String subindent = indentString(level + 1); Set<Object> calleeSet = new HashSet<Object>(); while (iterator != null && iterator.hasNext()) { Edge edge = iterator.next(); if (!systemApi) { List<Stmt> invokeStmtList = SootUtils.getInvokeStatements(caller, edge.tgt()); for (Stmt stmt : invokeStmtList) { if (calleeSet.contains(stmt)) continue; printStream.printf("%s #[%s] ", subindent, stmt); SourceLocationTag tag = SootUtils.getSourceLocation(stmt); if (tag != null) { printStream.printf(": %s", tag.toString()); } printStream.printf("\n"); calleeSet.add(stmt.toString()); } } if (!callgraphSet.contains(edge.tgt())) { dumpTextGraph(edge.tgt(), printStream, level + 1); } else { // already in the call graph, just print it out if (calleeSet.contains(edge.tgt())) continue; printStream.printf("%s %s\n", subindent, edge.tgt().toString()); calleeSet.add(edge.tgt()); } } }
/** Dumps out the call chain in json format * */ public void dump_json(PrintStream fp, String indent) { fp.printf("%s{ %s,\n", indent, json_field("type", type)); fp.printf("%s %s,\n", indent, json_field("link", link)); String sig = method.getSignature(); fp.printf("%s %s,\n", indent, json_field("signature", sig)); if (stmt != null) { SootMethodRef invoke = stmt.getInvokeExpr().getMethodRef(); String invokeSig; try { SootMethod concrete = SootUtils.resolve(stmt.getInvokeExpr().getMethodRef()); invokeSig = concrete.getSignature(); } catch (CannotFindMethodException e1) { logger.debug("Cannot find concrete method for {} in SourceCallChainInfo.dump_json()", stmt); invokeSig = invoke.getSignature(); } if (!invokeSig.equals(sig)) { fp.printf("%s %s,\n", indent, json_field("source-signature", invokeSig)); } } SourceLocationTag slt = (stmt == null) ? SootUtils.getMethodLocation(method) : getSourceLocation(stmt); if (slt != null) { fp.printf("%s %s", indent, json_field("src-loc")); fp.printf( "{ %s, %s},\n", json_field("class", slt.getClz()), json_field("line", slt.getLine())); } fp.printf("%s %s,\n", indent, json_field("syscalls", syscalls)); fp.printf("%s %s,\n", indent, json_field("calls", calls)); if ((contents != null) && (contents.length > 0)) { fp.printf("%s %s,\n", indent, json_field("score", score)); fp.printf("%s %s [\n", indent, json_field("contents")); String delim = ""; for (SourceCallChainInfo cci : contents) { fp.print(delim); delim = ",\n"; cci.dump_json(fp, indent + " "); } fp.printf("\n%s]}", indent); } else { fp.printf("%s %s\n", indent, json_field("score", score)); fp.printf("%s}", indent); } }