private boolean createPlainMethodCall(Local classLocal, SootMethod currentMethod, Body body) { // Do not create calls to lifecycle methods which we handle explicitly if (AndroidEntryPointConstants.getServiceLifecycleMethods().contains(currentMethod.getSubSignature())) return false; JNopStmt beforeStmt = new JNopStmt(); JNopStmt thenStmt = new JNopStmt(); body.getUnits().add(beforeStmt); createIfStmt(thenStmt, body); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); createIfStmt(beforeStmt, body); return true; }
private void generateBroadcastReceiverLifecycle(Set<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal, Body body) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt, body); Stmt onReceiveStmt = searchAndBuildMethod(AndroidEntryPointConstants.BROADCAST_ONRECEIVE, currentClass, entryPoints, classLocal, body); // methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); createIfStmt(endWhileStmt, body); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for (SootMethod currentMethod : currentClass.getMethods()) if (entryPoints.contains(currentMethod.toString())) hasAdditionalMethods |= createPlainMethodCall(classLocal, currentMethod, body); } addCallbackMethods(currentClass, null, "", body); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt, body); createIfStmt(onReceiveStmt, body); }
private void generateContentProviderLifecycle(Set<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal, Body body) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt, body); // ContentProvider.onCreate() runs before everything else, even before // Application.onCreate(). We must thus handle it elsewhere. // Stmt onCreateStmt = // searchAndBuildMethod(AndroidEntryPointConstants.CONTENTPROVIDER_ONCREATE, // currentClass, entryPoints, classLocal); // see: // http://developer.android.com/reference/android/content/ContentProvider.html // methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); createIfStmt(endWhileStmt, body); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for (SootMethod currentMethod : currentClass.getMethods()) if (entryPoints.contains(currentMethod.toString())) hasAdditionalMethods |= createPlainMethodCall(classLocal, currentMethod, body); } addCallbackMethods(currentClass, null, "", body); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt, body); // createIfStmt(onCreateStmt); }
private void addNopStmtToMethods() { for (SootClass c : Scene.v().getClasses()) { for (SootMethod m : c.getMethods()) { if (!m.hasActiveBody()) { continue; } Body b = m.getActiveBody(); b.getUnits().addFirst(new JNopStmt()); } } }
/** * Generates the lifecycle for an Android content provider class * @param entryPoints The list of methods to consider in this class * @param currentClass The class for which to build the content provider * lifecycle * @param endClassStmt The statement to which to jump after completing * the lifecycle * @param classLocal The local referencing an instance of the current class */ private void generateContentProviderLifecycle (Set<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt); // ContentProvider.onCreate() runs before everything else, even before // Application.onCreate(). We must thus handle it elsewhere. // Stmt onCreateStmt = searchAndBuildMethod(AndroidEntryPointConstants.CONTENTPROVIDER_ONCREATE, currentClass, entryPoints, classLocal); // see: http://developer.android.com/reference/android/content/ContentProvider.html //methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); createIfStmt(endWhileStmt); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for (SootMethod currentMethod : currentClass.getMethods()) if (entryPoints.contains(currentMethod.toString())) hasAdditionalMethods |= createPlainMethodCall(classLocal, currentMethod); } addCallbackMethods(currentClass); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt); // createIfStmt(onCreateStmt); }
/** * Generates the lifecycle for an Android broadcast receiver class * @param entryPoints The list of methods to consider in this class * @param currentClass The class for which to build the broadcast receiver * lifecycle * @param endClassStmt The statement to which to jump after completing * the lifecycle * @param classLocal The local referencing an instance of the current class */ private void generateBroadcastReceiverLifecycle (Set<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt); Stmt onReceiveStmt = searchAndBuildMethod(AndroidEntryPointConstants.BROADCAST_ONRECEIVE, currentClass, entryPoints, classLocal); //methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); createIfStmt(endWhileStmt); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for (SootMethod currentMethod : currentClass.getMethods()) if (entryPoints.contains(currentMethod.toString())) hasAdditionalMethods |= createPlainMethodCall(classLocal, currentMethod); } addCallbackMethods(currentClass); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt); createIfStmt(onReceiveStmt); }
private boolean createPlainMethodCall(Local classLocal, SootMethod currentMethod) { // Do not create calls to lifecycle methods which we handle explicitly if(AndroidEntryPointConstants.getServiceLifecycleMethods().contains(currentMethod.getSubSignature())) return false; JNopStmt beforeStmt = new JNopStmt(); JNopStmt thenStmt = new JNopStmt(); body.getUnits().add(beforeStmt); createIfStmt(thenStmt); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); createIfStmt(beforeStmt); return true; }
@Override public String toFIString(Unit u) { StringBuilder sb = new StringBuilder(); boolean printId = Utils.buildBoolProperty("petablox.printrel.printID", false); if (printId) sb.append("(" + indexOf(u) + ")"); String type; if(u instanceof JAssignStmt) type = "Assign"; else if(u instanceof JBreakpointStmt) type = "Breakpoint"; else if(u instanceof JGotoStmt) type = "Goto"; else if(u instanceof JIfStmt) type = "If"; else if(u instanceof JIdentityStmt) type = "Identity"; else if(u instanceof JInvokeStmt) type = "Invoke"; else if(u instanceof JLookupSwitchStmt) type = "LookupSwitch"; else if(u instanceof JNopStmt) type = "Nop"; else if(u instanceof JRetStmt) type = "Return"; else if(u instanceof JTableSwitchStmt) type = "TablelSwitch"; else if(u instanceof JThrowStmt) type = "Throw"; else type = "Other"; sb.append(type); sb.append(": " + SootUtilities.getMethod(u).getName() + "@" + SootUtilities.getMethod(u).getDeclaringClass().getName()); return sb.toString(); }
/** * Generates the lifecycle for an Android content provider class * @param entryPoints The list of methods to consider in this class * @param currentClass The class for which to build the content provider * lifecycle * @param endClassStmt The statement to which to jump after completing * the lifecycle * @param classLocal The local referencing an instance of the current class */ private void generateContentProviderLifecycle (List<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt); // ContentProvider.onCreate() runs before everything else, even before // Application.onCreate(). We must thus handle it elsewhere. // Stmt onCreateStmt = searchAndBuildMethod(AndroidEntryPointConstants.CONTENTPROVIDER_ONCREATE, currentClass, entryPoints, classLocal); // see: http://developer.android.com/reference/android/content/ContentProvider.html //methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for(SootMethod currentMethod : currentClass.getMethods()){ if(entryPoints.contains(currentMethod.toString()) && !AndroidEntryPointConstants.getContentproviderLifecycleMethods().contains(currentMethod.getSubSignature())){ JNopStmt thenStmt = new JNopStmt(); createIfStmt(thenStmt); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); hasAdditionalMethods = true; } } } addCallbackMethods(currentClass); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt); // createIfStmt(onCreateStmt); }
/** * Generates the lifecycle for an Android broadcast receiver class * @param entryPoints The list of methods to consider in this class * @param currentClass The class for which to build the broadcast receiver * lifecycle * @param endClassStmt The statement to which to jump after completing * the lifecycle * @param classLocal The local referencing an instance of the current class */ private void generateBroadcastReceiverLifecycle (List<String> entryPoints, SootClass currentClass, JNopStmt endClassStmt, Local classLocal) { // As we don't know the order in which the different Android lifecycles // run, we allow for each single one of them to be skipped createIfStmt(endClassStmt); Stmt onReceiveStmt = searchAndBuildMethod(AndroidEntryPointConstants.BROADCAST_ONRECEIVE, currentClass, entryPoints, classLocal); //methods JNopStmt startWhileStmt = new JNopStmt(); JNopStmt endWhileStmt = new JNopStmt(); body.getUnits().add(startWhileStmt); boolean hasAdditionalMethods = false; if (modelAdditionalMethods) { for(SootMethod currentMethod : currentClass.getMethods()){ if(entryPoints.contains(currentMethod.toString()) && !AndroidEntryPointConstants.getBroadcastLifecycleMethods().contains(currentMethod.getSubSignature())){ JNopStmt thenStmt = new JNopStmt(); createIfStmt(thenStmt); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); hasAdditionalMethods = true; } } } addCallbackMethods(currentClass); body.getUnits().add(endWhileStmt); if (hasAdditionalMethods) createIfStmt(startWhileStmt); createIfStmt(onReceiveStmt); }
private void addApplicationCallbackMethods(Body body) { if (!this.callbackFunctions.containsKey(applicationClass.getName())) return; // Do not try to generate calls to methods in non-concrete classes if (applicationClass.isAbstract()) return; if (applicationClass.isPhantom()) { System.err.println("Skipping possible application callbacks in " + "phantom class " + applicationClass); return; } for (String methodSig : this.callbackFunctions.get(applicationClass.getName())) { SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(methodSig); // We do not consider lifecycle methods which are directly inserted // at their respective positions if (AndroidEntryPointConstants.getApplicationLifecycleMethods().contains(methodAndClass.getSubSignature())) continue; SootMethod method = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()), methodAndClass.getSubSignature()); // If we found no implementation or if the implementation we found // is in a system class, we skip it. Note that null methods may // happen since all callback interfaces for application callbacks // are registered under the name of the application class. if (method == null) continue; if (method.getDeclaringClass().getName().startsWith("android.") || method.getDeclaringClass().getName().startsWith("java.")) continue; // Get the local instance of the target class Local local = this.localVarsForClasses.get(methodAndClass.getClassName()); if (local == null) { System.err.println( "Could not create call to application callback " + method.getSignature() + ". Local was null."); continue; } // Add a conditional call to the method JNopStmt thenStmt = new JNopStmt(); createIfStmt(thenStmt, body); buildMethodCall(method, body, local, generator); body.getUnits().add(thenStmt); } }
@Override protected void internalTransform(Body b, String phaseName, Map<String, String> options) { b.getUnits().addFirst(new JNopStmt()); }
/** * Adds calls to the callback methods defined in the application class * @param applicationClass The class in which the user-defined application * is implemented * @param applicationLocal The local containing the instance of the * user-defined application */ private void addApplicationCallbackMethods() { if (!this.callbackFunctions.containsKey(applicationClass.getName())) return; // Do not try to generate calls to methods in non-concrete classes if (applicationClass.isAbstract()) return; if (applicationClass.isPhantom()) { System.err.println("Skipping possible application callbacks in " + "phantom class " + applicationClass); return; } for (String methodSig : this.callbackFunctions.get(applicationClass.getName())) { SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(methodSig); // We do not consider lifecycle methods which are directly inserted // at their respective positions if (AndroidEntryPointConstants.getApplicationLifecycleMethods().contains (methodAndClass.getSubSignature())) continue; SootMethod method = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()), methodAndClass.getSubSignature()); // If we found no implementation or if the implementation we found // is in a system class, we skip it. Note that null methods may // happen since all callback interfaces for application callbacks // are registered under the name of the application class. if (method == null) continue; if (method.getDeclaringClass().getName().startsWith("android.") || method.getDeclaringClass().getName().startsWith("java.")) continue; // Get the local instance of the target class Local local = this.localVarsForClasses.get(methodAndClass.getClassName()); if (local == null) { System.err.println("Could not create call to application callback " + method.getSignature() + ". Local was null."); continue; } // Add a conditional call to the method JNopStmt thenStmt = new JNopStmt(); createIfStmt(thenStmt); buildMethodCall(method, body, local, generator); body.getUnits().add(thenStmt); } }
@Override protected SootMethod createDummyMainInternal(SootMethod mainMethod) { Map<String, Set<String>> classMap = SootMethodRepresentationParser.v().parseClassNames(methodsToCall, false); // create new class: Body body = mainMethod.getActiveBody(); LocalGenerator generator = new LocalGenerator(body); HashMap<String, Local> localVarsForClasses = new HashMap<String, Local>(); // create constructors: for(String className : classMap.keySet()){ SootClass createdClass = Scene.v().forceResolve(className, SootClass.BODIES); createdClass.setApplicationClass(); Local localVal = generateClassConstructor(createdClass, body); if (localVal == null) { logger.warn("Cannot generate constructor for class: {}", createdClass); continue; } localVarsForClasses.put(className, localVal); } // add entrypoint calls int conditionCounter = 0; JNopStmt startStmt = new JNopStmt(); JNopStmt endStmt = new JNopStmt(); Value intCounter = generator.generateLocal(IntType.v()); body.getUnits().add(startStmt); for (Entry<String, Set<String>> entry : classMap.entrySet()){ Local classLocal = localVarsForClasses.get(entry.getKey()); for (String method : entry.getValue()){ SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(method); SootMethod currentMethod = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()), methodAndClass.getSubSignature()); if (currentMethod == null) { logger.warn("Entry point not found: {}", method); continue; } JEqExpr cond = new JEqExpr(intCounter, IntConstant.v(conditionCounter)); conditionCounter++; JNopStmt thenStmt = new JNopStmt(); JIfStmt ifStmt = new JIfStmt(cond, thenStmt); body.getUnits().add(ifStmt); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); } } body.getUnits().add(endStmt); JGotoStmt gotoStart = new JGotoStmt(startStmt); body.getUnits().add(gotoStart); body.getUnits().add(Jimple.v().newReturnVoidStmt()); NopEliminator.v().transform(body); eliminateSelfLoops(body); return mainMethod; }
private void visitNopInsts(JNopStmt s) { if (nopVisitors != null) { for (INopInstVisitor v : nopVisitors) v.visit(s); } }
public void visit(JNopStmt s) { add(s); }
/** * Soot requires a main method, so we create a dummy method which calls all entry functions. * * @param classMap * the methods to call (signature as String) * @param createdClass * the class which contains the methods * @return list of entryPoints */ @Override protected SootMethod createDummyMainInternal(List<String> methods) { Map<String, List<String>> classMap = SootMethodRepresentationParser.v().parseClassNames(methods, false); // create new class: JimpleBody body = Jimple.v().newBody(); SootMethod mainMethod = createEmptyMainMethod(body); LocalGenerator generator = new LocalGenerator(body); HashMap<String, Local> localVarsForClasses = new HashMap<String, Local>(); // create constructors: for(String className : classMap.keySet()){ SootClass createdClass = Scene.v().forceResolve(className, SootClass.BODIES); createdClass.setApplicationClass(); Local localVal = generateClassConstructor(createdClass, body); if (localVal == null) { logger.warn("Cannot generate constructor for class: {}", createdClass); continue; } localVarsForClasses.put(className, localVal); } // add entrypoint calls int conditionCounter = 0; JNopStmt startStmt = new JNopStmt(); JNopStmt endStmt = new JNopStmt(); Value intCounter = generator.generateLocal(IntType.v()); body.getUnits().add(startStmt); for (Entry<String, List<String>> entry : classMap.entrySet()){ Local classLocal = localVarsForClasses.get(entry.getKey()); for (String method : entry.getValue()){ SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(method); SootMethod currentMethod = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()), methodAndClass.getSubSignature()); if (currentMethod == null) { logger.warn("Entry point not found: {}", method); continue; } JEqExpr cond = new JEqExpr(intCounter, IntConstant.v(conditionCounter)); conditionCounter++; JNopStmt thenStmt = new JNopStmt(); JIfStmt ifStmt = new JIfStmt(cond, thenStmt); body.getUnits().add(ifStmt); buildMethodCall(currentMethod, body, classLocal, generator); body.getUnits().add(thenStmt); } } body.getUnits().add(endStmt); JGotoStmt gotoStart = new JGotoStmt(startStmt); body.getUnits().add(gotoStart); body.getUnits().add(Jimple.v().newReturnVoidStmt()); return mainMethod; }
public void visit(JNopStmt s);