Example #1
0
  /** Count taint on prims or strings */
  private static Set<InfoValue> getTaintSet(Value v, MethodOrMethodContext momc) {
    Set<InfoValue> taints = null;

    if (v instanceof Local && v.getType() instanceof PrimType) {
      taints = InformationFlowAnalysis.v().getTaints(momc, (Local) v);
    } else if (PTABridge.v().isPointer(v) && SootUtils.isStringOrSimilarType(v.getType())) {
      taints = new HashSet<InfoValue>();
      for (IAllocNode node : PTABridge.v().getPTSet(v, momc.context())) {
        taints.addAll(InformationFlowAnalysis.v().getTaints(node, momc));
      }
    }

    return taints;
  }
  /**
   * Clone non-static ancestor methods that are not hidden by virtual dispatch and that are
   * reachable based on a pta run.
   */
  private void cloneReachableNonHiddenAncestorMethods(SootClass ancestor) {
    if (ClassCloner.isClonedClass(ancestor)) {
      logger.error("Cloning method from clone: {}", ancestor);
      droidsafe.main.Main.exit(1);
    }

    // create all methods, cloning body, replacing instance field refs
    for (SootMethod ancestorM : ancestor.getMethods()) {
      if (ancestorM.isAbstract()
          || ancestorM.isPhantom()
          || !ancestorM.isConcrete()
          || SootUtils.isRuntimeStubMethod(ancestorM)) continue;

      // never clone static methods
      if (ancestorM.isStatic()) continue;

      // clone only reachable methods
      if (!cloneAllMethods && !PTABridge.v().getReachableMethods().contains(ancestorM)) continue;

      // check if this method already exists
      if (containsMethod(ancestorM.getSignature())) {
        // System.out.printf("\tAlready contains method %s.\n", ancestorM);
        continue;
      }

      // turn off final for ancestor methods
      if (ancestorM.isFinal()) ancestorM.setModifiers(ancestorM.getModifiers() ^ Modifier.FINAL);

      cloneMethod(ancestorM, ancestorM.getName());
    }
  }
Example #3
0
  private static String getReachableLines() {
    int totalReachableLines = 0;

    for (SootMethod sm : PTABridge.v().getReachableMethods()) {
      totalReachableLines += SootUtils.getNumLines(sm);
    }

    return Integer.toString(totalReachableLines);
  }
