Java Examples for soot.jimple.toolkits.callgraph.CallGraph
The following java examples will help you to understand the usage of soot.jimple.toolkits.callgraph.CallGraph. These source code samples are taken from different open source projects.
Example 1
| Project: apkinspector-master File: MultiRunStatementsFinder.java View source code |
private void findMultiCalledMethodsIntra(Set<Object> multiCalledMethods, CallGraph callGraph) {
Iterator<Unit> it = multiRunStatements.iterator();
while (it.hasNext()) {
Unit unit = it.next();
if (((Stmt) unit).containsInvokeExpr()) {
Value invokeExpr = ((Stmt) unit).getInvokeExpr();
List<SootMethod> targetList = new ArrayList<SootMethod>();
SootMethod method = ((InvokeExpr) invokeExpr).getMethod();
if (invokeExpr instanceof StaticInvokeExpr) {
targetList.add(method);
} else if (invokeExpr instanceof InstanceInvokeExpr) {
if (method.isConcrete() && !method.getDeclaringClass().isLibraryClass()) {
TargetMethodsFinder tmd = new TargetMethodsFinder();
// targetList = tmd.find(unit, callGraph, false, true);
// list could be empty... that's ok
targetList = tmd.find(unit, callGraph, true, true);
}
}
if (targetList != null) {
Iterator<SootMethod> iterator = targetList.iterator();
while (iterator.hasNext()) {
SootMethod obj = iterator.next();
if (!obj.isNative()) {
multiCalledMethods.add(obj);
}
}
}
}
}
}Example 2
| Project: DesignPatternAnalysis-master File: AnalysisUtil.java View source code |
// Independent Role Analysis over a Type
public void analyzeRole(SootClass aType, Map<String, MetaInfo> metaInfoMap, RoleRepository roles, Map<String, SootClass> classMap, Hierarchy hierarchy, CallGraph cg) {
for (String key : metaInfoMap.keySet()) {
MetaInfo metaInfo = metaInfoMap.get(key);
if (metaInfo.getElement() instanceof SootMethod) {
SootMethod method = (SootMethod) metaInfo.getElement();
Map<String, LocalInfo> callLocalInfos = calls(method, aType, classMap);
Map<String, LocalInfo> creationLocalInfos = typeFilterOfLocalMap(creations(method), aType, hierarchy, classMap);
for (LocalInfo callLocalInfo : callLocalInfos.values()) {
checkCaller(aType, metaInfo, callLocalInfo, roles);
}
for (LocalInfo creationLocalInfo : creationLocalInfos.values()) {
checkCreator(aType, metaInfo, creationLocalInfo, roles, classMap);
}
checkInjector(method, aType, metaInfoMap, roles, classMap, hierarchy, cg);
} else if (metaInfo.getElement() instanceof SootField) {
SootField field = (SootField) metaInfo.getElement();
SootClass fieldType = typeToClass(field.getType(), classMap);
if (fieldType != null) {
if (fieldType.equals(aType)) {
Store store = new Store();
store.setInterfaceType(aType);
metaInfo.addRole(store);
roles.addStore(metaInfo);
}
}
}
}
}Example 3
| Project: Slithice-master File: SootUtils.java View source code |
/**
* get graph of strong connected components.
* XXX: Here we break thread start calls in the call graph when finding SCCs
*/
public static DirectedGraph<Collection> getSCCGraph(CallGraph cg, Collection entries) {
ReachableMethods rm = CallGraphHelper.getReachableMethod(cg, entries);
CallGraphNodeFilter nodeFilter = CallGraphHelper.getCallGraphNodeFilter(rm);
CallGraphEdgeFilter edgeFilter = new CallGraphEdgeFilter() {
public boolean isIgnored(Edge e) {
return (e.kind() == Kind.THREAD);
}
};
DirectedCallGraph dcg = new DirectedCallGraph(cg, entries, nodeFilter, edgeFilter);
StronglyConnectedComponents scc = new StronglyConnectedComponents(dcg);
return scc.getSuperGraph();
}Example 4
| Project: soot-master File: GeomEvaluator.java View source code |
/**
* Report the virtual callsites resolution result for the user's code.
*/
public void checkCallGraph() {
Map<Stmt, Set<SootMethod>> my_vir_tgts = new HashMap<Stmt, Set<SootMethod>>();
int n_func;
int total_virtual_calls = 0;
int n_geom_call_edges = 0, n_geom_user_edges = 0;
int n_spark_user_edges = 0, n_spark_cinit_edges = 0;
int geom_solved = 0, spark_solved = 0;
n_func = ptsProvider.n_func;
// We first collect the internal call graph information
for (int i = 1; i < n_func; ++i) {
if (!ptsProvider.isReachableMethod(i))
continue;
CgEdge p = ptsProvider.getCallEgesOutFrom(i);
int edge_cnt = 0;
while (p != null) {
if (p.base_var != null) {
Stmt expr = p.sootEdge.srcStmt();
if (expr != null) {
Set<SootMethod> tgts = my_vir_tgts.get(expr);
if (tgts == null) {
tgts = new HashSet<SootMethod>();
my_vir_tgts.put(expr, tgts);
}
tgts.add(p.sootEdge.tgt().method());
}
}
++edge_cnt;
p = p.next;
}
n_geom_call_edges += edge_cnt;
if (!ptsProvider.getSootMethodFromID(i).isJavaLibraryMethod())
n_geom_user_edges += edge_cnt;
}
int[] limits = new int[] { 1, 2, 4, 8 };
Histogram total_call_edges = new Histogram(limits);
System.gc();
System.gc();
System.gc();
CallGraph cGraph = Scene.v().getCallGraph();
// Scan all the callsites
for (SootMethod sm : ptsProvider.getAllReachableMethods()) {
// Skip the uninteresting methods
if (sm.isJavaLibraryMethod())
continue;
if (!sm.isConcrete())
continue;
if (!sm.hasActiveBody()) {
sm.retrieveActiveBody();
}
if (!ptsProvider.isValidMethod(sm))
continue;
// All the statements in the method
for (Iterator stmts = sm.getActiveBody().getUnits().iterator(); stmts.hasNext(); ) {
Stmt st = (Stmt) stmts.next();
if (st.containsInvokeExpr()) {
InvokeExpr ie = st.getInvokeExpr();
if (ie instanceof VirtualInvokeExpr) {
total_virtual_calls++;
Local l = (Local) ((VirtualInvokeExpr) ie).getBase();
LocalVarNode vn = ptsProvider.findLocalVarNode(l);
// Test my points-to analysis
solved = false;
if (my_vir_tgts.containsKey(st)) {
Set<SootMethod> tgts = my_vir_tgts.get(st);
if (tgts.size() == 1) {
++geom_solved;
solved = true;
} else {
// We try to test if this callsite is solvable under some contexts
Histogram call_edges = new Histogram(limits);
test_1cfa_call_graph(vn, sm, ie.getMethod(), call_edges);
total_call_edges.merge(call_edges);
call_edges = null;
}
} else {
// It has zero target, dead code
++geom_solved;
solved = true;
}
int count = 0;
for (Iterator<Edge> it = cGraph.edgesOutOf(st); it.hasNext(); ) {
it.next();
++count;
}
if (count <= 1)
spark_solved++;
if (count > 1 && solved == true && ptsProvider.getOpts().verbose()) {
outputer.println();
outputer.println("<<<<<<<<< Additional Solved Call >>>>>>>>>>");
outputer.println(sm.toString());
outputer.println(ie.toString());
EvalHelper.debug_succint_pointsto_info(vn, ptsProvider);
}
}
}
}
for (Iterator<Edge> it = cGraph.edgesOutOf(sm); it.hasNext(); ) {
Edge e = it.next();
if (!e.isClinit())
++n_spark_user_edges;
}
}
// Now we count the cinit edges
QueueReader<Edge> edgeList = Scene.v().getCallGraph().listener();
while (edgeList.hasNext()) {
Edge edge = edgeList.next();
if (edge.isClinit())
++n_spark_cinit_edges;
}
ptsProvider.ps.println();
ptsProvider.ps.printf("Call graph edges (total): Geom = %d, SPARK = %d\n", n_geom_call_edges, cGraph.size() - n_spark_cinit_edges);
ptsProvider.ps.printf("Call graph edges (app code): Geom = %d, SPARK = %d\n", n_geom_user_edges, n_spark_user_edges);
ptsProvider.ps.println("Total virtual callsites (app code): " + total_virtual_calls);
ptsProvider.ps.println("Resolved virtual callsites : Geom = " + geom_solved + ", SPARK = " + spark_solved);
total_call_edges.printResult(ptsProvider.ps, "Random testing of the 1-CFA call graph : ");
if (ptsProvider.getOpts().verbose())
ptsProvider.outputNotEvaluatedMethods();
}Example 5
| Project: ptii-master File: SideEffectFreeInvocationRemover.java View source code |
protected void internalTransform(String phaseName, Map options) {
System.out.println("SideEffectFreeInvocationRemover.internalTransform(" + phaseName + ", " + options + ")");
Scene.v().releaseCallGraph();
// Temporary hack to deal with interfaces... assume that methods of
// interfaces are automatically reachable.
HashSet forcedReachableMethodSet = new HashSet();
forcedReachableMethodSet.addAll(EntryPoints.v().application());
// Loop over all the classes...
for (Iterator i = Scene.v().getApplicationClasses().iterator(); i.hasNext(); ) {
SootClass theClass = (SootClass) i.next();
// System.out.println("forcing interfaces of " + theClass);
if (!theClass.isInterface()) {
for (Iterator interfaces = theClass.getInterfaces().iterator(); interfaces.hasNext(); ) {
SootClass theInterface = (SootClass) interfaces.next();
_addMethodsFrom(forcedReachableMethodSet, theInterface, theClass);
}
}
}
System.out.println("forcedMethods = " + forcedReachableMethodSet);
// Loop over all the classes...
for (Iterator i = Scene.v().getApplicationClasses().iterator(); i.hasNext(); ) {
SootClass theClass = (SootClass) i.next();
Scene.v().loadClassAndSupport(theClass.getName());
}
System.out.println("done loading classes!");
// Construct the graph of methods that are directly reachable
// from any method.
// Construct the graph of all method invocations, so we know what
// method contains each invocation and what method(s) can be
// targeted by that invocation.
CallGraphBuilder cg = new CallGraphBuilder(DumbPointerAnalysis.v(), true);
cg.build();
CallGraph callGraph = Scene.v().getCallGraph();
Scene.v().setCallGraph(callGraph);
SideEffectAnalysis analysis = new SideEffectAnalysis();
for (Iterator classes = Scene.v().getApplicationClasses().iterator(); classes.hasNext(); ) {
SootClass theClass = (SootClass) classes.next();
for (Iterator methods = theClass.getMethods().iterator(); methods.hasNext(); ) {
SootMethod method = (SootMethod) methods.next();
_removeSideEffectFreeMethodCalls(method, callGraph, analysis);
}
}
}Example 6
| Project: SPLlift-master File: UnitUtil.java View source code |
/** * Serialize a CallGraph in the DOT format into a provided file path. * * TODO: describe the behaviour of this method in case the file already exists. * * @param graph * the graph to be serialized * @param fileName * the file name, or null to use the default Soot output folder. */ public static File serializeCallGraph(CallGraph graph, String fileName) { if (fileName == null) { fileName = soot.SourceLocator.v().getOutputDir(); if (fileName.length() > 0) { fileName = fileName + java.io.File.separator; } fileName = fileName + "call-graph" + DotGraph.DOT_EXTENSION; } DotGraph canvas = new DotGraph("call-graph"); QueueReader<Edge> listener = graph.listener(); while (listener.hasNext()) { Edge next = listener.next(); MethodOrMethodContext src = next.getSrc(); MethodOrMethodContext tgt = next.getTgt(); canvas.drawNode(src.toString()); canvas.drawNode(tgt.toString()); canvas.drawEdge(src.toString(), tgt.toString()); } canvas.plot(fileName); return new File(fileName); }
Example 7
| Project: ic3-master File: EntryPointMappingSceneTransformer.java View source code |
@Override
protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
PropagationTimers.v().totalTimer.start();
Timers.v().entryPointMapping.start();
// Set<String> signatures = new HashSet<>();
Map<SootMethod, Set<String>> entryPointMap = this.entryPointMap;
if (logger.isDebugEnabled()) {
Set<String> difference = new HashSet<>(this.callbackMethods.keySet());
difference.removeAll(entryPointClasses);
if (difference.size() == 0) {
logger.debug("Difference size is 0");
} else {
logger.debug("Difference is " + difference);
}
}
// Set<String> lifecycleMethods = new HashSet<>();
// lifecycleMethods.addAll(AndroidEntryPointConstants.getActivityLifecycleMethods());
// lifecycleMethods.addAll(AndroidEntryPointConstants.getApplicationLifecycleMethods());
// lifecycleMethods.addAll(AndroidEntryPointConstants.getBroadcastLifecycleMethods());
// lifecycleMethods.addAll(AndroidEntryPointConstants.getContentproviderLifecycleMethods());
// lifecycleMethods.addAll(AndroidEntryPointConstants.getServiceLifecycleMethods());
activityClass = Scene.v().getSootClass(AndroidEntryPointConstants.ACTIVITYCLASS);
serviceClass = Scene.v().getSootClass(AndroidEntryPointConstants.SERVICECLASS);
gcmBaseIntentServiceClass = Scene.v().getSootClass(AndroidEntryPointConstants.GCMBASEINTENTSERVICECLASS);
receiverClass = Scene.v().getSootClass(AndroidEntryPointConstants.BROADCASTRECEIVERCLASS);
providerClass = Scene.v().getSootClass(AndroidEntryPointConstants.CONTENTPROVIDERCLASS);
applicationClass = Scene.v().getSootClass(AndroidEntryPointConstants.APPLICATIONCLASS);
if (logger.isDebugEnabled()) {
logger.debug(this.callbackMethods.toString());
}
for (String entryPoint : entryPointClasses) {
// if (!entryPointClasses.contains(entryPoint)) {
// System.err.println("Warning: " + entryPoint + " is not an entry point");
// continue;
// }
SootClass entryPointClass = Scene.v().getSootClass(entryPoint);
List<MethodOrMethodContext> callbacks = new ArrayList<>();
// Add methods for component.
boolean knownComponentType = addLifecycleMethods(entryPointClass, callbacks);
for (SootMethod method : entryPointClass.getMethods()) {
String methodName = method.getName();
if (methodName.equals(SootMethod.constructorName) || methodName.equals(SootMethod.staticInitializerName) || !knownComponentType) {
callbacks.add(method);
}
}
Set<String> callbackMethodStrings = this.callbackMethods.get(entryPoint);
if (callbackMethodStrings != null) {
for (String callbackMethodString : callbackMethodStrings) {
if (!Scene.v().containsMethod(callbackMethodString)) {
if (logger.isWarnEnabled()) {
logger.warn("Warning: " + callbackMethodString + " is not in scene");
}
continue;
}
SootMethod method = Scene.v().getMethod(callbackMethodString);
// Add constructors for callbacks.
for (SootMethod potentialInit : method.getDeclaringClass().getMethods()) {
if (potentialInit.isPrivate()) {
continue;
}
String name = potentialInit.getName();
if (name.equals(SootMethod.constructorName)) {
addConstructorStack(potentialInit, callbacks);
} else if (name.equals(SootMethod.staticInitializerName)) {
callbacks.add(potentialInit);
}
}
callbacks.add(method);
}
}
if (logger.isDebugEnabled()) {
logger.debug(callbacks.toString());
}
ReachableMethods reachableMethods = new ReachableMethods(Scene.v().getCallGraph(), callbacks.iterator(), null);
reachableMethods.update();
for (Iterator<MethodOrMethodContext> iter = reachableMethods.listener(); iter.hasNext(); ) {
SootMethod method = iter.next().method();
if (!AnalysisParameters.v().isAnalysisClass(method.getDeclaringClass().getName())) {
continue;
}
if (logger.isDebugEnabled()) {
logger.debug(method.toString());
}
Set<String> entryPoints = entryPointMap.get(method);
if (entryPoints == null) {
entryPoints = new HashSet<>();
entryPointMap.put(method, entryPoints);
}
entryPoints.add(entryPoint);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Entry points");
logger.debug(entryPointMap.toString());
CallGraph cg = Scene.v().getCallGraph();
Iterator<Edge> it = cg.listener();
StringBuilder stringBuilder = new StringBuilder("Call graph:\n");
while (it.hasNext()) {
soot.jimple.toolkits.callgraph.Edge e = it.next();
stringBuilder.append("" + e.src() + e.srcStmt() + " =" + e.kind() + "=> " + e.tgt() + "\n");
}
logger.debug(stringBuilder.toString());
}
Timers.v().entryPointMapping.end();
PropagationTimers.v().totalTimer.end();
}Example 8
| Project: vasco-master File: CallGraphTransformer.java View source code |
/**
* {@inheritDoc}
*/
@SuppressWarnings("deprecation")
@Override
protected void internalTransform(String arg0, @SuppressWarnings("rawtypes") Map arg1) {
// Perform the points-to analysis
pointsToAnalysis = new PointsToAnalysis();
pointsToAnalysis.doAnalysis();
// Use the context transition table generated by the analysis to construct soot call graphs
final ContextTransitionTable<SootMethod, Unit, PointsToGraph> ctt = pointsToAnalysis.getContextTransitionTable();
// Initialize collections (for creating the soot context-sensitive call graph)
final Set<SootMethod> allMethods = pointsToAnalysis.getMethods();
final Map<Context<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>> csEdgesIntoContext = new HashMap<Context<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>>();
final Map<Context<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>> csEdgesOutOfContext = new HashMap<Context<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>>();
final Map<CallSite<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>> csEdgesOutOfCallSite = new HashMap<CallSite<SootMethod, Unit, PointsToGraph>, Collection<ContextSensitiveEdge>>();
final Collection<ContextSensitiveEdge> csEdges = new ArrayList<ContextSensitiveEdge>();
// Initialize the context-insensitive call graph
CallGraph callGraph = new CallGraph();
// Create soot-style edges for every context transition
for (Map.Entry<CallSite<SootMethod, Unit, PointsToGraph>, Map<SootMethod, Context<SootMethod, Unit, PointsToGraph>>> e : ctt.getTransitions().entrySet()) {
CallSite<SootMethod, Unit, PointsToGraph> cs = e.getKey();
final Context<SootMethod, Unit, PointsToGraph> sourceContext = cs.getCallingContext();
final SootMethod sourceMethod = sourceContext.getMethod();
final Unit stmt = cs.getCallNode();
final Map<SootMethod, Context<SootMethod, Unit, PointsToGraph>> targets = e.getValue();
for (final SootMethod targetMethod : targets.keySet()) {
final Context<SootMethod, Unit, PointsToGraph> targetContext = targets.get(targetMethod);
Kind k;
if (stmt instanceof InvokeExpr) {
k = Edge.ieToKind((InvokeExpr) stmt);
} else {
k = Kind.INVALID;
}
// The context-insensitive edge
Edge cgEdge = new Edge(sourceMethod, stmt, targetMethod, k);
// Add it to the context-insensitive call-graph
callGraph.addEdge(cgEdge);
// The context-sensitive edge
ContextSensitiveEdge csEdge = new ContextSensitiveEdge() {
@Override
public Kind kind() {
if (stmt instanceof InvokeExpr) {
return Edge.ieToKind((InvokeExpr) stmt);
} else {
return Kind.INVALID;
}
}
@Override
public SootMethod src() {
return sourceMethod;
}
@Override
public soot.Context srcCtxt() {
return sourceContext;
}
@Override
public Stmt srcStmt() {
return (Stmt) stmt;
}
@Override
public Unit srcUnit() {
return stmt;
}
@Override
public SootMethod tgt() {
return targetMethod;
}
@Override
public soot.Context tgtCtxt() {
return targetContext;
}
};
// Add this in all the collections
csEdges.add(csEdge);
if (!csEdgesOutOfContext.containsKey(sourceContext))
csEdgesOutOfContext.put(sourceContext, new ArrayList<ContextSensitiveEdge>());
csEdgesOutOfContext.get(sourceContext).add(csEdge);
if (!csEdgesOutOfCallSite.containsKey(cs))
csEdgesOutOfCallSite.put(cs, new ArrayList<ContextSensitiveEdge>());
csEdgesOutOfCallSite.get(cs).add(csEdge);
if (!csEdgesIntoContext.containsKey(targetContext))
csEdgesIntoContext.put(targetContext, new ArrayList<ContextSensitiveEdge>());
csEdgesIntoContext.get(targetContext).add(csEdge);
}
}
// Set the scene's context-insensitive call-graph to what we just created
Scene.v().setCallGraph(callGraph);
// Set the scene's context-sensitive call graph to one that we construct on-the-fly using the above collections
Scene.v().setContextSensitiveCallGraph(new ContextSensitiveCallGraph() {
@SuppressWarnings("unchecked")
private Context<SootMethod, Unit, PointsToGraph> vContext(soot.Context sContext) {
return (Context<SootMethod, Unit, PointsToGraph>) sContext;
}
private CallSite<SootMethod, Unit, PointsToGraph> vCallSite(soot.Context sContext, Unit unit) {
return new CallSite<SootMethod, Unit, PointsToGraph>(vContext(sContext), unit);
}
@Override
public Iterator<?> edgesOutOf(soot.Context sContext, SootMethod m, Unit stmt) {
return csEdgesOutOfCallSite.get((vCallSite(sContext, stmt))).iterator();
}
@Override
public Iterator<?> edgesOutOf(soot.Context sContext, SootMethod m) {
return csEdgesOutOfContext.get(vContext(sContext)).iterator();
}
@Override
public Iterator<?> edgesInto(soot.Context sContext, SootMethod m) {
return csEdgesIntoContext.get(vContext(sContext)).iterator();
}
@Override
public Iterator<?> edgeSources() {
return allMethods.iterator();
}
@Override
public Iterator<?> allEdges() {
return csEdges.iterator();
}
});
}Example 9
| Project: bugvm-master File: LocalMustAliasAnalysis.java View source code |
/**
* 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;
}