/** Returns a list of all concrete methods of all application classes. */ public List<SootMethod> methodsOfApplicationClasses() { List<SootMethod> ret = new ArrayList<SootMethod>(); for (Iterator<SootClass> clIt = Scene.v().getApplicationClasses().iterator(); clIt.hasNext();) { final SootClass cl = clIt.next(); for (Iterator<SootMethod> mIt = cl.getMethods().iterator(); mIt.hasNext();) { final SootMethod m = mIt.next(); if (m.isConcrete()) { ret.add(m); } } } return ret; }
/** * Returns a list of all concrete main(String[]) methods of all application classes. */ public List<SootMethod> mainsOfApplicationClasses() { List<SootMethod> ret = new ArrayList<SootMethod>(); for (Iterator<SootClass> clIt = Scene.v().getApplicationClasses().iterator(); clIt.hasNext();) { final SootClass cl = clIt.next(); SootMethod m = cl.getMethodUnsafe("void main(java.lang.String[])"); if (m != null) { if (m.isConcrete()) { ret.add(m); } } } return ret; }
public HashMutableDirectedGraph<EquivalentValue> getMethodInfoFlowSummary(SootMethod method, boolean doFullAnalysis) { if (!methodToInfoFlowSummary.containsKey(method)) { methodCount++; // First do simple version that doesn't follow invoke expressions // The "smart" version will be computed later, but since it may // request its own DataFlowGraph, we need this simple version first. HashMutableDirectedGraph<EquivalentValue> dataFlowGraph = simpleConservativeInfoFlowAnalysis(method); methodToInfoFlowSummary.put(method, dataFlowGraph); // Then do smart version that does follow invoke expressions, if possible if (method.isConcrete() && doFullAnalysis)// && method.getDeclaringClass().isApplicationClass()) { Body b = method.retrieveActiveBody(); UnitGraph g = new ExceptionalUnitGraph(b); SmartMethodInfoFlowAnalysis smdfa = new SmartMethodInfoFlowAnalysis(g, dfa); methodToInfoFlowAnalysis.put(method, smdfa); methodToInfoFlowSummary.remove(method); methodToInfoFlowSummary.put(method, smdfa.getMethodInfoFlowSummary()); // logger.debug(""+method + " has SMART infoFlowGraph: "); // printDataFlowGraph(mdfa.getMethodDataFlowGraph()); } } return methodToInfoFlowSummary.get(method); }
public SmartMethodInfoFlowAnalysis getMethodInfoFlowAnalysis(SootMethod method) { if (!methodToInfoFlowAnalysis.containsKey(method)) { methodCount++; // First do simple version that doesn't follow invoke expressions // The "smart" version will be computed later, but since it may // request its own DataFlowGraph, we need this simple version first. if (!methodToInfoFlowSummary.containsKey(method)) { HashMutableDirectedGraph<EquivalentValue> dataFlowGraph = simpleConservativeInfoFlowAnalysis(method); methodToInfoFlowSummary.put(method, dataFlowGraph); } // Then do smart version that does follow invoke expressions, if possible if (method.isConcrete()) { Body b = method.retrieveActiveBody(); UnitGraph g = new ExceptionalUnitGraph(b); SmartMethodInfoFlowAnalysis smdfa = new SmartMethodInfoFlowAnalysis(g, dfa); methodToInfoFlowAnalysis.put(method, smdfa); methodToInfoFlowSummary.remove(method); methodToInfoFlowSummary.put(method, smdfa.getMethodInfoFlowSummary()); return smdfa; // logger.debug(""+method + " has SMART infoFlowGraph: "); // printDataFlowGraph(mdfa.getMethodDataFlowGraph()); } } return methodToInfoFlowAnalysis.get(method); }
private void processNewMethod(SootMethod m) { if (!m.isConcrete()) { return; } Body b = m.retrieveActiveBody(); getImplicitTargets(m); findReceivers(m, b); }
/** * Sets the active body for this method. */ public synchronized void setActiveBody(Body body) { if ((declaringClass != null) && declaringClass.isPhantomClass()) { throw new RuntimeException("cannot set active body for phantom class! " + this); } // If someone sets a body for a phantom method, this method then is no // longer phantom setPhantom(false); if (!isConcrete()) { throw new RuntimeException("cannot set body for non-concrete method! " + this); } if (body != null && body.getMethod() != this) { body.setMethod(this); } this.activeBody = body; }
private void computeAverageMethodSizeAndSaveOriginalSizes() { long sum = 0, count = 0; Iterator classesIt = Scene.v().getApplicationClasses().iterator(); while (classesIt.hasNext()) { SootClass c = (SootClass) classesIt.next(); Iterator methodsIt = c.methodIterator(); while (methodsIt.hasNext()) { SootMethod m = (SootMethod) methodsIt.next(); if (m.isConcrete()) { int size = ((JimpleBody) m.retrieveActiveBody()).getUnits().size(); sum += size; methodToOriginalSize.put(m, new Integer(size)); count++; } } } if (count == 0) { return; } } }
private void findMultiCalledMethodsIntra(Set<SootMethod> multiCalledMethods, CallGraph callGraph) { Iterator<Unit> it = multiRunStatements.iterator(); while (it.hasNext()) { Stmt stmt = (Stmt) it.next(); if (stmt.containsInvokeExpr()) { InvokeExpr invokeExpr = stmt.getInvokeExpr(); List<SootMethod> targetList = new ArrayList<SootMethod>(); SootMethod method = 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(stmt, callGraph, true, true); } } if (targetList != null) { Iterator<SootMethod> iterator = targetList.iterator(); while (iterator.hasNext()) { SootMethod obj = iterator.next(); if (!obj.isNative()) { multiCalledMethods.add(obj); } } } } } }
public void preJimplify() { boolean change = true; while (change) { change = false; for (Iterator<SootClass> cIt = new ArrayList<>(Scene.v().getClasses()).iterator(); cIt.hasNext();) { final SootClass c = cIt.next(); for (final SootMethod m : c.getMethods()) { if (!m.isConcrete()) { continue; } if (m.isNative()) { continue; } if (m.isPhantom()) { continue; } if (!m.hasActiveBody()) { change = true; m.retrieveActiveBody(); } } } } }
protected void handleClass(PrintWriter out, SootClass c) { for (SootMethod m : c.getMethods()) { if (!m.isConcrete()) { continue; } Body b = m.retrieveActiveBody(); Local[] sortedLocals = b.getLocals().toArray(new Local[b.getLocalCount()]); Arrays.sort(sortedLocals, new StringComparator<Local>()); for (Local l : sortedLocals) { out.println("V " + m + l); if (l.getType() instanceof RefLikeType) { Set<Type> types = pa.reachingObjects(l).possibleTypes(); Type[] sortedTypes = types.toArray(new Type[types.size()]); Arrays.sort(sortedTypes, new StringComparator<Type>()); for (Type type : sortedTypes) { out.println("T " + type); } } } } } }
protected void ensureProcessed(SootMethod m) { if (processedMethods.contains(m)) { return; } processedMethods.add(m); if (!m.isConcrete()) { return; } if (m.isPhantom()) { return; } for (Iterator sIt = m.retrieveActiveBody().getUnits().iterator(); sIt.hasNext();) { final Stmt s = (Stmt) sIt.next(); if (s instanceof AssignStmt) { AssignStmt as = (AssignStmt) s; Value l = as.getLeftOp(); if (l instanceof FieldRef) { methodToWrite.put(m, ((FieldRef) l).getField()); } Value r = as.getRightOp(); if (r instanceof FieldRef) { methodToRead.put(m, ((FieldRef) r).getField()); } } } }
public static void retrieveAllBodies() { if (bodiesHaveBeenBuilt) { return; } // iterate through application classes, rename fields with junk for (SootClass c : soot.Scene.v().getApplicationClasses()) { for (SootMethod m : c.getMethods()) { if (!m.isConcrete()) { continue; } if (!m.hasActiveBody()) { m.retrieveActiveBody(); } } } bodiesHaveBeenBuilt = true; }
public RWSet writeSet(SootMethod method, Stmt stmt) { RWSet ret = null; Iterator<MethodOrMethodContext> targets = tt.iterator(stmt); while (targets.hasNext()) { SootMethod target = (SootMethod) targets.next(); if (target.isNative()) { if (ret == null) { ret = new SiteRWSet(); } ret.setCallsNative(); } else if (target.isConcrete()) { RWSet ntw = nonTransitiveWriteSet(target); if (ntw != null) { if (ret == null) { ret = new SiteRWSet(); } ret.union(ntw); } } } if (ret == null) { return ntWriteSet(method, stmt); } ret.union(ntWriteSet(method, stmt)); return ret; }
public RWSet readSet(SootMethod method, Stmt stmt) { RWSet ret = null; Iterator<MethodOrMethodContext> targets = tt.iterator(stmt); while (targets.hasNext()) { SootMethod target = (SootMethod) targets.next(); if (target.isNative()) { if (ret == null) { ret = new SiteRWSet(); } ret.setCallsNative(); } else if (target.isConcrete()) { RWSet ntr = nonTransitiveReadSet(target); if (ntr != null) { if (ret == null) { ret = new SiteRWSet(); } ret.union(ntr); } } } if (ret == null) { return ntReadSet(method, stmt); } ret.union(ntReadSet(method, stmt)); return ret; }
protected Body initForMethod(SootMethod m) { assert Scene.v().hasFastHierarchy(); Body b = null; if (m.isConcrete()) { SootClass declaringClass = m.getDeclaringClass(); ensureClassHasBodies(declaringClass); synchronized (Scene.v()) { b = m.retrieveActiveBody(); } if (b != null) { for (Unit u : b.getUnits()) { if (unitToOwner.put(u, b) != null) { // if the unit was registered already then so were all units; // simply skip the rest break; } } } } assert Scene.v().hasFastHierarchy(); return b; }
protected void handleClass(SootClass c) { boolean incedClasses = false; if (c.isConcrete()) { for (SootMethod m : c.getMethods()) { if (!m.isConcrete() && !m.isNative()) { continue; } totalMethods++; if (reachables.contains(m)) { MethodPAG mpag = MethodPAG.v(pag, m); mpag.build(); mpag.addToPAG(null); analyzedMethods++; if (!incedClasses) { incedClasses = true; classes++; } } } } }
public void build() { if (hasBeenBuilt) { return; } hasBeenBuilt = true; if (method.isNative()) { if (pag().getOpts().simulate_natives()) { buildNative(); } } else { if (method.isConcrete() && !method.isPhantom()) { buildNormal(); } } addMiscEdges(); }
@Override public void visitEnd() { super.visitEnd(); if (visibleParamAnnotations != null) { VisibilityParameterAnnotationTag tag = new VisibilityParameterAnnotationTag(visibleParamAnnotations.length, AnnotationConstants.RUNTIME_VISIBLE); for (VisibilityAnnotationTag vat : visibleParamAnnotations) { tag.addVisibilityAnnotation(vat); } method.addTag(tag); } if (invisibleParamAnnotations != null) { VisibilityParameterAnnotationTag tag = new VisibilityParameterAnnotationTag(invisibleParamAnnotations.length, AnnotationConstants.RUNTIME_INVISIBLE); for (VisibilityAnnotationTag vat : invisibleParamAnnotations) { tag.addVisibilityAnnotation(vat); } method.addTag(tag); } if (method.isConcrete()) { method.setSource(new AsmMethodSource(maxLocals, instructions, localVariables, tryCatchBlocks)); } } }
protected void internalApply() { CGOptions options = new CGOptions(PhaseOptions.v().getPhaseOptions(this)); if (!Scene.v().hasCustomEntryPoints()) { if (!options.implicit_entry()) { Scene.v().setEntryPoints(EntryPoints.v().application()); } if (options.all_reachable()) { List<SootMethod> entryPoints = new ArrayList<SootMethod>(); entryPoints.addAll(EntryPoints.v().all()); entryPoints.addAll(EntryPoints.v().methodsOfApplicationClasses()); Scene.v().setEntryPoints(entryPoints); } } super.internalApply(); ClinitElimTransformer trimmer = new ClinitElimTransformer(); if (options.trim_clinit()) { for (SootClass cl : Scene.v().getClasses(SootClass.BODIES)) { for (SootMethod m : cl.getMethods()) { if (m.isConcrete() && m.hasActiveBody()) { trimmer.transform(m.getActiveBody()); } } } } } }
public static EquivalentValue getNodeForFieldRef(SootMethod sm, SootField sf, Local realLocal) { if (sf.isStatic()) { return new CachedEquivalentValue(Jimple.v().newStaticFieldRef(sf.makeRef())); } else { // Jimple.v().newThisRef(sf.getDeclaringClass().getType()) if (sm.isConcrete() && !sm.isStatic() && sm.getDeclaringClass() == sf.getDeclaringClass() && realLocal == null) { JimpleLocal fakethis = new FakeJimpleLocal("fakethis", sf.getDeclaringClass().getType(), sm.retrieveActiveBody().getThisLocal()); return new CachedEquivalentValue(Jimple.v().newInstanceFieldRef(fakethis, sf.makeRef())); // fake thisLocal } else { // Pretends to be a this.<somefield> ref for a method without a body, // for a static method, or for an inner field JimpleLocal fakethis = new FakeJimpleLocal("fakethis", sf.getDeclaringClass().getType(), realLocal); return new CachedEquivalentValue(Jimple.v().newInstanceFieldRef(fakethis, sf.makeRef())); // fake thisLocal } } }