Search in sources :

Example 6 with CallGraph

use of soot.jimple.toolkits.callgraph.CallGraph in project soot by Sable.

the class CallGraphExample method main.

public static void main(String[] args) {
    List<String> argsList = new ArrayList<String>(Arrays.asList(args));
    argsList.addAll(Arrays.asList(new String[] { "-w", "-main-class", // main-class
    "testers.CallGraphs", // argument classes
    "testers.CallGraphs", // 
    "testers.A" }));
    PackManager.v().getPack("wjtp").add(new Transform("wjtp.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);
            }
        }
    }));
    args = argsList.toArray(new String[0]);
    soot.Main.main(args);
}
Also used : CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ArrayList(java.util.ArrayList) SootMethod(soot.SootMethod) Targets(soot.jimple.toolkits.callgraph.Targets) Transform(soot.Transform) SootClass(soot.SootClass) MethodOrMethodContext(soot.MethodOrMethodContext) Map(java.util.Map) SceneTransformer(soot.SceneTransformer)

Example 7 with CallGraph

use of soot.jimple.toolkits.callgraph.CallGraph in project soot by Sable.

the class PurityAnalysis method internalTransform.

@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
    PurityOptions opts = new PurityOptions(options);
    logger.debug("[AM] Analysing purity");
    CallGraph cg = Scene.v().getCallGraph();
    // launch the analysis
    new PurityInterproceduralAnalysis(cg, Scene.v().getEntryPoints().iterator(), opts);
}
Also used : PurityOptions(soot.options.PurityOptions) CallGraph(soot.jimple.toolkits.callgraph.CallGraph)

Example 8 with CallGraph

use of soot.jimple.toolkits.callgraph.CallGraph in project soot by Sable.

the class LocalMustAliasAnalysis method trackableFields.

