@Override public KillGenInfo propagateReturnFlow( Trackable trackable, Unit callSite, SootMethod calleeMethod, Unit exitStmt, Unit returnSite) { boolean isSeedMethod = seedMethods.contains(context.icfg.getMethodOf(exitStmt)); if (!(exitStmt instanceof ReturnStmt)) return new KillGenInfo(isSeedMethod, Collections.<Trackable>emptyList()); Taint taint = (Taint) trackable; ReturnStmt returnStmt = (ReturnStmt) exitStmt; Value retVal = AnalysisUtil.getForwardsBase(returnStmt.getOp()); if (isSeedMethod && AnalysisUtil.maybeSameLocation(taint.value, retVal)) { SootMethod m = context.icfg.getMethodOf(returnStmt); if (AnalysisUtil.methodMayBeCallableFromApplication(m)) { if (!trackable.getPayload().isEmpty()) { context.reporter.reportTrackable(new Report(context, taint, exitStmt)); } } } return new KillGenInfo(isSeedMethod, Collections.<Trackable>emptyList()); }
@Override public Type appliesInternal(AndroidMethod method) { SootMethod sm = getSootMethod(method); // We are only interested in getters and setters if (!sm.getName().startsWith("get") && !sm.getName().startsWith("set")) return Type.NOT_SUPPORTED; String baseName = sm.getName().substring(3); String getterName = "get" + baseName; String setterName = "set" + baseName; try { // Find the getter and the setter SootMethod getter = getSootMethod(new AndroidMethod(getterName, "", sm.getDeclaringClass().getName())); SootMethod setter = getSootMethod(new AndroidMethod(setterName, "", sm.getDeclaringClass().getName())); if (getter == null || setter == null) return Type.FALSE; if (!setter.isConcrete() || !getter.isConcrete()) return Type.NOT_SUPPORTED; Body bodyGetter = null; try { bodyGetter = getter.retrieveActiveBody(); } catch (Exception ex) { return Type.NOT_SUPPORTED; } // Find the local that gets returned Local returnLocal = null; for (Unit u : bodyGetter.getUnits()) if (u instanceof ReturnStmt) { ReturnStmt ret = (ReturnStmt) u; if (ret.getOp() instanceof Local) { returnLocal = (Local) ret.getOp(); break; } } if (returnLocal == null) return Type.FALSE; // Find where the local is assigned a value in the code List<FieldRef> accessPath = new ArrayList<FieldRef>(); Local returnBase = returnLocal; while (returnBase != null) for (Unit u : bodyGetter.getUnits()) { if (u instanceof AssignStmt) { AssignStmt assign = (AssignStmt) u; if (assign.getLeftOp().equals(returnBase)) if (assign.getRightOp() instanceof InstanceFieldRef) { InstanceFieldRef ref = (InstanceFieldRef) assign.getRightOp(); accessPath.add(0, ref); returnBase = (Local) ref.getBase(); break; } else returnBase = null; } else if (u instanceof IdentityStmt) { IdentityStmt id = (IdentityStmt) u; if (id.getLeftOp().equals(returnBase)) returnBase = null; } } if (accessPath.isEmpty()) return Type.FALSE; /* // Find the corresponding access path in the setter for (Unit u : bodySetter.getUnits()) if (u instanceof AssignStmt) { AssignStmt assign = (AssignStmt) u; if (assign.getLeftOp() instanceof InstanceFieldRef && assign.getRightOp() instanceof Local) { InstanceFieldRef iref = (InstanceFieldRef) assign.getLeftOp(); if (iref.getFieldRef().toString().equals(accessPath.get(accessPath.size() - 1).getFieldRef().toString())) { // This is a starting point boolean pathFound = false; Local startLocal = (Local) iref.getBase(); int accessPathPos = accessPath.size() - 2; while (startLocal != null) { for (Unit u2 : bodySetter.getUnits()) { if (u2 instanceof AssignStmt) { AssignStmt assign2 = (AssignStmt) u2; if (assign2.getLeftOp().equals(startLocal)) if (assign2.getRightOp() instanceof InstanceFieldRef) { InstanceFieldRef ref = (InstanceFieldRef) assign2.getRightOp(); if (accessPath.get(accessPathPos--).getFieldRef().toString().equals(ref.getFieldRef().toString())) { startLocal = (Local) ref.getBase(); break; } else startLocal = null; } else startLocal = null; } else if (u2 instanceof IdentityStmt) { IdentityStmt id = (IdentityStmt) u2; if (id.getLeftOp().equals(startLocal)) { startLocal = null; pathFound = true; break; } } } } if (pathFound) { if (assign.getRightOp() instanceof Local) { // Find the parameter being set for (Unit u2 : bodySetter.getUnits()) if (u2 instanceof IdentityStmt) { IdentityStmt id = (IdentityStmt) u2; if (id.getLeftOp().equals(assign.getRightOp())) return Type.TRUE; } } break; } } } } return Type.FALSE; */ return Type.TRUE; } catch (Exception ex) { System.err.println("Something went wrong:"); ex.printStackTrace(); return Type.NOT_SUPPORTED; } }