public boolean twoValueEquals(Value v1, Value v2) {
   if (v1.toString().equals(v2.toString())
       && v1.getType().toString().equals(v2.getType().toString())) {
     return true;
   }
   return false;
 }
Beispiel #2
0
 private static boolean checkIfIsArrayFunction(
     SootMethod method, InstanceInvokeExpr instanceInvokeExpr) {
   String methodName = method.getName();
   Value base = instanceInvokeExpr.getBase();
   System.out.println(base.getType());
   if (base.getType().toString().equals("android.content.Intent")) {
     if (methodName.startsWith("get") && methodName.contains("Array")) {
       return true;
     }
   }
   return false;
 }
  /** 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;
  }
  /**
   * Returns <code>true</code> if both references may point to the same memory location. The current
   * implementation is conservative, as it does not take any points-to information into account.
   */
  public static boolean maybeSameLocation(Value abstrRef, Value programRef) {
    // arrays are handled through their "base" pointer
    assert !(abstrRef instanceof ArrayRef);
    assert !(programRef instanceof ArrayRef);

    if (abstrRef == programRef) return true;

    // handle primtive types
    Type abstrRefType = abstrRef.getType();
    Type programRefType = programRef.getType();
    if (programRefType instanceof PrimType) {
      // we don't track primitive types, just Strings, ClassLoaders, etc.
      // ...
      return false;
    }
    if (abstrRefType instanceof PrimType) {
      // we don't track primitive types, just Strings, ClassLoaders, etc.
      // ...
      throw new InternalError("abstraction ref type is " + abstrRefType);
    }

    if (abstrRef instanceof Local && programRef instanceof Local) {
      // two locals only point to the same memory locations if they are
      // the same
      return abstrRef == programRef;
    } else if (abstrRef instanceof FieldRef && programRef instanceof FieldRef) {
      FieldRef fieldRef = (FieldRef) abstrRef;
      FieldRef fieldRef2 = (FieldRef) programRef;
      // references point to the same location if class and field name are
      // identical;
      // note that we ignore the receiver object of InstanceFieldRefs
      return fieldRef
              .getField()
              .getDeclaringClass()
              .equals(fieldRef2.getField().getDeclaringClass())
          && fieldRef.getFieldRef().name().equals(fieldRef2.getFieldRef().name());
    } else {
      return false;
    }
  }
  @Override
  public Set<? extends IAllocNode> getPTSet(Value val, Context context) {
    // handle case for insensitive run
    if (k == 0) return getPTSetIns(val);

    final Set<AllocNode> allocNodes = new LinkedHashSet<AllocNode>();
    final Type filteringType = val.getType();

    PointsToSetInternal pts = null;

    try {
      if (val instanceof InstanceFieldRef) {
        final InstanceFieldRef ifr = (InstanceFieldRef) val;
        pts =
            (PointsToSetInternal)
                ptsProvider.reachingObjects(context, (Local) ifr.getBase(), ifr.getField());
      } else if (val instanceof ArrayRef) {
        ArrayRef arrayRef = (ArrayRef) val;
        pts =
            (PointsToSetInternal)
                ptsProvider.reachingObjectsOfArrayElement(
                    ptsProvider.reachingObjects(context, (Local) arrayRef.getBase()));
      } else if (val instanceof Local) {
        pts = (PointsToSetInternal) ptsProvider.reachingObjects(context, (Local) val);
      } else if (val instanceof StaticFieldRef) {
        SootField field = ((StaticFieldRef) val).getField();
        pts = (PointsToSetInternal) ptsProvider.reachingObjects(field);
      } else if (val instanceof NullConstant) {
        return allocNodes;
      } else {
        logger.error("Unknown reference type for insenstive search: {} {}", val, val.getClass());
        droidsafe.main.Main.exit(1);
      }

      // visit internal points to set and grab all allocnodes
      pts.forall(
          new P2SetVisitor() {
            public void visit(Node n) {
              if (typeManager.castNeverFails(n.getType(), filteringType))
                allocNodes.add((AllocNode) n);
            }
          });

    } catch (Exception e) {
      logger.info("Some sort of error getting context insensitive points to set for {}", val, e);
      // e.printStackTrace();
    }

    return allocNodes;
  }
  /**
   * Because the parameter passing in Java is generally pass-by-value, the traditional meaning of
   * reference parameter can hardly be used to judge whether a parameter should be considered in
   * binding in Java.
   *
   * <p>Here we choose use the type of a parameter to determined whether it is mutable.
   * Specifically, we just exclude some common immutable types, such as primitives, their wrappers,
   * and java.lang.String.
   *
   * @param v
   * @return
   */
  private boolean isMutableRefParam(Value v) {
    Type type = v.getType();

    // this condition excludes the primitive types, but not their wrappers
    if (type instanceof RefType) {
      // TODO: test the cases of Java generics
      String typeName = ((RefType) type).getClassName();
      if (commonImmutableTypes.contains(typeName)) {
        return false;
      } else {
        // this is really a conservative design, as there may
        // be a lot of customized immutable types.
        return true;
      }
    } else {
      // if the type is a primitive type or
      // an other special type, e.g., NullType
      return false;
    }
  }
