public Edge(MethodOrMethodContext src, Stmt srcUnit, MethodOrMethodContext tgt) { this.kind = ieToKind(srcUnit.getInvokeExpr()); this.src = src; this.srcUnit = srcUnit; this.tgt = tgt; }
public List<SootMethod> getExtMethods(SootClass sc) { if (classToExtCalls.containsKey(sc)) { List extCalls = classToExtCalls.get(sc); List<SootMethod> extMethods = new ArrayList<SootMethod>(); for (Iterator callIt = extCalls.iterator(); callIt.hasNext();) { Pair call = (Pair) callIt.next(); SootMethod calledMethod = ((Stmt) call.getO2()).getInvokeExpr().getMethod(); if (!extMethods.contains(calledMethod)) { extMethods.add(calledMethod); } } return extMethods; } throw new RuntimeException("UseFinder does not search non-application classes: " + sc); }
final SootMethod destinationMethod) { Stmt stmt = (Stmt) callStmt; InvokeExpr invokeExpr = stmt.getInvokeExpr(); final List<Value> args = invokeExpr.getArgs();
private void addEdge(SootMethod src, Stmt stmt, SootMethod tgt) { InvokeExpr ie = stmt.getInvokeExpr(); addEdge(src, stmt, tgt, Edge.ieToKind(ie)); }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for (Unit u : b.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { InvokeExpr ie = s.getInvokeExpr(); if (FixedMethods.isFixed(ie)) { System.err.println("+++ " + ie); yes++; } else { System.err.println(" - " + ie); no++; } } } }
@Override public FlowFunction<Value> getReturnFlowFunction(final Unit callSite, SootMethod calleeMethod, final Unit exitStmt, Unit returnSite) { Stmt s = (Stmt) callSite; InvokeExpr ie = s.getInvokeExpr(); final List<Value> callArgs = ie.getArgs(); final List<Local> paramLocals = new ArrayList<Local>(); for (int i = 0; i < calleeMethod.getParameterCount(); i++) { paramLocals.add(calleeMethod.getActiveBody().getParameterLocal(i)); } return new FlowFunction<Value>() { public Set<Value> computeTargets(Value source) { Set<Value> liveParamsAtCallee = new HashSet<Value>(); for (int i = 0; i < paramLocals.size(); i++) { if (paramLocals.get(i).equivTo(source)) { liveParamsAtCallee.add(callArgs.get(i)); } } return liveParamsAtCallee; } }; }
public FlowFunction<Pair<Value, Type>> getCallFlowFunction(final Unit src, final SootMethod dest) { Stmt stmt = (Stmt) src; InvokeExpr ie = stmt.getInvokeExpr(); final List<Value> callArgs = ie.getArgs(); final List<Local> paramLocals = new ArrayList<Local>(); for (int i = 0; i < dest.getParameterCount(); i++) { paramLocals.add(dest.getActiveBody().getParameterLocal(i)); } return new FlowFunction<Pair<Value, Type>>() { public Set<Pair<Value, Type>> computeTargets(Pair<Value, Type> source) { if (!dest.getName().equals("<clinit>") && !dest.getSubSignature().equals("void run()")) { Value value = source.getO1(); int argIndex = callArgs.indexOf(value); if (argIndex > -1) { return Collections.singleton(new Pair<Value, Type>(paramLocals.get(argIndex), source.getO2())); } } return Collections.emptySet(); } }; }
@Override public FlowFunction<Local> getCallFlowFunction(Unit src, final SootMethod dest) { Stmt s = (Stmt) src; InvokeExpr ie = s.getInvokeExpr(); final List<Value> callArgs = ie.getArgs(); final List<Local> paramLocals = new ArrayList<Local>(); for (int i = 0; i < dest.getParameterCount(); i++) { paramLocals.add(dest.getActiveBody().getParameterLocal(i)); } return new FlowFunction<Local>() { public Set<Local> computeTargets(Local source) { // ignore implicit calls to static initializers if (dest.getName().equals(SootMethod.staticInitializerName) && dest.getParameterCount() == 0) { return Collections.emptySet(); } Set<Local> taintsInCaller = new HashSet<Local>(); for (int i = 0; i < callArgs.size(); i++) { if (callArgs.get(i).equivTo(source)) { taintsInCaller.add(paramLocals.get(i)); } } return taintsInCaller; } }; }
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); } } } } } }
@Override public void validate(Body body, List<ValidationException> exceptions) { for (Unit u : body.getUnits()) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { InvokeExpr iinvExpr = s.getInvokeExpr(); SootMethod callee = iinvExpr.getMethod(); if (callee != null && iinvExpr.getArgCount() != callee.getParameterCount()) { exceptions.add(new ValidationException(s, "Invalid number of arguments")); } } } }
public void defaultFeedPtsRoutines() { switch (Parameters.seedPts) { case Constants.seedPts_allUser: setAllUserCodeVariablesUseful(); break; case Constants.seedPts_all: // All pointers will be processed for (int i = 0; i < n_var; ++i) { IVarAbstraction pn = int2var.get(i); if (pn != null && pn.getRepresentative() == pn) { pn.willUpdate = true; } } return; } // We always refine the callsites that have multiple call targets Set<Node> multiBaseptrs = new HashSet<Node>(); for (Stmt callsite : geomPTA.multiCallsites) { InstanceInvokeExpr iie = (InstanceInvokeExpr) callsite.getInvokeExpr(); VarNode vn = geomPTA.findLocalVarNode(iie.getBase()); multiBaseptrs.add(vn); } addUserDefPts(multiBaseptrs); }
@Override public void methodInvoke(SootMethod container, Stmt invokeStmt) { if (container.getDeclaringClass().isJavaLibraryClass()) { super.methodInvoke(container, invokeStmt); return; } InstanceInvokeExpr d = (InstanceInvokeExpr) invokeStmt.getInvokeExpr(); Value base = d.getArg(0); // TODO no support for statics at the moment // SA: Better just fall back to degraded functionality than fail // altogether if (!(base instanceof Local)) { super.methodInvoke(container, invokeStmt); return; } addInvokeCallSite(invokeStmt, container, d); } }
@Override public void validate(Body body, List<ValidationException> exception) { for (Unit u : body.getUnits()) { if (u instanceof Stmt) { Stmt stmt = (Stmt) u; if (stmt.containsInvokeExpr()) { InvokeExpr iexpr = stmt.getInvokeExpr(); SootMethodRef ref = iexpr.getMethodRef(); if (ref.name().contains("'") || ref.declaringClass().getName().contains("'")) { throw new ValidationException(stmt, "Escaped name in signature found"); } for (Type paramType : ref.parameterTypes()) { if (paramType.toString().contains("'")) { throw new ValidationException(stmt, "Escaped name in signature found"); } } } } } }
public static int getOutWordCount(Collection<Unit> units) { int outWords = 0; for (Unit u : units) { Stmt stmt = (Stmt) u; if (stmt.containsInvokeExpr()) { int wordsForParameters = 0; InvokeExpr invocation = stmt.getInvokeExpr(); List<Value> args = invocation.getArgs(); for (Value arg : args) { wordsForParameters += getDexWords(arg.getType()); } if (!invocation.getMethod().isStatic()) { wordsForParameters++; // extra word for "this" } if (wordsForParameters > outWords) { outWords = wordsForParameters; } } } return outWords; }
public static boolean checkSpecialInlineRestrictions(SootMethod container, SootMethod target, String options) { // Check the body of the method to inline for specialinvoke's boolean accessors = options.equals("accessors"); Body inlineeBody = target.getActiveBody(); Iterator unitsIt = inlineeBody.getUnits().iterator(); while (unitsIt.hasNext()) { Stmt st = (Stmt) unitsIt.next(); if (st.containsInvokeExpr()) { InvokeExpr ie1 = st.getInvokeExpr(); if (ie1 instanceof SpecialInvokeExpr) { if ((InlinerSafetyManager.specialInvokePerformsLookupIn(ie1, container.getDeclaringClass()) || InlinerSafetyManager.specialInvokePerformsLookupIn(ie1, target.getDeclaringClass()))) { return false; } SootMethod specialTarget = ie1.getMethod(); if (specialTarget.isPrivate()) { if (specialTarget.getDeclaringClass() != container.getDeclaringClass()) { // Do not inline a call which contains a specialinvoke call to a private method outside // the current class. This avoids a verifier error and we assume will not have a big // impact because we are inlining methods bottom-up, so such a call will be rare if (!accessors) { return false; } } } } } } return true; }
/** * @param stmt * any statement containing an InvokeExpr * * @see PurityGraph.methodCall */ @Override protected void applySummary(PurityGraphBox src, Stmt stmt, PurityGraphBox summary, PurityGraphBox dst) { // extract call info InvokeExpr e = stmt.getInvokeExpr(); Local ret = null; if (stmt instanceof AssignStmt) { Local v = (Local) ((AssignStmt) stmt).getLeftOp(); if (v.getType() instanceof RefLikeType) { ret = v; } } Local obj = null; if (!(e instanceof StaticInvokeExpr)) { obj = (Local) ((InstanceInvokeExpr) e).getBase(); } List<Value> args = e.getArgs(); // call methoCall on the PurityGraph PurityGraph g = new PurityGraph(src.g); g.methodCall(summary.g, obj, args, ret); dst.g = g; }
/** * Obtain the set of possible call targets at given @param callsite. */ private void getCallTargets(IVarAbstraction pn, SootMethod src, Stmt callsite, ChunkedQueue<SootMethod> targetsQueue) { InstanceInvokeExpr iie = (InstanceInvokeExpr) callsite.getInvokeExpr(); Local receiver = (Local) iie.getBase(); NumberedString subSig = iie.getMethodRef().getSubSignature(); // We first build the set of possible call targets for (AllocNode an : pn.get_all_points_to_objects()) { Type type = an.getType(); if (type == null) { continue; } VirtualCalls.v().resolve(type, receiver.getType(), subSig, src, targetsQueue); } }
public static boolean checkAccessRestrictions(SootMethod container, SootMethod target, String modifierOptions) { // Check the body of the method to inline for // method or field access restrictions { Body inlineeBody = target.getActiveBody(); Iterator unitsIt = inlineeBody.getUnits().iterator(); while (unitsIt.hasNext()) { Stmt st = (Stmt) unitsIt.next(); if (st.containsInvokeExpr()) { InvokeExpr ie1 = st.getInvokeExpr(); if (!AccessManager.ensureAccess(container, ie1.getMethod(), modifierOptions)) { return false; } } if (st instanceof AssignStmt) { Value lhs = ((AssignStmt) st).getLeftOp(); Value rhs = ((AssignStmt) st).getRightOp(); if (lhs instanceof FieldRef && !AccessManager.ensureAccess(container, ((FieldRef) lhs).getField(), modifierOptions)) { return false; } if (rhs instanceof FieldRef && !AccessManager.ensureAccess(container, ((FieldRef) rhs).getField(), modifierOptions)) { return false; } } } } return true; }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { for (Iterator<Unit> unitIt = b.getUnits().snapshotIterator(); unitIt.hasNext();) { Unit u = unitIt.next(); if (u instanceof Stmt) { Stmt s = (Stmt) u; if (s.containsInvokeExpr()) { InvokeExpr iexpr = s.getInvokeExpr(); if (iexpr instanceof StaticInvokeExpr) { if (isClassLoaded(iexpr.getMethodRef().declaringClass())) { SootMethod target = Scene.v().grabMethod(iexpr.getMethodRef().getSignature()); if (target != null && !target.isStatic()) { if (canBeMadeStatic(target)) { // Remove the this-assignment to prevent // 'this-assignment in a static method!' exception target.getActiveBody().getUnits().remove(target.getActiveBody().getThisUnit()); target.setModifiers(target.getModifiers() | Modifier.STATIC); logger.warn(target.getName() + " changed into a static method"); } } } } } } } }
/** * Returns true if the statement <code>stmt</code> contains an illegal access to a field or method, assuming the statement * is in method <code>container</code> * * @param container * @param stmt * @return */ public static boolean isAccessLegal(SootMethod container, Stmt stmt) { if (stmt.containsInvokeExpr()) { return AccessManager.isAccessLegal(container, stmt.getInvokeExpr().getMethod()); } else if (stmt instanceof AssignStmt) { AssignStmt as = (AssignStmt) stmt; if (as.getRightOp() instanceof FieldRef) { FieldRef r = (FieldRef) as.getRightOp(); return AccessManager.isAccessLegal(container, r.getField()); } if (as.getLeftOp() instanceof FieldRef) { FieldRef r = (FieldRef) as.getLeftOp(); return AccessManager.isAccessLegal(container, r.getField()); } } return true; }