/** * Returns true if a method call is fixed, i.e., assuming that all classes in the Scene resemble library code, then client * code cannot possible overwrite the called method. This is trivially true for InvokeStatic and InvokeSpecial, but can * also hold for virtual invokes if all possible call targets in the library cannot be overwritten. * * @see #clientOverwriteableOverwrites(SootMethod) */ public static boolean isFixed(InvokeExpr ie) { return ie instanceof StaticInvokeExpr || ie instanceof SpecialInvokeExpr || !clientOverwriteableOverwrites(ie.getMethod()); }
private static SootMethod getMethodSafely(InvokeExpr invokeExpr) { try { final SootMethod invokedMethod = invokeExpr.getMethod(); if (invokedMethod == null) { return null; } if (SootMethod.constructorName.equals(invokedMethod.getName()) || SootMethod.staticInitializerName.equals(invokedMethod.getName())) { logger.debug("Skipping wrapping method {} as it is constructor/initializer.", invokedMethod); return null; } final SootClass invokedMethodClass = invokedMethod.getDeclaringClass(); if (!invokedMethodClass.isLibraryClass()) { logger.debug("Skipping wrapping method {} as it is not library one.", invokedMethod); return null; } if (invokeExpr.getMethodRef().declaringClass().isInterface() && !invokedMethodClass.isInterface()) { logger.debug( "Skipping wrapping method {} as original code suppose to execute it on interface {}" + " but resolved code trying to execute it on class {}", invokedMethod, invokeExpr.getMethodRef().declaringClass(), invokedMethodClass); return null; } return invokedMethod; } catch (RuntimeException exception) { logger.debug("Cannot resolve method of InvokeExpr: " + invokeExpr.toString(), exception); return null; } }
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); }
: ie.getMethod().getExceptionsUnsafe(); if (exceptions == null) { return;
public void analyseInvokeExpr(InvokeExpr ie) { curExceptionSet.addAll(ie.getMethod().getExceptions()); }
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")); } } } }
SootMethod method = ((InvokeExpr) invokeExpr).getMethod();
static boolean specialInvokePerformsLookupIn(InvokeExpr ie, SootClass containerClass) { // If all of the conditions are true, a lookup is performed. SootMethod m = ie.getMethod(); if (m.getName().equals("<init>")) { return false; } if (m.isPrivate()) { return false; } Hierarchy h = Scene.v().getActiveHierarchy(); if (!h.isClassSuperclassOf(m.getDeclaringClass(), containerClass)) { return false; } // ACC_SUPER must always be set, eh? return true; } }
if (ie instanceof InstanceInvokeExpr) { InstanceInvokeExpr iie = (InstanceInvokeExpr) ie; SootMethod invokeMethod = ie.getMethod(); if (invokeMethod.getName().equals("start")) { RefType baseType = (RefType) iie.getBase().getType();
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; }
public void inInvokeStmt(InvokeStmt s) { InvokeExpr invokeExpr = s.getInvokeExpr(); SootMethod maybeInline = invokeExpr.getMethod();
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; }
if (stmt.containsInvokeExpr()) { InvokeExpr inv = stmt.getInvokeExpr(); curStmtSet = mightThrow(inv.getMethod(), doneSet); } else { curStmtSet = mightThrow(u);
if (invokeExpr.getMethod().getSignature().equals(INVOKE_SIG)) { if (invokeExpr.getArg(0) instanceof StringConstant) {
/** * 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; }