Beispiel #7
0
  /**
   * Returns all possible ref/array types of instances that Value can represent as variables.
   * Returns null if no instance obj can be represented by Value (e.g., static method call).
   */
  private static Set<RefLikeType> getAllPossibleRuntimeRefTypes(Value val) {
    Set<RefLikeType> typeTargets = new HashSet<RefLikeType>();
    // 1.a) NewExpr        (instance)
    if (val instanceof NewExpr) typeTargets.add((RefLikeType) ((NewExpr) val).getType());
    // 1.b) NewArrayExpr   (instance)
    else if (val instanceof NewArrayExpr)
      typeTargets.add((RefLikeType) ((NewArrayExpr) val).getType());
    // 2. InvokeExpr     (static or instance)
    else if (val instanceof InvokeExpr) {
      if (val instanceof StaticInvokeExpr) typeTargets = null; // special case
      else if (val instanceof SpecialInvokeExpr)
        typeTargets.add((RefType) ((SpecialInvokeExpr) val).getBase().getType());
      else {
        assert val instanceof InstanceInvokeExpr;
        SootClass declCls = ((InvokeExpr) val).getMethod().getDeclaringClass();
        typeTargets.add(declCls.getType());

        for (SootClass clsSub : getAllSubtypes(declCls)) typeTargets.add(clsSub.getType());
      }
    }
    // 3. Local/statfield ref var  (instance)
    else if (val instanceof Local || val instanceof StaticFieldRef) {
      RefLikeType lType = (RefLikeType) val.getType();
      typeTargets.add(lType);
      if (lType instanceof RefType) {
        // add all possible subtypes of ref type
        for (SootClass clsSub : getAllSubtypes(((RefType) lType).getSootClass()))
          typeTargets.add(clsSub.getType());
      } else assert lType instanceof ArrayType; // array type has no subtypes
    }
    // 4. StringConstant (instance)
    else {
      assert (val instanceof StringConstant);
      typeTargets.add(Scene.v().getRefType("java.lang.String"));
    }
    return typeTargets;
  }
  private Value generateCorrectObject(Body body, Value value, List<Unit> generated) {
    if (value.getType() instanceof PrimType) {
      // in case of a primitive type, we use boxing (I know it is not nice, but it works...) in
      // order to use the Object type
      if (value.getType() instanceof BooleanType) {
        Local booleanLocal = generateFreshLocal(body, RefType.v("java.lang.Boolean"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Boolean");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Boolean valueOf(boolean)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(booleanLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return booleanLocal;
      } else if (value.getType() instanceof ByteType) {
        Local byteLocal = generateFreshLocal(body, RefType.v("java.lang.Byte"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Byte");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Byte valueOf(byte)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(byteLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return byteLocal;
      } else if (value.getType() instanceof CharType) {
        Local characterLocal = generateFreshLocal(body, RefType.v("java.lang.Character"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Character");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Character valueOf(char)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(characterLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return characterLocal;
      } else if (value.getType() instanceof DoubleType) {
        Local doubleLocal = generateFreshLocal(body, RefType.v("java.lang.Double"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Double");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Double valueOf(double)");

        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(doubleLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return doubleLocal;
      } else if (value.getType() instanceof FloatType) {
        Local floatLocal = generateFreshLocal(body, RefType.v("java.lang.Float"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Float");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Float valueOf(float)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(floatLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return floatLocal;
      } else if (value.getType() instanceof IntType) {
        Local integerLocal = generateFreshLocal(body, RefType.v("java.lang.Integer"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Integer");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Integer valueOf(int)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(integerLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return integerLocal;
      } else if (value.getType() instanceof LongType) {
        Local longLocal = generateFreshLocal(body, RefType.v("java.lang.Long"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Long");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Long valueOf(long)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(longLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return longLocal;
      } else if (value.getType() instanceof ShortType) {
        Local shortLocal = generateFreshLocal(body, RefType.v("java.lang.Short"));

        SootClass sootClass = Scene.v().getSootClass("java.lang.Short");
        SootMethod valueOfMethod = sootClass.getMethod("java.lang.Short valueOf(short)");
        StaticInvokeExpr staticInvokeExpr =
            Jimple.v().newStaticInvokeExpr(valueOfMethod.makeRef(), value);

        Unit newAssignStmt = Jimple.v().newAssignStmt(shortLocal, staticInvokeExpr);
        generated.add(newAssignStmt);

        return shortLocal;
      } else throw new RuntimeException("Ooops, something went all wonky!");
    } else
      // just return the value, there is nothing to box
      return value;
  }
  /**
   * @param cfg
   * @param sink
   * @param assignmentStatement
   */
  private void instrumentSourceToSinkConnections(
      BiDiInterproceduralCFG<Unit, SootMethod> cfg,
      ResultSinkInfo sink,
      boolean assignmentStatement) {
    sourceSinkConnectionCounter += 1;

    // loop through the sinks
    for (ResultSinkInfo key : results.getResults().keySet()) {

      log.debug("compare: " + key);
      log.debug("     to: " + sink);

      // if the current sink is the sink at the unit tagged with 'sink'
      if (key.equals(sink)) {

        // loop through the sources
        for (ResultSourceInfo si : results.getResults().get(key)) {

          Stmt stmt = si.getSource();
          SootMethod sm = cfg.getMethodOf(stmt);
          Body body = sm.retrieveActiveBody();

          // Source instrumentation. The three type categories for the source are:
          // - callback
          // - ICC source method (i.e., Intent.getExtras())
          // - not a callback and not an ICC source method (i.e., getLine1Number())
          //
          if (isInterComponentSourceCallback(si, cfg)) {
            throw new RuntimeException("Callbacks as sources are not supported right now");
          } else if (isInterComponentSourceNoCallback(si, cfg)) {
            // only invoke expression are treated here
            if (stmt.containsInvokeExpr()) {
              // only statements that return a android.os.Bundle are currently supported
              if (stmt instanceof DefinitionStmt) {
                DefinitionStmt defStmt = (DefinitionStmt) stmt;
                Value leftValue = defStmt.getLeftOp();

                if (leftValue.getType().equals(RefType.v("android.os.Bundle"))) {
                  List<Object> args = new ArrayList<Object>();
                  args.add(IntType.v());
                  args.add(IntConstant.v(sourceSinkConnectionCounter));
                  args.add(RefType.v("android.os.Bundle"));
                  args.add(leftValue);
                  InvokeExpr invExpr =
                      Instrumentation.createJimpleStaticInvokeExpr(
                          Settings.INSTRUMENTATION_HELPER_JAVA,
                          "registerNewSourceSinkConnection",
                          args);
                  InvokeStmt invStmt = Jimple.v().newInvokeStmt(invExpr);

                  Unit instrumentationPoint = null;
                  if (stmt instanceof IdentityStmt) {
                    instrumentationPoint = getLastIdentityStmt(body);
                  } else {
                    instrumentationPoint = stmt;
                  }
                  body.getUnits().insertAfter(invStmt, instrumentationPoint);
                  log.debug("insert a: " + invStmt);
                } else {
                  System.err.println("We do only support android.os.Bundle right now!");
                }
              }
            }
          } else {

            String sourceCat = getSourceCategory(si);
            if (sourceCat != null) {
              List<Object> args = new ArrayList<Object>();
              args.add(IntType.v());
              args.add(IntConstant.v(sourceSinkConnectionCounter));
              args.add(RefType.v("java.lang.String"));
              args.add(StringConstant.v(sourceCat));
              InvokeExpr invExpr =
                  Instrumentation.createJimpleStaticInvokeExpr(
                      Settings.INSTRUMENTATION_HELPER_JAVA,
                      "registerNewSourceSinkConnection",
                      args);
              InvokeStmt invStmt = Jimple.v().newInvokeStmt(invExpr);

              Unit instrumentationPoint = null;
              if (stmt instanceof IdentityStmt) instrumentationPoint = getLastIdentityStmt(body);
              else instrumentationPoint = stmt;
              body.getUnits().insertAfter(invStmt, instrumentationPoint);
              log.debug("insert b: " + invStmt);
            }
          }

          // sink instrumentation
          if (sink.getSink().containsInvokeExpr()) {
            Body bodyOfSink = cfg.getMethodOf(key.getSink()).getActiveBody();
            InvokeExpr invExpr = sink.getSink().getInvokeExpr();
            List<Unit> generated = new ArrayList<Unit>();
            generated.addAll(
                instrumentIntentAddings(cfg, stmt, invExpr, results.getResults().get(key)));

            EventInformation sinkEventInfo =
                allEventInformation.get(invExpr.getMethod().getSignature());
            EventInformation sourceEventInfo =
                allEventInformation.get(si.getSource().getInvokeExpr().getMethod().getSignature());

            generated.addAll(
                generatePolicyEnforcementPoint(
                    key.getSink(),
                    invExpr,
                    bodyOfSink,
                    sourceSinkConnectionCounter,
                    assignmentStatement));

            log.debug("body with data flow:\n" + body);
            for (Unit u : generated) {
              log.debug("gen: " + u);
            }

            if (sinkEventInfo.isInstrumentAfterStatement())
              bodyOfSink.getUnits().insertAfter(generated, key.getSink());
            else bodyOfSink.getUnits().insertBefore(generated, key.getSink());
          } else throw new RuntimeException("Double-Check the assumption");
        } // loop through the sources
      } // if the sink at the unit is the current sink
    } // loop through the sinks
  }