private static boolean checkIfIsArrayFunction( SootMethod method, InstanceInvokeExpr instanceInvokeExpr) { String methodName = method.getName(); Value base = instanceInvokeExpr.getBase(); System.out.println(base.getType()); if (base.getType().toString().equals("android.content.Intent")) { if (methodName.startsWith("get") && methodName.contains("Array")) { return true; } } return false; }
@Override public Type appliesInternal(AndroidMethod method) { SootMethod sm = getSootMethod(method); if (sm == null) { System.err.println("Method not declared: " + method); return Type.NOT_SUPPORTED; } // We are only interested in setters if (!sm.isConcrete()) return Type.NOT_SUPPORTED; try { Set<Value> paramVals = new HashSet<Value>(); for (Unit u : sm.retrieveActiveBody().getUnits()) { // Collect the parameters if (u instanceof IdentityStmt) { IdentityStmt id = (IdentityStmt) u; if (id.getRightOp() instanceof ParameterRef) paramVals.add(id.getLeftOp()); } // Check for invocations if (u instanceof Stmt) { Stmt stmt = (Stmt) u; if (stmt.containsInvokeExpr()) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iinv = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (paramVals.contains(iinv.getBase())) if (iinv.getMethod().getName().startsWith(methodName)) return Type.TRUE; } } } return Type.FALSE; } catch (Exception ex) { System.err.println("Something went wrong:"); ex.printStackTrace(); return Type.NOT_SUPPORTED; } }
public void assureAllSyncInCallGraph(Collection<JavaCriticalSection> criticalSections) { System.out.println("[assureAllSyncInCallgraph] starting"); Date start = new Date(); ReachableMethods oldReach = Scene.v().getReachableMethods(); // Collection et = EntryPoints.v().all(); // ReachableMethods reachableFromMain = new ReachableMethods(cg, et); // reachableFromMain.update(); Set<SootMethod> notInCG = new HashSet<SootMethod>(); for (JavaCriticalSection cs : criticalSections) { SootMethod m = cs.getSootMethod(); if (!oldReach.contains(m)) notInCG.add(m); } Set<SootMethod> alreadyInCG = new HashSet<SootMethod>(); for (Iterator<MethodOrMethodContext> it = oldReach.listener(); it.hasNext(); ) { alreadyInCG.add(it.next().method()); } /* * for(Iterator<?> it=cg.sourceMethods();it.hasNext();){ SootMethod m = * (SootMethod)it.next(); alreadyInCG.add(m); if(notInCG.contains(m)){ * notInCG.remove(m); } } */ // add new methods to the call graph Stack<SootMethod> worklist = new Stack<SootMethod>(); for (SootMethod m : notInCG) { worklist.push(m); } while (!worklist.isEmpty()) { SootMethod m = worklist.pop(); if (alreadyInCG.contains(m) || m == null) { continue; } alreadyInCG.add(m); Body body = m.retrieveActiveBody(); for (Unit u : body.getUnits()) { if (!(u instanceof Stmt)) { continue; } Stmt s = (Stmt) u; if (!s.containsInvokeExpr()) { continue; } InvokeExpr invoke = s.getInvokeExpr(); SootMethod declCallee = invoke.getMethod(); Collection<SootMethod> targets = new ArrayList<SootMethod>(); if (declCallee.isStatic()) { targets.add(declCallee); } else { // XXX: pay attention to reflexive call, thread call, and // etc. // Here we do not add edges for implicit targets, as these // parts of methods is not reachable // from the entry, and they will most likely to be analyzed // in a very conservative ways. InstanceInvokeExpr iie = (InstanceInvokeExpr) invoke; Local receiver = (Local) iie.getBase(); NumberedString subSig = iie.getMethodRef().getSubSignature(); if (invoke instanceof SpecialInvokeExpr) { SootMethod tgt = VirtualCalls.v().resolveSpecial((SpecialInvokeExpr) invoke, subSig, m); targets.add(tgt); } else { Type t = receiver.getType(); if (t instanceof ArrayType) { // t = RefType.v("java.lang.Object"); targets.add(declCallee); } // BottomType bug else if (t instanceof soot.jimple.toolkits.typing.fast.BottomType) { System.out.println("BottomType:" + s); } else if (t instanceof soot.NullType) { System.out.println("NullType:" + s); } else { SootClass c = ((RefType) t).getSootClass(); // Soot has a type resolving bug, and here may be // exceptions try { Set<SootMethod> callees = Scene.v().getOrMakeFastHierarchy().resolveAbstractDispatch(c, declCallee); targets.addAll(callees); } catch (Exception e) { System.out.println(e.getMessage()); } } } } for (SootMethod t : targets) { // add call edge Edge e = new Edge(m, s, t); Scene.v().getCallGraph().addEdge(e); // add to worklist if (t.isConcrete() && !alreadyInCG.contains(t)) { worklist.push(t); } } } } // infer entries for the methods not reachable from main entry List<SootMethod> entries = Scene.v().getEntryPoints(); _patchedEntries = new ArrayList<SootMethod>(notInCG); for (SootMethod m : notInCG) { // XXX there can be recursive calls, so for simple processing, all // methods not in old // call graph should be added to the entry. Checking the // non-existence of incoming edges // may miss some recursively called methods // if(!cg.edgesInto(m).hasNext()){ entries.add(m); // } } // update reachable methods Scene.v().setReachableMethods(null); }