@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());
  }
Example #2
0
  public static void print() {
    Set<SootMethod> _reachableMethods = Sets.newHashSet();
    Set<SootMethod> _methods = Sets.newHashSet();

    {
      int reachable = 0;
      int reachableAndCallable = 0;
      int concrete = 0;
      int reachableAndCallableWithBody = 0;
      Set<SootClass> reachableClasses = Sets.newHashSet();

      for (Iterator<MethodOrMethodContext> iter = Scene.v().getReachableMethods().listener();
          iter.hasNext(); ) {
        SootMethod m = iter.next().method();
        if (m.isPhantom()) continue;
        reachable++;

        if (m.isConcrete()) {
          _reachableMethods.add(m);
          concrete++;
        }

        if (AnalysisUtil.methodMayBeCallableFromApplication(m)) {
          reachableAndCallable++;
          if (m.hasActiveBody()) reachableAndCallableWithBody++;
        }

        reachableClasses.add(m.getDeclaringClass());
      }
      writeFile(reachableClasses);
      System.out.println("Reachable methods: " + reachable);
      System.out.println("Reachable and concrete methods: " + concrete);
      System.out.println("Reachable and callable methods: " + reachableAndCallable);
      System.out.println(
          "Reachable and callable methods with body: " + reachableAndCallableWithBody);
      System.out.println("Reachable classes: " + reachableClasses.size());
    }

    {
      int classes = 0;
      int methods = 0;
      int callableMethods = 0;
      int reachableAndCallableWithBody = 0;
      int callableAndConcrete = 0;
      int concrete = 0;
      for (SootClass c : Scene.v().getClasses()) {
        if (c.isPhantomClass()) continue;

        classes++;
        for (SootMethod m : c.getMethods()) {
          if (m.isPhantom()) continue;

          if (m.isConcrete()) {
            concrete++;
            _methods.add(m);
          }

          methods++;
          if (AnalysisUtil.methodMayBeCallableFromApplication(m)) {
            callableMethods++;
            if (m.hasActiveBody()) reachableAndCallableWithBody++;
            if (m.isConcrete()) callableAndConcrete++;
          }
        }
      }

      System.out.println("Total methods: " + methods);
      System.out.println("Total concrete methods: " + concrete);
      System.out.println("Total callable methods: " + callableMethods);
      System.out.println("Total callable methods with body: " + reachableAndCallableWithBody);
      System.out.println("Total callable concrete methods: " + callableAndConcrete);
      System.out.println("Total classes: " + classes);
    }

    {
      int classes = 0;
      int methods = 0;
      int callableMethods = 0;
      for (SootClass c : Scene.v().getLibraryClasses()) {

        if (c.isPhantomClass()) continue;

        classes++;
        for (SootMethod m : c.getMethods()) {
          if (m.isPhantom()) continue;

          methods++;
          if (AnalysisUtil.methodMayBeCallableFromApplication(m)) {
            callableMethods++;
          }
        }
      }

      System.out.println("Library methods: " + methods);
      System.out.println("Library callable methods: " + callableMethods);
      System.out.println("Library classes: " + classes);
    }

    {
      int classes = 0;
      int methods = 0;
      int callableMethods = 0;
      for (SootClass c : Scene.v().getApplicationClasses()) {

        if (c.isPhantomClass()) continue;

        classes++;
        for (SootMethod m : c.getMethods()) {
          if (m.isPhantom()) continue;

          methods++;
          if (AnalysisUtil.methodMayBeCallableFromApplication(m)) {
            callableMethods++;
          }
        }
      }

      System.out.println("Application methods: " + methods);
      System.out.println("Application callable methods: " + callableMethods);
      System.out.println("Application classes: " + classes);
    }

    {
      int classes = 0;
      int methods = 0;
      int callableMethods = 0;
      for (SootClass c : Scene.v().getPhantomClasses()) {
        classes++;
        for (SootMethod m : c.getMethods()) {
          if (!m.isPhantom()) continue;

          methods++;
          if (AnalysisUtil.methodMayBeCallableFromApplication(m)) {
            callableMethods++;
          }
        }
      }

      System.out.println("Phantom methods: " + methods);
      System.out.println("Phantom callable methods: " + callableMethods);
      System.out.println("Phantom classes: " + classes);
    }

    // System.out.println("Unreachable methods:");
    // int i = 0;
    // for (SootMethod m : _methods) {
    // if (!_reachableMethods.contains(m)) {
    // System.out.println((++i) + " " + m);
    // }
    // }
  }