/**
 * 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;
}
Also used : EquivalentValue(soot.EquivalentValue) FieldRef(soot.jimple.FieldRef) Unit(soot.Unit) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ReachableMethods(soot.jimple.toolkits.callgraph.ReachableMethods) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ValueBox(soot.ValueBox) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) MethodOrMethodContext(soot.MethodOrMethodContext) HashSet(java.util.HashSet)

Example 9 with CallGraph

use of soot.jimple.toolkits.callgraph.CallGraph in project soot by Sable.

the class StaticMethodBinder method internalTransform.

protected void internalTransform(String phaseName, Map opts) {
    Filter instanceInvokesFilter = new Filter(new InstanceInvokeEdgesPred());
    SMBOptions options = new SMBOptions(opts);
    String modifierOptions = PhaseOptions.getString(opts, "allowed-modifier-changes");
    HashMap instanceToStaticMap = new HashMap();
    CallGraph cg = Scene.v().getCallGraph();
    Hierarchy hierarchy = Scene.v().getActiveHierarchy();
    Iterator classesIt = Scene.v().getApplicationClasses().iterator();
    while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        LinkedList methodsList = new LinkedList();
        for (Iterator it = c.methodIterator(); it.hasNext(); ) {
            methodsList.add(it.next());
        }
        while (!methodsList.isEmpty()) {
            SootMethod container = (SootMethod) methodsList.removeFirst();
            if (!container.isConcrete())
                continue;
            if (!instanceInvokesFilter.wrap(cg.edgesOutOf(container)).hasNext())
                continue;
            JimpleBody b = (JimpleBody) container.getActiveBody();
            List<Unit> unitList = new ArrayList<Unit>();
            unitList.addAll(b.getUnits());
            Iterator<Unit> unitIt = unitList.iterator();
            while (unitIt.hasNext()) {
                Stmt s = (Stmt) unitIt.next();
                if (!s.containsInvokeExpr())
                    continue;
                InvokeExpr ie = s.getInvokeExpr();
                if (ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr)
                    continue;
                Iterator targets = new Targets(instanceInvokesFilter.wrap(cg.edgesOutOf(s)));
                if (!targets.hasNext())
                    continue;
                SootMethod target = (SootMethod) targets.next();
                if (targets.hasNext())
                    continue;
                if (!AccessManager.ensureAccess(container, target, modifierOptions))
                    continue;
                if (!target.getDeclaringClass().isApplicationClass() || !target.isConcrete())
                    continue;
                // Don't modify java.lang.Object
                if (target.getDeclaringClass() == Scene.v().getSootClass("java.lang.Object"))
                    continue;
                if (!instanceToStaticMap.containsKey(target)) {
                    List newParameterTypes = new ArrayList();
                    newParameterTypes.add(RefType.v(target.getDeclaringClass().getName()));
                    newParameterTypes.addAll(target.getParameterTypes());
                    // Check for signature conflicts.
                    String newName = target.getName() + "_static";
                    while (target.getDeclaringClass().declaresMethod(newName, newParameterTypes, target.getReturnType())) newName = newName + "_static";
                    SootMethod ct = Scene.v().makeSootMethod(newName, newParameterTypes, target.getReturnType(), target.getModifiers() | Modifier.STATIC, target.getExceptions());
                    target.getDeclaringClass().addMethod(ct);
                    methodsList.addLast(ct);
                    ct.setActiveBody((Body) target.getActiveBody().clone());
                    // Make the invoke graph take into account the
                    // newly-cloned body.
                    {
                        Iterator oldUnits = target.getActiveBody().getUnits().iterator();
                        Iterator newUnits = ct.getActiveBody().getUnits().iterator();
                        while (newUnits.hasNext()) {
                            Stmt oldStmt, newStmt;
                            oldStmt = (Stmt) oldUnits.next();
                            newStmt = (Stmt) newUnits.next();
                            Iterator edges = cg.edgesOutOf(oldStmt);
                            while (edges.hasNext()) {
                                Edge e = (Edge) edges.next();
                                cg.addEdge(new Edge(ct, newStmt, e.tgt(), e.kind()));
                                cg.removeEdge(e);
                            }
                        }
                    }
                    // Shift the parameter list to apply to the new this
                    // parameter.
                    // If the method uses this, then we replace
                    // the r0 := @this with r0 := @parameter0 & shift.
                    // Otherwise, just zap the r0 := @this.
                    {
                        Body newBody = ct.getActiveBody();
                        Chain units = newBody.getUnits();
                        Iterator unitsIt = newBody.getUnits().snapshotIterator();
                        while (unitsIt.hasNext()) {
                            Stmt st = (Stmt) unitsIt.next();
                            if (st instanceof IdentityStmt) {
                                IdentityStmt is = (IdentityStmt) st;
                                if (is.getRightOp() instanceof ThisRef) {
                                    units.swapWith(st, Jimple.v().newIdentityStmt(is.getLeftOp(), Jimple.v().newParameterRef(is.getRightOp().getType(), 0)));
                                } else {
                                    if (is.getRightOp() instanceof ParameterRef) {
                                        ParameterRef ro = (ParameterRef) is.getRightOp();
                                        ro.setIndex(ro.getIndex() + 1);
                                    }
                                }
                            }
                        }
                    }
                    instanceToStaticMap.put(target, ct);
                }
                SootMethod clonedTarget = (SootMethod) instanceToStaticMap.get(target);
                Value thisToAdd = ((InstanceInvokeExpr) ie).getBase();
                // Insert casts to please the verifier.
                if (options.insert_redundant_casts()) {
                    // The verifier will complain if targetUsesThis, and:
                    // the argument passed to the method is not the same
                    // type.
                    // For instance, Bottle.price_static takes a cost.
                    // Cost is an interface implemented by Bottle.
                    SootClass localType, parameterType;
                    localType = ((RefType) ((InstanceInvokeExpr) ie).getBase().getType()).getSootClass();
                    parameterType = target.getDeclaringClass();
                    if (localType.isInterface() || hierarchy.isClassSuperclassOf(localType, parameterType)) {
                        Local castee = Jimple.v().newLocal("__castee", parameterType.getType());
                        b.getLocals().add(castee);
                        b.getUnits().insertBefore(Jimple.v().newAssignStmt(castee, Jimple.v().newCastExpr(((InstanceInvokeExpr) ie).getBase(), parameterType.getType())), s);
                        thisToAdd = castee;
                    }
                }
                // Now rebind the method call & fix the invoke graph.
                {
                    List newArgs = new ArrayList();
                    newArgs.add(thisToAdd);
                    newArgs.addAll(ie.getArgs());
                    StaticInvokeExpr sie = Jimple.v().newStaticInvokeExpr(clonedTarget.makeRef(), newArgs);
                    ValueBox ieBox = s.getInvokeExprBox();
                    ieBox.setValue(sie);
                    cg.addEdge(new Edge(container, s, clonedTarget));
                }
                // (If enabled), add a null pointer check.
                if (options.insert_null_checks()) {
                    boolean caught = TrapManager.isExceptionCaughtAt(Scene.v().getSootClass("java.lang.NullPointerException"), s, b);
                    /* Ah ha. Caught again! */
                    if (caught) {
                        /*
							 * In this case, we don't use throwPoint; instead,
							 * put the code right there.
							 */
                        Stmt insertee = Jimple.v().newIfStmt(Jimple.v().newNeExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), s);
                        b.getUnits().insertBefore(insertee, s);
                        // This sucks (but less than before).
                        ((IfStmt) insertee).setTarget(s);
                        ThrowManager.addThrowAfter(b, insertee);
                    } else {
                        Stmt throwPoint = ThrowManager.getNullPointerExceptionThrower(b);
                        b.getUnits().insertBefore(Jimple.v().newIfStmt(Jimple.v().newEqExpr(((InstanceInvokeExpr) ie).getBase(), NullConstant.v()), throwPoint), s);
                    }
                }
                // Add synchronizing stuff.
                {
                    if (target.isSynchronized()) {
                        clonedTarget.setModifiers(clonedTarget.getModifiers() & ~Modifier.SYNCHRONIZED);
                        SynchronizerManager.v().synchronizeStmtOn(s, b, (Local) ((InstanceInvokeExpr) ie).getBase());
                    }
                }
                // Resolve name collisions.
                LocalNameStandardizer.v().transform(b, phaseName + ".lns");
            }
        }
    }
}
Also used : Chain(soot.util.Chain) HashMap(java.util.HashMap) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IfStmt(soot.jimple.IfStmt) IdentityStmt(soot.jimple.IdentityStmt) Stmt(soot.jimple.Stmt) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) Hierarchy(soot.Hierarchy) InstanceInvokeEdgesPred(soot.jimple.toolkits.callgraph.InstanceInvokeEdgesPred) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) SpecialInvokeExpr(soot.jimple.SpecialInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) JimpleBody(soot.jimple.JimpleBody) Body(soot.Body) JimpleBody(soot.jimple.JimpleBody) IdentityStmt(soot.jimple.IdentityStmt) SMBOptions(soot.options.SMBOptions) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Local(soot.Local) Targets(soot.jimple.toolkits.callgraph.Targets) SootClass(soot.SootClass) LinkedList(java.util.LinkedList) ParameterRef(soot.jimple.ParameterRef) IfStmt(soot.jimple.IfStmt) Filter(soot.jimple.toolkits.callgraph.Filter) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ThisRef(soot.jimple.ThisRef) ValueBox(soot.ValueBox) Value(soot.Value) SootMethod(soot.SootMethod) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 10 with CallGraph