Example #4
0
  private static String finegrainedFlowResults() {
    int totalReachableIfs = 0;
    int taintedReachableIfs = 0;

    int totalCountOfTaintSets = 0;
    int totalSizeOfTaintSets = 0;

    long totalValues = 0;

    Set<InfoValue> allSrcs = new HashSet<InfoValue>();
    Set<Set<InfoValue>> allSrcSets = new HashSet<Set<InfoValue>>();

    StringBuffer buf = new StringBuffer();

    for (MethodOrMethodContext momc : PTABridge.v().getReachableMethodContexts()) {
      // reset counted locals for each method
      Set<Value> countedLocals = new HashSet<Value>();

      SootMethod method = momc.method();

      if (!method.isConcrete()) continue;
      try {
        Body body = method.retrieveActiveBody();

        Iterator<Unit> unitIt = body.getUnits().snapshotIterator();

        while (unitIt.hasNext()) {
          Stmt stmt = (Stmt) unitIt.next();

          for (ValueBox vb : stmt.getUseAndDefBoxes()) {
            Value v = vb.getValue();

            if (countedLocals.contains(v)) continue;

            countedLocals.add(v);

            Set<InfoValue> taints = getTaintSet(v, momc);

            if (taints != null) totalValues++;

            if (taints != null && !taints.isEmpty()) {
              allSrcs.addAll(taints);

              totalCountOfTaintSets++;
              totalSizeOfTaintSets += taints.size();

              if (!allSrcSets.contains(taints)) allSrcSets.add(taints);

              countedLocals.add(v);
            }
          }

          if (stmt instanceof IfStmt) {
            totalReachableIfs++;
            boolean hasTainted = false;

            for (ValueBox vb : stmt.getUseBoxes()) {
              Value v = vb.getValue();

              Set<InfoValue> taints = getTaintSet(v, momc);

              if (taints != null && !taints.isEmpty()) {
                hasTainted = true;
                break;
              }
            }

            totalReachableIfs++;

            if (hasTainted) {
              taintedReachableIfs++;
            }
          }
        }

      } catch (Exception e) {
        // ignore and continue
      }
    }

    buf.append("Tainted Reachable if statements: " + taintedReachableIfs + "\n");
    buf.append("Total Reachable if Statements: " + totalReachableIfs + "\n");
    buf.append(
        "Count of non-zero taint sets for primitives and strings: " + totalCountOfTaintSets + "\n");
    buf.append(
        "Total distinct reachable primitives or string values in code: " + totalValues + "\n");
    buf.append(
        "Total size of non-zero taint sets for primitives and strings: "
            + totalSizeOfTaintSets
            + "\n");
    buf.append("Count of distinct sources: " + allSrcs.size() + "\n");
    buf.append("Total distinct source sets: " + allSrcSets.size() + "\n");

    return buf.toString();
  }
  @Override
  public void tranformsInvoke(
      SootMethod containingMthd, SootMethod callee, InvokeExpr invokeExpr, Stmt stmt, Body body) {

    if (!Project.v().isSrcClass(containingMthd.getDeclaringClass())) {
      return;
    }

    if (modified.contains(stmt)) {
      return;
    }
    modified.add(stmt);

    IntentResolutionStats.v().contentProviderOps++;

    Value lvalue = null;
    if (stmt instanceof AssignStmt) {
      lvalue = ((AssignStmt) stmt).getLeftOp();
    }

    Set<SootField> targetCPFields = new LinkedHashSet<SootField>();

    boolean resolved = true;

    for (IAllocNode node : PTABridge.v().getPTSetIns(invokeExpr.getArg(0))) {
      resolved = addToTargets(node, targetCPFields, stmt);

      if (!resolved) {
        UnresolvedICC.v().addInfo(stmt, callee, "Unresolved URI for Content Provider");
        // can break here because we added all possible content provider destinations
        IntentResolutionStats.v().contentProviderOpsUnresolvedUri++;
        break;
      }
    }

    // for each field of harness that is a content provider
    for (SootField cpField : targetCPFields) {
      SootClass cpClass = ((RefType) cpField.getType()).getSootClass();
      SootMethod target = cpClass.getMethod(callee.getSubSignature());

      // create local and add to body
      Local local = Jimple.v().newLocal("_$contentprovider_local_" + localID++, cpField.getType());
      body.getLocals().add(local);

      // set field of cp to local [local = harness.contentproviderfield]
      // set local to field
      Stmt localAssign =
          Jimple.v().newAssignStmt(local, Jimple.v().newStaticFieldRef(cpField.makeRef()));
      // insert before original statement
      body.getUnits().insertBefore(localAssign, stmt);

      InvokeExpr newInvoke =
          Jimple.v().newVirtualInvokeExpr(local, target.makeRef(), invokeExpr.getArgs());

      // create statement to invoke
      Stmt toInsert = null;
      if (lvalue == null) {
        // original call not in an assign;
        toInsert = Jimple.v().newInvokeStmt(newInvoke);
      } else {
        // original call in an assign
        toInsert = Jimple.v().newAssignStmt(lvalue, newInvoke);
      }
      // insert after original statement just to have all locals assigned in a block
      body.getUnits().insertAfter(toInsert, stmt);
      logger.info(
          "Adding {} call to ContentProvider {} in method {}",
          callee.getSubSignature(),
          cpClass,
          containingMthd);

      // ignore generated calls in rcfg
      RCFG.v().ignoreInvokeForOutputEvents(toInsert);
    }

    // if resolved and in app target, then don't report
    if (resolved) {
      IntentResolutionStats.v().contentProviderOpsResolvedUri++;
      if (targetCPFields.size() > 0) {
        RCFG.v().ignoreInvokeForOutputEvents(stmt);
        IntentResolutionStats.v().contentProviderOpsInAppTotalTargets += targetCPFields.size();
      } else {
        IntentResolutionStats.v().contentProviderOpsInterAppTarget++;
      }
    }
  }