Search in sources :

Example 6 with Edge

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

the class SootInfo method countCallEdgesForCallsite.

public static int countCallEdgesForCallsite(Stmt callsite, boolean stopForMutiple) {
    CallGraph cg = Scene.v().getCallGraph();
    int count = 0;
    for (Iterator<Edge> it = cg.edgesOutOf(callsite); it.hasNext(); ) {
        it.next();
        ++count;
        if (stopForMutiple && count > 1)
            break;
    }
    return count;
}
Also used : CallGraph(soot.jimple.toolkits.callgraph.CallGraph) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 7 with Edge

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

the class ContextInsensitiveBuilder method build.

/**
 * Fills in the pointer assignment graph returned by setup.
 */
public void build() {
    QueueReader<Edge> callEdges;
    if (ofcg != null) {
        callEdges = ofcg.callGraph().listener();
        ofcg.build();
        reachables = ofcg.reachableMethods();
        reachables.update();
    } else {
        callEdges = cgb.getCallGraph().listener();
        cgb.build();
        reachables = cgb.reachables();
    }
    for (final SootClass c : Scene.v().getClasses()) {
        handleClass(c);
    }
    while (callEdges.hasNext()) {
        Edge e = callEdges.next();
        if (e.getTgt().method().getDeclaringClass().isConcrete()) {
            if (e.tgt().isConcrete() || e.tgt().isNative())
                MethodPAG.v(pag, e.tgt()).addToPAG(null);
            pag.addCallTarget(e);
        }
    }
    if (pag.getOpts().verbose()) {
        logger.debug("Total methods: " + totalMethods);
        logger.debug("Initially reachable methods: " + analyzedMethods);
        logger.debug("Classes with at least one reachable method: " + classes);
    }
}
Also used : SootClass(soot.SootClass) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 8 with Edge

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

the class GeomQueries method kCFA.

/**
 * Standard K-CFA querying for arbitrary K.
 *
 * @param callEdgeChain: last K call edges leading to the method that contains l. callEdgeChain[0] is the farthest call edge in the chain.
 * @param l: the querying pointer
 * @param visitor: the querying result container
 * @return false, l does not have points-to information under the given context
 */
@SuppressWarnings("rawtypes")
public boolean kCFA(Edge[] callEdgeChain, Local l, PtSensVisitor visitor) {
    // Prepare for initial contexts
    SootMethod firstMethod = callEdgeChain[0].src();
    int firstMethodID = geomPTA.getIDFromSootMethod(firstMethod);
    if (firstMethodID == -1)
        return false;
    // Obtain the internal representation for querying pointer
    LocalVarNode vn = geomPTA.findLocalVarNode(l);
    if (vn == null) {
        // Normally this could not happen, perhaps it's a bug
        return false;
    }
    IVarAbstraction pn = geomPTA.findInternalNode(vn);
    if (pn == null) {
        // This pointer is no longer reachable
        return false;
    }
    pn = pn.getRepresentative();
    if (!pn.hasPTResult())
        return false;
    SootMethod sm = vn.getMethod();
    if (geomPTA.getIDFromSootMethod(sm) == -1)
        return false;
    // Iterate the call edges and compute the contexts mapping iteratively
    visitor.prepare();
    long L = 1;
    for (int i = 0; i < callEdgeChain.length; ++i) {
        Edge sootEdge = callEdgeChain[i];
        CgEdge ctxt = geomPTA.getInternalEdgeFromSootEdge(sootEdge);
        if (ctxt == null || ctxt.is_obsoleted == true)
            return false;
        // Following searching procedure works for both methods in SCC and out of SCC
        // with blocking scheme or without blocking scheme
        int caller = geomPTA.getIDFromSootMethod(sootEdge.src());
        // We obtain the block that contains current offset L
        long block_size = max_context_size_block[rep_cg[caller]];
        long in_block_offset = (L - 1) % block_size;
        // Transfer to the target block with the same in-block offset
        L = ctxt.map_offset + in_block_offset;
    }
    long ctxtLength = max_context_size_block[rep_cg[firstMethodID]];
    long R = L + ctxtLength;
    pn.get_all_context_sensitive_objects(L, R, visitor);
    visitor.finish();
    return visitor.numOfDiffObjects() != 0;
}
Also used : CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) SootMethod(soot.SootMethod) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) CgEdge(soot.jimple.spark.geom.dataRep.CgEdge) Edge(soot.jimple.toolkits.callgraph.Edge)

Example 9 with Edge

use of soot.jimple.toolkits.callgraph.Edge 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 Edge

use of soot.jimple.toolkits.callgraph.Edge 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

Edge (soot.jimple.toolkits.callgraph.Edge)15 CgEdge (soot.jimple.spark.geom.dataRep.CgEdge)8 SootMethod (soot.SootMethod)7 CallGraph (soot.jimple.toolkits.callgraph.CallGraph)7 PlainConstraint (soot.jimple.spark.geom.dataRep.PlainConstraint)5 Stmt (soot.jimple.Stmt)4 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)4 IVarAbstraction (soot.jimple.spark.geom.geomPA.IVarAbstraction)3 SootClass (soot.SootClass)2 Unit (soot.Unit)2 InstanceInvokeExpr (soot.jimple.InstanceInvokeExpr)2 InvokeExpr (soot.jimple.InvokeExpr)2 AllocNode (soot.jimple.spark.pag.AllocNode)2 ContextVarNode (soot.jimple.spark.pag.ContextVarNode)2 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1