public String getSootClassPath() { if (sootClassPath == null) { String optionscp = Options.v().soot_classpath(); if (optionscp.length() > 0) sootClassPath = optionscp; String defaultSootClassPath = defaultClassPath(); // if no classpath is given on the command line, take the default if (sootClassPath == null) { sootClassPath = defaultSootClassPath; } else { // if one is given... if (Options.v().prepend_classpath()) { // if the prepend flag is set, append the default classpath sootClassPath += File.pathSeparator + defaultSootClassPath; } // else, leave it as it is } // add process-dirs List<String> process_dir = Options.v().process_dir(); StringBuffer pds = new StringBuffer(); for (String path : process_dir) { if (!sootClassPath.contains(path)) { pds.append(path); pds.append(File.pathSeparator); } } sootClassPath = pds + sootClassPath; } return sootClassPath; }
/** * Load the set of classes that soot needs, including those specified on the command-line. This is * the standard way of initialising the list of classes soot should use. */ public void loadNecessaryClasses() { loadBasicClasses(); for (String name : Options.v().classes()) { loadNecessaryClass(name); } loadDynamicClasses(); if (Options.v().oaat()) { if (Options.v().process_dir().isEmpty()) { throw new IllegalArgumentException( "If switch -oaat is used, then also -process-dir must be given."); } } else { for (final String path : Options.v().process_dir()) { for (String cl : SourceLocator.v().getClassesUnder(path)) { SootClass theClass = loadClassAndSupport(cl); theClass.setApplicationClass(); } } } prepareClasses(); setDoneResolving(); }
public void setMainClassFromOptions() { if (mainClass != null) return; if (Options.v().main_class() != null && Options.v().main_class().length() > 0) { setMainClass(getSootClass(Options.v().main_class())); } else { // try to infer a main class from the command line if none is given for (Iterator<String> classIter = Options.v().classes().iterator(); classIter.hasNext(); ) { SootClass c = getSootClass(classIter.next()); if (c.declaresMethod( "main", Collections.<Type>singletonList(ArrayType.v(RefType.v("java.lang.String"), 1)), VoidType.v())) { G.v().out.println("No main class given. Inferred '" + c.getName() + "' as main class."); setMainClass(c); return; } } // try to infer a main class from the usual classpath if none is given for (Iterator<SootClass> classIter = getApplicationClasses().iterator(); classIter.hasNext(); ) { SootClass c = (SootClass) classIter.next(); if (c.declaresMethod( "main", Collections.<Type>singletonList(ArrayType.v(RefType.v("java.lang.String"), 1)), VoidType.v())) { G.v().out.println("No main class given. Inferred '" + c.getName() + "' as main class."); setMainClass(c); return; } } } }
/* Generate classes to process, adding or removing package marked by * command line options. */ private void prepareClasses() { // Remove/add all classes from packageInclusionMask as per -i option Chain<SootClass> processedClasses = new HashChain<SootClass>(); while (true) { Chain<SootClass> unprocessedClasses = new HashChain<SootClass>(getClasses()); unprocessedClasses.removeAll(processedClasses); if (unprocessedClasses.isEmpty()) break; processedClasses.addAll(unprocessedClasses); for (SootClass s : unprocessedClasses) { if (s.isPhantom()) continue; if (Options.v().app()) { s.setApplicationClass(); } if (Options.v().classes().contains(s.getName())) { s.setApplicationClass(); continue; } if (s.isApplicationClass() && isExcluded(s)) { s.setLibraryClass(); } if (isIncluded(s)) { s.setApplicationClass(); } if (s.isApplicationClass()) { // make sure we have the support loadClassAndSupport(s.getName()); } } } }
@Override public void execute() throws MojoExecutionException { G.reset(); String classpath = getCompileClasspath(); getLog().info(String.format("Using transform classpath: %s", classpath)); Options.v().set_soot_classpath(classpath); Options.v().set_process_dir(asList(getProcessDirectory())); Options.v().set_output_dir(getOutputDirectory()); SimulationTransform.main(null); }
@BeforeClass public static void initializeSoot() throws IOException { soot.G.reset(); Options.v().set_output_format(Options.output_format_jimple); Options.v().set_include_all(true); Options.v().set_print_tags_in_output(true); Options.v().set_allow_phantom_refs(true); Options.v() .set_soot_classpath( System.getProperty("sun.boot.class.path") + ":" + System.getProperty("java.class.path")); Scene.v().loadNecessaryClasses(); }
/** * Traverse the statements in the given body, looking for aggregation possibilities; that is, * given a def d and a use u, d has no other uses, u has no other defs, collapse d and u. * * <p>option: only-stack-locals; if this is true, only aggregate variables starting with $ */ protected void internalTransform(Body b, String phaseName, Map<String, String> options) { StmtBody body = (StmtBody) b; boolean onlyStackVars = PhaseOptions.getBoolean(options, "only-stack-locals"); int aggregateCount = 1; if (Options.v().time()) Timers.v().aggregationTimer.start(); boolean changed = false; Map<ValueBox, Zone> boxToZone = new HashMap<ValueBox, Zone>(body.getUnits().size() * 2 + 1, 0.7f); // Determine the zone of every box { Zonation zonation = new Zonation(body); for (Unit u : body.getUnits()) { Zone zone = zonation.getZoneOf(u); for (ValueBox box : u.getUseBoxes()) { boxToZone.put(box, zone); } for (ValueBox box : u.getDefBoxes()) { boxToZone.put(box, zone); } } } do { if (Options.v().verbose()) G.v() .out .println( "[" + body.getMethod().getName() + "] Aggregating iteration " + aggregateCount + "..."); // body.printTo(new java.io.PrintWriter(G.v().out, true)); changed = internalAggregate(body, boxToZone, onlyStackVars); aggregateCount++; } while (changed); if (Options.v().time()) Timers.v().aggregationTimer.end(); }
/** * Prints out the method corresponding to b Body, (declaration and body), in the textual format * corresponding to the IR used to encode b body. * * @param out a PrintWriter instance to print to. */ private void printTo(Body b, PrintWriter out) { b.validate(); String decl = b.getMethod().getDavaDeclaration(); { out.println(" " + decl); for (Iterator<Tag> tIt = b.getMethod().getTags().iterator(); tIt.hasNext(); ) { final Tag t = tIt.next(); if (Options.v().print_tags_in_output()) { out.println(t); } } out.println(" {"); /* The locals are now printed out from within the toString method of ASTMethodNode Nomair A Naeem 10-MARCH-2005 */ // printLocalsInBody(b, out); } printStatementsInBody(b, out); out.println(" }"); }
/** * Constructs a BriefUnitGraph given a Body instance. * * @param body The underlying body we want to make a graph for. */ public BriefUnitGraph(Body body) { super(body); int size = unitChain.size(); if (Options.v().time()) Timers.v().graphTimer.start(); unitToSuccs = new HashMap(size * 2 + 1, 0.7f); unitToPreds = new HashMap(size * 2 + 1, 0.7f); buildUnexceptionalEdges(unitToSuccs, unitToPreds); makeMappedListsUnmodifiable(unitToSuccs); makeMappedListsUnmodifiable(unitToPreds); buildHeadsAndTails(); if (Options.v().time()) Timers.v().graphTimer.end(); }
private void initialize(Map<String, String> options) { if (drawer == null) { drawer = new CFGToDotGraph(); drawer.setBriefLabels(PhaseOptions.getBoolean(options, briefLabelOptionName)); drawer.setOnePage(!PhaseOptions.getBoolean(options, multipageOptionName)); drawer.setUnexceptionalControlFlowAttr("color", "black"); drawer.setExceptionalControlFlowAttr("color", "red"); drawer.setExceptionEdgeAttr("color", "lightgray"); drawer.setShowExceptions(Options.v().show_exception_dests()); ir = CFGIntermediateRep.getIR(PhaseOptions.getString(options, irOptionName)); graphtype = CFGGraphType.getGraphType(PhaseOptions.getString(options, graphTypeOptionName)); AltClassLoader.v().setAltClassPath(PhaseOptions.getString(options, altClassPathOptionName)); AltClassLoader.v() .setAltClasses( new String[] { "soot.toolkits.graph.ArrayRefBlockGraph", "soot.toolkits.graph.Block", "soot.toolkits.graph.Block$AllMapTo", "soot.toolkits.graph.BlockGraph", "soot.toolkits.graph.BriefBlockGraph", "soot.toolkits.graph.BriefUnitGraph", "soot.toolkits.graph.CompleteBlockGraph", "soot.toolkits.graph.CompleteUnitGraph", "soot.toolkits.graph.TrapUnitGraph", "soot.toolkits.graph.UnitGraph", "soot.toolkits.graph.ZonedBlockGraph", }); } }
/** * Returns the {@link ThrowAnalysis} to be used by default when constructing CFGs which include * exceptional control flow. * * @return the default {@link ThrowAnalysis} */ public ThrowAnalysis getDefaultThrowAnalysis() { if (defaultThrowAnalysis == null) { int optionsThrowAnalysis = Options.v().throw_analysis(); switch (optionsThrowAnalysis) { case Options.throw_analysis_pedantic: defaultThrowAnalysis = PedanticThrowAnalysis.v(); break; case Options.throw_analysis_unit: defaultThrowAnalysis = UnitThrowAnalysis.v(); break; default: throw new IllegalStateException( "Options.v().throw_analysi() == " + Options.v().throw_analysis()); } } return defaultThrowAnalysis; }
// This method is deprecated. Use soot.util.JasminOutputStream instead. public void writeXXXDeprecated(SootClass cl, String outputDir) { String outputDirWithSep = ""; if (!outputDir.equals("")) outputDirWithSep = outputDir + fileSeparator; try { File tempFile = new File(outputDirWithSep + cl.getName() + ".jasmin"); FileOutputStream streamOut = new FileOutputStream(tempFile); PrintWriter writerOut = new PrintWriter(new EscapedWriter(new OutputStreamWriter(streamOut))); if (cl.containsBafBody()) new soot.baf.JasminClass(cl).print(writerOut); else new soot.jimple.JasminClass(cl).print(writerOut); writerOut.close(); if (Options.v().time()) Timers.v().assembleJasminTimer.start(); // Invoke jasmin { String[] args; if (outputDir.equals("")) { args = new String[1]; args[0] = cl.getName() + ".jasmin"; } else { args = new String[3]; args[0] = "-d"; args[1] = outputDir; args[2] = outputDirWithSep + cl.getName() + ".jasmin"; } jasmin.Main.main(args); } tempFile.delete(); if (Options.v().time()) Timers.v().assembleJasminTimer.end(); } catch (IOException e) { throw new RuntimeException("Could not produce new classfile! (" + e + ")"); } }
public static void main(String[] args) { if (args.length == 0) { System.out.println("Syntax: java Main -app <main_classfile> [soot options]"); System.exit(0); } PackManager.v().getPack("wjtp").add(new Transform("wjtp.profiler", Evaluator.v())); // For the transformer to be executed, as it was added as one of // whole-program analysis, we need to set whole-program analysis to true. soot.options.Options.v().set_whole_program(true); // This is to skip analyzing the bodies of excluded classes (e.g., JDK). soot.options.Options.v().set_no_bodies_for_excluded(true); soot.Main.main(args); }
public static void printDbg(String s, Object... objects) { TODEX_DEBUG = Options.v().verbose(); if (TODEX_DEBUG) { for (Object o : objects) { s += o.toString(); } System.out.println(s); } }
private void determineExcludedPackages() { excludedPackages = new LinkedList<String>(); if (Options.v().exclude() != null) excludedPackages.addAll(Options.v().exclude()); // do not kill contents of the APK if we want a working new APK afterwards if (!Options.v().include_all() && Options.v().output_format() != Options.output_format_dex && Options.v().output_format() != Options.output_format_force_dex) { excludedPackages.add("java.*"); excludedPackages.add("sun.*"); excludedPackages.add("javax.*"); excludedPackages.add("com.sun.*"); excludedPackages.add("com.ibm.*"); excludedPackages.add("org.xml.*"); excludedPackages.add("org.w3c.*"); excludedPackages.add("apple.awt.*"); excludedPackages.add("com.apple.*"); } }
/** * Performs the work that is required to construct any sort of <tt>UnitGraph</tt>. * * @param body The body of the method for which to construct a control flow graph. */ protected UnitGraph(Body body) { this.body = body; unitChain = body.getUnits(); method = body.getMethod(); if (Options.v().verbose()) G.v() .out .println( "[" + method.getName() + "] Constructing " + this.getClass().getName() + "..."); }
public boolean isIncluded(SootClass sc) { String name = sc.getName(); for (String inc : (List<String>) Options.v().include()) { if (name.equals(inc) || ((inc.endsWith(".*") || inc.endsWith("$*")) && name.startsWith(inc.substring(0, inc.length() - 1)))) { return true; } } return false; }
/** * Call soot.Main.main(), which does command line argument processing and then starts the * transformation. This method should be called after calling initialize() and addTransforms(). * * @param args Soot command line arguments to be passed to soot.Main.main(). */ public void generateCode(String[] args) { // // This is rather ugly. The moml Class is not a Java class, so // // soot won't recognize it. However, if we give soot nothing, then // // it won't run. Note that later we will call setLibraryClass() on // // this class so that we don't actually generate code for it. // args[0] = "java.lang.Object"; // // As of soot 2.0.1, this is all that is required. // // soot.Main.main(args); if (!soot.options.Options.v().parse(args)) { throw new KernelRuntimeException("Option parse error"); } PackManager.v().getPack("wjtp").apply(); }
public void loadDynamicClasses() { dynamicClasses = new ArrayList<SootClass>(); HashSet<String> dynClasses = new HashSet<String>(); dynClasses.addAll(Options.v().dynamic_class()); for (Iterator<String> pathIt = Options.v().dynamic_dir().iterator(); pathIt.hasNext(); ) { final String path = (String) pathIt.next(); dynClasses.addAll(SourceLocator.v().getClassesUnder(path)); } for (Iterator<String> pkgIt = Options.v().dynamic_package().iterator(); pkgIt.hasNext(); ) { final String pkg = (String) pkgIt.next(); dynClasses.addAll(SourceLocator.v().classesInDynamicPackage(pkg)); } for (String className : dynClasses) { dynamicClasses.add(loadClassAndSupport(className)); } // remove non-concrete classes that may accidentally have been loaded for (Iterator<SootClass> iterator = dynamicClasses.iterator(); iterator.hasNext(); ) { SootClass c = iterator.next(); if (!c.isConcrete()) { if (Options.v().verbose()) { G.v() .out .println( "Warning: dynamic class " + c.getName() + " is abstract or an interface, and it will not be considered."); } iterator.remove(); } } }
private void printStatementsInBody(Body body, java.io.PrintWriter out) { if (Options.v().verbose()) System.out.println("Printing " + body.getMethod().getName()); Chain<Unit> units = ((DavaBody) body).getUnits(); if (units.size() != 1) { throw new RuntimeException("DavaBody AST doesn't have single root."); } UnitPrinter up = new DavaUnitPrinter((DavaBody) body); ((ASTNode) units.getFirst()).toString(up); out.print(up.toString()); }
/** * Computes the analysis given a UnitGraph computed from a method body. It is recommended that a * ExceptionalUnitGraph (or similar) be provided for correct results in the case of exceptional * control flow. * * @param g a graph on which to compute the analysis. * @see ExceptionalUnitGraph */ public SimpleLiveLocals(UnitGraph graph) { if (Options.v().time()) Timers.v().liveTimer.start(); if (Options.v().verbose()) G.v() .out .println( "[" + graph.getBody().getMethod().getName() + "] Constructing SimpleLiveLocals..."); SimpleLiveLocalsAnalysis analysis = new SimpleLiveLocalsAnalysis(graph); if (Options.v().time()) Timers.v().livePostTimer.start(); // Build unitToLocals map { unitToLocalsAfter = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f); unitToLocalsBefore = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f); Iterator unitIt = graph.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet set = (FlowSet) analysis.getFlowBefore(s); unitToLocalsBefore.put(s, Collections.unmodifiableList(set.toList())); set = (FlowSet) analysis.getFlowAfter(s); unitToLocalsAfter.put(s, Collections.unmodifiableList(set.toList())); } } if (Options.v().time()) Timers.v().livePostTimer.end(); if (Options.v().time()) Timers.v().liveTimer.end(); }
@BeforeClass public static void setUp() { Options.v().setPhaseOption("cg.spark", "on"); Options.v().setPhaseOption("jb.ulp", "off"); Options.v().set_output_format(Options.output_format_none); Options.v().set_prepend_classpath(true); // Options.v().set_no_bodies_for_excluded(true); Options.v().set_allow_phantom_refs(true); Options.v().set_whole_program(true); Options.v().set_soot_classpath(StringAnalysisTest.class.getResource("/").getPath()); Options.v() .set_process_dir( Arrays.asList( "edu.psu.cse.siis.coal.arguments.cases.StringProblems", "edu.psu.cse.siis.coal.arguments.cases.OtherClass")); SootClass class1 = Scene.v() .forceResolve("edu.psu.cse.siis.coal.arguments.cases.StringProblems", SootClass.BODIES); class1.setApplicationClass(); Scene.v().loadNecessaryClasses(); Scene.v().setEntryPoints(Collections.singletonList(class1.getMethodByName("main"))); if (USE_SHIMPLE) { Options.v().set_via_shimple(true); Options.v().set_whole_shimple(true); } String pack = USE_SHIMPLE ? "wstp" : "wjtp"; PackManager.v() .getPack(pack) .add(new Transform(pack + ".ExampleStringAnalyzer", new CustomSceneTransformer())); PackManager.v().runPacks(); result = CustomSceneTransformer.result; }
protected void internalTransform(Body body, String phaseName, Map options) { if (Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Tightening trap boundaries..."); Chain trapChain = body.getTraps(); Chain unitChain = body.getUnits(); if (trapChain.size() > 0) { ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body); for (Iterator trapIt = trapChain.iterator(); trapIt.hasNext(); ) { Trap trap = (Trap) trapIt.next(); Unit firstTrappedUnit = trap.getBeginUnit(); Unit firstTrappedThrower = null; Unit firstUntrappedUnit = trap.getEndUnit(); Unit lastTrappedUnit = (Unit) unitChain.getPredOf(firstUntrappedUnit); Unit lastTrappedThrower = null; for (Unit u = firstTrappedUnit; u != null && u != firstUntrappedUnit; u = (Unit) unitChain.getSuccOf(u)) { if (mightThrowTo(graph, u, trap)) { firstTrappedThrower = u; break; } } if (firstTrappedThrower != null) { for (Unit u = lastTrappedUnit; u != null; u = (Unit) unitChain.getPredOf(u)) { if (mightThrowTo(graph, u, trap)) { lastTrappedThrower = u; break; } } } if (firstTrappedThrower != null && firstTrappedUnit != firstTrappedThrower) { trap.setBeginUnit(firstTrappedThrower); } if (lastTrappedThrower == null) { lastTrappedThrower = firstTrappedUnit; } if (lastTrappedUnit != lastTrappedThrower) { trap.setEndUnit((Unit) unitChain.getSuccOf(lastTrappedThrower)); } } } }
private static void setOptions(String mainclass, boolean isJPF) { PhaseOptions.v().setPhaseOption("jb", "enabled:true"); PhaseOptions.v().setPhaseOption("tag.ln", "on"); Options.v().set_keep_line_number(true); Options.v().setPhaseOption("jb", "use-original-names:true"); Options.v().set_app(true); Options.v().set_whole_program(true); if (isJPF) { // Enable Spark HashMap<String, String> opt = new HashMap<String, String>(); // opt.put("verbose","true"); opt.put("propagator", "worklist"); opt.put("simple-edges-bidirectional", "false"); opt.put("on-fly-cg", "true"); opt.put("set-impl", "double"); opt.put("double-set-old", "hybrid"); opt.put("double-set-new", "hybrid"); opt.put("pre_jimplify", "true"); SparkTransformer.v().transform("", opt); PhaseOptions.v().setPhaseOption("cg.spark", "enabled:true"); Scene.v() .setSootClassPath( System.getProperty("sun.boot.class.path") + File.pathSeparator + System.getProperty("java.class.path")); } List excludes = new ArrayList(); excludes.add("org.eclipse."); excludes.add("javax."); excludes.add("java."); excludes.add("pt.tecnico."); Options.v().set_exclude(excludes); List includes = new ArrayList(); includes.add("org.apache.commons.pool."); // pool107 includes.add("org.apache.log4j."); // log4j_3 includes.add("org.apache.commons.lang."); // lang Options.v().set_include(includes); SootClass appclass = Scene.v().loadClassAndSupport(mainclass); try { Scene.v().setMainClass(appclass); Scene.v().getMainClass(); } catch (Exception e) { System.out.println(">> Exception [No main class]: " + e.getMessage()); } }
protected void internalTransform(String phaseName, Map options) { if (Options.v().verbose()) G.v().out.println("Transforming all classes in the Scene to Shimple..."); // *** FIXME: Add debug output to indicate which class/method is being shimplified. // *** FIXME: Is ShimpleTransformer the right solution? The call graph may deem // some classes unreachable. Iterator classesIt = Scene.v().getClasses().iterator(); while (classesIt.hasNext()) { SootClass sClass = (SootClass) classesIt.next(); if (sClass.isPhantom()) continue; Iterator methodsIt = sClass.getMethods().iterator(); while (methodsIt.hasNext()) { SootMethod method = (SootMethod) methodsIt.next(); if (!method.isConcrete()) continue; if (method.hasActiveBody()) { Body body = method.getActiveBody(); ShimpleBody sBody = null; if (body instanceof ShimpleBody) { sBody = (ShimpleBody) body; if (!sBody.isSSA()) sBody.rebuild(); } else { sBody = Shimple.v().newBody(body); } method.setActiveBody(sBody); } else { MethodSource ms = new ShimpleMethodSource(method.getSource()); method.setSource(ms); } } } }
SimpleLiveLocalsAnalysis(UnitGraph g) { super(g); if (Options.v().time()) Timers.v().liveSetupTimer.start(); emptySet = new ArraySparseSet(); // Create kill sets. { unitToKillSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f); Iterator unitIt = g.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet killSet = emptySet.clone(); Iterator boxIt = s.getDefBoxes().iterator(); while (boxIt.hasNext()) { ValueBox box = (ValueBox) boxIt.next(); if (box.getValue() instanceof Local) killSet.add(box.getValue(), killSet); } unitToKillSet.put(s, killSet); } } // Create generate sets { unitToGenerateSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f); Iterator unitIt = g.iterator(); while (unitIt.hasNext()) { Unit s = (Unit) unitIt.next(); FlowSet genSet = emptySet.clone(); Iterator boxIt = s.getUseBoxes().iterator(); while (boxIt.hasNext()) { ValueBox box = (ValueBox) boxIt.next(); if (box.getValue() instanceof Local) genSet.add(box.getValue(), genSet); } unitToGenerateSet.put(s, genSet); } } if (Options.v().time()) Timers.v().liveSetupTimer.end(); if (Options.v().time()) Timers.v().liveAnalysisTimer.start(); doAnalysis(); if (Options.v().time()) Timers.v().liveAnalysisTimer.end(); }
public static void main(String[] args) { List<String> argsList = new ArrayList<String>(Arrays.asList(args)); argsList.addAll( Arrays.asList( new String[] { "-w", // "-p", "cg.spark", "on-fly-cg:true", // "-main-class", "testers.CallGraphs",// main-class "testers.CallGraphs", // argument classes // "testers.A" // })); argsList.add("-soot-class-path"); argsList.add( "/home/nnguyen/workspaceluna/CoGConstructor/bin:/usr/java/jdk1.7.0_79/jre/lib/rt.jar:/usr/java/jdk1.7.0_79/jre/lib/jce.jar"); argsList.add("-p"); argsList.add("cg"); argsList.add("all-reachable:true"); argsList.add("-p"); argsList.add("cg.spark"); argsList.add("on-fly-cg:true"); argsList.add("-f"); argsList.add("J"); // argsList.add("-no-bodies-for-excluded"); // argsList.add("pre-jimplify:true"); System.out.println("JB " + PackManager.v().getPack("jb").getDefaultOptions()); System.out.println("JBLS " + PackManager.v().getPhase("jb.ls").getDefaultOptions()); System.out.println("JBDAE " + PackManager.v().getPhase("jb.dae").getDefaultOptions()); System.out.println("CHCHA " + PackManager.v().getPhase("cg.cha").getDeclaredOptions()); System.out.println("CG" + PackManager.v().getPack("cg").getDeclaredOptions()); // PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() { // // System.out.println(PackManager.v().getPhase("cg.spark").getDeclaredOptions()); // // // PackManager.v().getPack("cg").add(new Transform("cg.myTrans", new SceneTransformer() { // // @Override // protected void internalTransform(String phaseName, Map options) { // CHATransformer.v().transform(); // SootClass a = Scene.v().getSootClass("testers.A"); // // SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff"); // CallGraph cg = Scene.v().getCallGraph(); // // Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src)); // // while (targets.hasNext()) { // SootMethod tgt = (SootMethod) targets.next(); // System.out.println(src + " may call " + tgt); // } // // Iterator<MethodOrMethodContext> sources = new Sources(cg.edgesInto(src)); // // while (sources.hasNext()) { // SootMethod tgt = (SootMethod) sources.next(); // // System.out.println(src + " may be called by " + tgt + " " + tgt.getName()); // } // // } // // })); args = argsList.toArray(new String[0]); Options.v().parse(args); // disable if want to use soot.Main.main Options.v().set_keep_line_number(true); Options.v().set_whole_program(true); Options.v().set_allow_phantom_refs(true); Options.v().setPhaseOption("jb", "use-original-names:true"); // soot.Main.main(args); List addedEntryPoints = new ArrayList(); // for (String ePoint : customEntryPoints) { SootClass c = Scene.v().forceResolve("testers.CallGraphs", SootClass.BODIES); c.setApplicationClass(); Scene.v().loadNecessaryClasses(); SootMethod method; String methodName = "main"; if (!methodName.contains("(")) { method = c.getMethodByName(methodName); System.out.println("FOUND IT"); } else { // List<Type> types = new ArrayList<Type>(); method = c.getMethod(methodName); System.out.println("FOUND IT"); } addedEntryPoints.add(method); // } Scene.v().setEntryPoints(addedEntryPoints); PackManager.v().runPacks(); JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(); IFDSTabulationProblem< Unit, Pair<Value, Set<DefinitionStmt>>, SootMethod, InterproceduralCFG<Unit, SootMethod>> problem = (IFDSTabulationProblem) new IFDSReachingDefinitions(icfg); System.out.println("Number of threads :" + problem.numThreads()); JimpleIFDSSolver<Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>> solver = new JimpleIFDSSolver< Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>>( problem, true); System.out.println("Started Solving...."); System.out.println(Scene.v().getMainMethod().getName()); SootMethod mMethod = Scene.v().getSootClass("testers.CallGraphs").getMethodByName("main"); // SootMethod mMethod = Scene.v().getMainClass().getMethodByName("doStuff2"); BiDirICFGFactory icfgFactory = new DefaultBiDiICFGFactory(); IInfoflowCFG iCfg = icfgFactory.buildBiDirICFG(CallgraphAlgorithm.AutomaticSelection, true); CallGraph cg = Scene.v().getCallGraph(); // SootClass cl = Scene.v().getMainClass(); for (SootClass cl : Scene.v().getClasses()) { for (SootMethod sm : cl.getMethods()) { if (sm.getSignature().contains("testers") || sm.getSignature().contains("java.lang.Object next()")) { // if // (sm.getSignature().equals("<testers.CallGraphs$CellIterator: java.lang.Object // next()>")) // { // if (sm.getSignature().equals("<testers.CallGraphs: void p4(int)>")) { System.out.println( "WE FOUND " + sm.getSignature() + " AT " + sm.getJavaSourceStartLineNumber()); Iterator sources = new Sources(cg.edgesInto(sm)); while (sources.hasNext()) { SootMethod sm2 = (SootMethod) sources.next(); System.out.println("CALLED BY " + sm2.getSignature()); } // sources = new Sources(cg.edgesOutOf(sm)); // while (sources.hasNext()) { // SootMethod sm2 = (SootMethod) sources.next(); // System.out.println("CALLS " + sm2.getSignature()); // } // } } } } if (mMethod.hasActiveBody()) { System.out.println("YESSSSSSSSSSSSSSSSS"); Body b = mMethod.getActiveBody(); for (Unit u : b.getUnits()) { System.out.println(u + " AT " + u.getJavaSourceStartLineNumber()); } System.out.println("==================="); for (Unit u : b.getUnits()) { if (u instanceof IfStmt) { System.out.println("IF STMT AT " + u.getJavaSourceStartLineNumber()); IfStmt stmt = (IfStmt) u; System.out.println(u); Value condition = stmt.getCondition(); ValueBox conditionBox = stmt.getConditionBox(); System.out.println( "Condition " + condition + " AT " + conditionBox.getJavaSourceStartLineNumber()); System.out.println( "Target " + stmt.getTarget() + " AT " + stmt.getTarget().getJavaSourceStartLineNumber()); System.out.println( iCfg.getPostdominatorOf(u) + " AT " + u.getJavaSourceStartLineNumber()); System.out.println(iCfg.getSuccsOf(u)); System.out.println("====="); } if (u instanceof GotoStmt) { System.out.println("GOTO STMT AT " + u.getJavaSourceStartLineNumber()); GotoStmt stmt = (GotoStmt) u; System.out.println(u); System.out.println(stmt.getTarget()); System.out.println("====="); } } } // commented to test the IfStmt // if (!Scene.v().getMainMethod().hasActiveBody()) { // System.out.println("NONOOOOOOOOOOOOOOOOOOOOOOOOOOO"); // } // // Scene.v().getMainMethod().getActiveBody() // solver.solve(); // System.out.println("Completed Solving...."); // solver.dumpResults(); }
/** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */ private void printStatementsInBody( Body body, java.io.PrintWriter out, LabeledUnitPrinter up, UnitGraph unitGraph) { Chain units = body.getUnits(); Iterator unitIt = units.iterator(); Unit currentStmt = null, previousStmt; while (unitIt.hasNext()) { previousStmt = currentStmt; currentStmt = (Unit) unitIt.next(); // Print appropriate header. { // Put an empty line if the previous node was a branch node, the current node is a join node // or the previous statement does not have body statement as a successor, or if // body statement has a label on it if (currentStmt != units.getFirst()) { if (unitGraph.getSuccsOf(previousStmt).size() != 1 || unitGraph.getPredsOf(currentStmt).size() != 1 || up.labels().containsKey(currentStmt)) { up.newline(); } else { // Or if the previous node does not have body statement as a successor. List succs = unitGraph.getSuccsOf(previousStmt); if (succs.get(0) != currentStmt) { up.newline(); } } } if (up.labels().containsKey(currentStmt)) { up.unitRef(currentStmt, true); up.literal(":"); up.newline(); } if (up.references().containsKey(currentStmt)) { up.unitRef(currentStmt, false); } } up.startUnit(currentStmt); currentStmt.toString(up); up.endUnit(currentStmt); up.literal(";"); up.newline(); // only print them if not generating attributes files // because they mess up line number // if (!addJimpleLn()) { if (Options.v().print_tags_in_output()) { Iterator tagIterator = currentStmt.getTags().iterator(); while (tagIterator.hasNext()) { Tag t = (Tag) tagIterator.next(); up.noIndent(); up.literal("/*"); up.literal(t.toString()); up.literal("*/"); up.newline(); } /*Iterator udIt = currentStmt.getUseAndDefBoxes().iterator(); while (udIt.hasNext()) { ValueBox temp = (ValueBox)udIt.next(); Iterator vbtags = temp.getTags().iterator(); while (vbtags.hasNext()) { Tag t = (Tag) vbtags.next(); up.noIndent(); up.literal("VB Tag: "+t.toString()); up.newline(); } }*/ } } out.print(up.toString()); if (addJimpleLn()) { setJimpleLnNum(up.getPositionTagger().getEndLn()); } // Print out exceptions { Iterator trapIt = body.getTraps().iterator(); if (trapIt.hasNext()) { out.println(); incJimpleLnNum(); } while (trapIt.hasNext()) { Trap trap = (Trap) trapIt.next(); out.println( " catch " + Scene.v().quotedNameOf(trap.getException().getName()) + " from " + up.labels().get(trap.getBeginUnit()) + " to " + up.labels().get(trap.getEndUnit()) + " with " + up.labels().get(trap.getHandlerUnit()) + ";"); incJimpleLnNum(); } } }
public void printTo(SootClass cl, PrintWriter out) { // add jimple line number tags setJimpleLnNum(1); // Print class name + modifiers { StringTokenizer st = new StringTokenizer(Modifier.toString(cl.getModifiers())); while (st.hasMoreTokens()) { String tok = (String) st.nextToken(); if (cl.isInterface() && tok.equals("abstract")) continue; out.print(tok + " "); } String classPrefix = ""; if (!cl.isInterface()) { classPrefix = classPrefix + " class"; classPrefix = classPrefix.trim(); } out.print(classPrefix + " " + Scene.v().quotedNameOf(cl.getName()) + ""); } // Print extension { if (cl.hasSuperclass()) out.print(" extends " + Scene.v().quotedNameOf(cl.getSuperclass().getName()) + ""); } // Print interfaces { Iterator interfaceIt = cl.getInterfaces().iterator(); if (interfaceIt.hasNext()) { out.print(" implements "); out.print("" + Scene.v().quotedNameOf(((SootClass) interfaceIt.next()).getName()) + ""); while (interfaceIt.hasNext()) { out.print(","); out.print(" " + Scene.v().quotedNameOf(((SootClass) interfaceIt.next()).getName()) + ""); } } } out.println(); incJimpleLnNum(); /* if (!addJimpleLn()) { Iterator clTagsIt = cl.getTags().iterator(); while (clTagsIt.hasNext()) { final Tag t = (Tag)clTagsIt.next(); out.println(t); } }*/ out.println("{"); incJimpleLnNum(); if (Options.v().print_tags_in_output()) { Iterator cTagIterator = cl.getTags().iterator(); while (cTagIterator.hasNext()) { Tag t = (Tag) cTagIterator.next(); out.print("/*"); out.print(t.toString()); out.println("*/"); } } // Print fields { Iterator fieldIt = cl.getFields().iterator(); if (fieldIt.hasNext()) { while (fieldIt.hasNext()) { SootField f = (SootField) fieldIt.next(); if (f.isPhantom()) continue; if (Options.v().print_tags_in_output()) { Iterator fTagIterator = f.getTags().iterator(); while (fTagIterator.hasNext()) { Tag t = (Tag) fTagIterator.next(); out.print("/*"); out.print(t.toString()); out.println("*/"); } } out.println(" " + f.getDeclaration() + ";"); if (addJimpleLn()) { setJimpleLnNum(addJimpleLnTags(getJimpleLnNum(), f)); } // incJimpleLnNum(); } } } // Print methods { Iterator methodIt = cl.methodIterator(); if (methodIt.hasNext()) { if (cl.getMethodCount() != 0) { out.println(); incJimpleLnNum(); } while (methodIt.hasNext()) { SootMethod method = (SootMethod) methodIt.next(); if (method.isPhantom()) continue; if (!Modifier.isAbstract(method.getModifiers()) && !Modifier.isNative(method.getModifiers())) { if (!method.hasActiveBody()) throw new RuntimeException("method " + method.getName() + " has no active body!"); else if (Options.v().print_tags_in_output()) { Iterator mTagIterator = method.getTags().iterator(); while (mTagIterator.hasNext()) { Tag t = (Tag) mTagIterator.next(); out.print("/*"); out.print(t.toString()); out.println("*/"); } } printTo(method.getActiveBody(), out); if (methodIt.hasNext()) { out.println(); incJimpleLnNum(); } } else { if (Options.v().print_tags_in_output()) { Iterator mTagIterator = method.getTags().iterator(); while (mTagIterator.hasNext()) { Tag t = (Tag) mTagIterator.next(); out.print("/*"); out.print(t.toString()); out.println("*/"); } } out.print(" "); out.print(method.getDeclaration()); out.println(";"); incJimpleLnNum(); if (methodIt.hasNext()) { out.println(); incJimpleLnNum(); } } } } } out.println("}"); incJimpleLnNum(); }
/** * This method pushes all newExpr down to be the stmt directly before every invoke of the init * only if they are in the types list */ public void internalTransform(Body b, String phaseName, Map options) { JimpleBody body = (JimpleBody) b; if (Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors..."); Chain units = body.getUnits(); List<Unit> stmtList = new ArrayList<Unit>(); stmtList.addAll(units); Iterator<Unit> it = stmtList.iterator(); Iterator<Unit> nextStmtIt = stmtList.iterator(); // start ahead one nextStmtIt.next(); SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body); UnitGraph graph = localDefs.getGraph(); LocalUses localUses = new SimpleLocalUses(graph, localDefs); /* fold in NewExpr's with specialinvoke's */ while (it.hasNext()) { Stmt s = (Stmt) it.next(); if (!(s instanceof AssignStmt)) continue; /* this should be generalized to ArrayRefs */ // only deal with stmts that are an local = newExpr Value lhs = ((AssignStmt) s).getLeftOp(); if (!(lhs instanceof Local)) continue; Value rhs = ((AssignStmt) s).getRightOp(); if (!(rhs instanceof NewExpr)) continue; // check if very next statement is invoke --> // this indicates there is no control flow between // new and invoke and should do nothing if (nextStmtIt.hasNext()) { Stmt next = (Stmt) nextStmtIt.next(); if (next instanceof InvokeStmt) { InvokeStmt invoke = (InvokeStmt) next; if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) { SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr(); if (invokeExpr.getBase() == lhs) { break; } } } } // check if new is in the types list - only process these if (!types.contains(((NewExpr) rhs).getType())) continue; List lu = localUses.getUsesOf(s); Iterator luIter = lu.iterator(); boolean MadeNewInvokeExpr = false; while (luIter.hasNext()) { Unit use = ((UnitValueBoxPair) (luIter.next())).unit; if (!(use instanceof InvokeStmt)) continue; InvokeStmt is = (InvokeStmt) use; if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr) || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue; // make a new one here AssignStmt constructStmt = Jimple.v() .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp()); constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType())); MadeNewInvokeExpr = true; // redirect jumps use.redirectJumpsToThisTo(constructStmt); // insert new one here units.insertBefore(constructStmt, use); constructStmt.addTag(s.getTag("SourceLnPosTag")); } if (MadeNewInvokeExpr) { units.remove(s); } } }