use of soot.jimple.toolkits.callgraph.CallGraph in project soot by Sable.

the class InfoFlowAnalysis method getInvokeInfoFlowSummary.

protected HashMutableDirectedGraph<EquivalentValue> getInvokeInfoFlowSummary(InvokeExpr ie, Stmt is, SootMethod context) {
    // get the data flow graph for each possible target of ie,
    // then combine them conservatively and return the result.
    HashMutableDirectedGraph<EquivalentValue> ret = null;
    SootMethodRef methodRef = ie.getMethodRef();
    String subSig = methodRef.resolve().getSubSignature();
    CallGraph cg = Scene.v().getCallGraph();
    for (Iterator<Edge> edges = cg.edgesOutOf(is); edges.hasNext(); ) {
        Edge e = edges.next();
        SootMethod target = e.getTgt().method();
        // and not just a class initializer or other unintended control flow.
        if (target.getSubSignature().equals(subSig)) {
            HashMutableDirectedGraph<EquivalentValue> ifs = getMethodInfoFlowSummary(target, context.getDeclaringClass().isApplicationClass());
            if (ret == null)
                ret = ifs;
            else {
                for (EquivalentValue node : ifs.getNodes()) {
                    if (!ret.containsNode(node))
                        ret.addNode(node);
                    for (EquivalentValue succ : ifs.getSuccsOf(node)) ret.addEdge(node, succ);
                }
            }
        }
    }
    return ret;
// return getMethodInfoFlowSummary(methodRef.resolve(), context.getDeclaringClass().isApplicationClass());
}
Also used : CallGraph(soot.jimple.toolkits.callgraph.CallGraph) Edge(soot.jimple.toolkits.callgraph.Edge)

Aggregations

CallGraph (soot.jimple.toolkits.callgraph.CallGraph)11 SootMethod (soot.SootMethod)7 Edge (soot.jimple.toolkits.callgraph.Edge)7 Stmt (soot.jimple.Stmt)5 MethodOrMethodContext (soot.MethodOrMethodContext)3 CgEdge (soot.jimple.spark.geom.dataRep.CgEdge)3 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 SootClass (soot.SootClass)2 Unit (soot.Unit)2 Value (soot.Value)2 ValueBox (soot.ValueBox)2 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)2 InvokeExpr (soot.jimple.InvokeExpr)2 PlainConstraint (soot.jimple.spark.geom.dataRep.PlainConstraint)2 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)2 Targets (soot.jimple.toolkits.callgraph.Targets)2 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1