Beispiel #1
1
  public JDynamicInvokeExpr(
      SootMethodRef bootstrapMethodRef,
      List<Value> bootstrapArgs,
      SootMethodRef methodRef,
      List<Value> methodArgs) {
    if (!methodRef.getSignature().startsWith("<" + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME + ": "))
      throw new IllegalArgumentException(
          "Receiver type of JDynamicInvokeExpr must be "
              + SootClass.INVOKEDYNAMIC_DUMMY_CLASS_NAME
              + "!");
    if (!bootstrapMethodRef.returnType().equals(RefType.v("java.lang.invoke.CallSite"))) {
      throw new IllegalArgumentException(
          "Return type of bootstrap method must be java.lang.invoke.CallSite!");
    }

    this.bsmRef = bootstrapMethodRef;
    this.methodRef = methodRef;
    this.bsmArgBoxes = new ValueBox[bootstrapArgs.size()];
    this.argBoxes = new ValueBox[methodArgs.size()];

    for (int i = 0; i < bootstrapArgs.size(); i++) {
      // RoboVM note: Changed to handle InvokeExpr values in bootstrap args
      Value v = bootstrapArgs.get(i);
      if (v instanceof InvokeExpr) {
        this.bsmArgBoxes[i] = Jimple.v().newInvokeExprBox(v);
      } else {
        this.bsmArgBoxes[i] = Jimple.v().newImmediateBox(v);
      }
    }
    for (int i = 0; i < methodArgs.size(); i++) {
      this.argBoxes[i] = Jimple.v().newImmediateBox((Value) methodArgs.get(i));
    }
  }
 private SootMethodRef remapRef(SootMethodRef ref) {
   Type return_type = fixType(ref.returnType());
   List params = fixParameterList(ref.parameterTypes());
   int modifiers = Modifier.PUBLIC;
   if (ref.isStatic()) {
     modifiers += Modifier.STATIC;
   }
   SootMethod method = new SootMethod(ref.name(), params, return_type, modifiers);
   SootClass decl_class = ref.declaringClass();
   if (shouldMap(decl_class)) {
     decl_class = getMapping(decl_class);
   }
   method.setDeclaringClass(decl_class);
   return method.makeRef();
 }
Beispiel #3
0
 @SuppressWarnings("unchecked")
 public static FunctionType getFunctionType(SootMethodRef methodRef) {
   Type returnType = getType(methodRef.returnType());
   Type[] paramTypes =
       new Type[(methodRef.isStatic() ? 1 : 2) + methodRef.parameterTypes().size()];
   int i = 0;
   paramTypes[i++] = ENV_PTR;
   if (!methodRef.isStatic()) {
     paramTypes[i++] = OBJECT_PTR;
   }
   for (soot.Type t : (List<soot.Type>) methodRef.parameterTypes()) {
     paramTypes[i++] = getType(t);
   }
   return new FunctionType(returnType, paramTypes);
 }
Beispiel #4
0
  public String toString() {
    StringBuffer buffer = new StringBuffer();

    buffer.append(Jimple.DYNAMICINVOKE);
    buffer.append(" \"");
    buffer.append(methodRef.name()); // quoted method name (can be any UTF8 string)
    buffer.append("\" <");
    buffer.append(
        SootMethod.getSubSignature(
            "" /* no method name here*/, methodRef.parameterTypes(), methodRef.returnType()));
    buffer.append(">(");

    for (int i = 0; i < argBoxes.length; i++) {
      if (i != 0) buffer.append(", ");

      buffer.append(argBoxes[i].getValue().toString());
    }

    buffer.append(") ");

    buffer.append(bsmRef.getSignature());
    buffer.append("(");
    for (int i = 0; i < bsmArgBoxes.length; i++) {
      if (i != 0) buffer.append(", ");

      buffer.append(bsmArgBoxes[i].getValue().toString());
    }
    buffer.append(")");

    return buffer.toString();
  }
Beispiel #5
0
  /**
   * Finds in class hierarchy and returns all app and lib concrete methods possibly referenced by
   * method ref. Method is assumed to be virtual (not special or static). Returns true if there are
   * library methods among targets found.
   */
  public static boolean getConcreteCallTargets(
      InvokeExpr instInvExpr, /*OUT*/
      Set<SootMethod> appTargets, /*OUT*/
      Set<SootMethod> libTargets) {
    // get class of method ref; we start searching from this class
    SootMethodRef mref = instInvExpr.getMethodRef();
    SootClass cls = mref.declaringClass(); // starting class
    final NumberedString subsignature = mref.getSubSignature(); // signature to search for

    // CASE 1: object is of declared class type or inherited from some superclass
    //         find first superclass, starting from current cls, that declares method; there HAS to
    // be such a class
    // note that if cls is interface, superclass if java.lang.Object
    // note that we don't check if there is indeed an interface declaring the method; we assume this
    // is the case if no superclass declares it
    while (!cls.declaresMethod(subsignature) && cls.hasSuperclass())
      cls = cls.getSuperclass(); // never an interface
    // now, method might not be in superclass, or might be abstract; in that case, it's not a target
    SootMethod m;
    if (cls.declaresMethod(subsignature)) {
      m = cls.getMethod(subsignature);
      if (!m.isAbstract()) {
        if (cls.hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method
        else libTargets.add(m); // add lib method
      }
    }

    // (only for virtual/interface calls)
    // CASE 2: object's actual type is a subclass; any subclass declaring the method is a possible
    // target
    //         we have to check all superclasses of implementers, because starting cls might be
    // interface
    if (instInvExpr instanceof VirtualInvokeExpr || instInvExpr instanceof InterfaceInvokeExpr) {
      cls = mref.declaringClass(); // start again from declaring class
      List<SootClass> allSubclasses = getAllSubtypes(cls);
      for (SootClass subCls : allSubclasses) {
        m = getMethodInClassOrSuperclass(subCls, subsignature);
        if (m != null && !m.isAbstract()) {
          if (m.getDeclaringClass().hasTag(ClassTag.TAG_NAME)) appTargets.add(m); // add app method
          else libTargets.add(m); // add lib method
        }
      }
    }

    return !libTargets.isEmpty();
  }
Beispiel #6
0
  public void outAStaticInvokeExpr(AStaticInvokeExpr node) {
    List args;

    if (node.getArgList() != null) args = (List) mProductions.removeLast();
    else args = new ArrayList();

    SootMethodRef method = (SootMethodRef) mProductions.removeLast();
    method =
        Scene.v()
            .makeMethodRef(
                method.declaringClass(),
                method.name(),
                method.parameterTypes(),
                method.returnType(),
                true);

    mProductions.addLast(Jimple.v().newStaticInvokeExpr(method, args));
  }
  /** Dumps out the call chain in json format * */
  public void dump_json(PrintStream fp, String indent) {
    fp.printf("%s{ %s,\n", indent, json_field("type", type));
    fp.printf("%s  %s,\n", indent, json_field("link", link));
    String sig = method.getSignature();
    fp.printf("%s  %s,\n", indent, json_field("signature", sig));
    if (stmt != null) {
      SootMethodRef invoke = stmt.getInvokeExpr().getMethodRef();
      String invokeSig;
      try {
        SootMethod concrete = SootUtils.resolve(stmt.getInvokeExpr().getMethodRef());
        invokeSig = concrete.getSignature();
      } catch (CannotFindMethodException e1) {
        logger.debug("Cannot find concrete method for {} in SourceCallChainInfo.dump_json()", stmt);
        invokeSig = invoke.getSignature();
      }
      if (!invokeSig.equals(sig)) {
        fp.printf("%s  %s,\n", indent, json_field("source-signature", invokeSig));
      }
    }
    SourceLocationTag slt =
        (stmt == null) ? SootUtils.getMethodLocation(method) : getSourceLocation(stmt);
    if (slt != null) {
      fp.printf("%s  %s", indent, json_field("src-loc"));
      fp.printf(
          "{ %s, %s},\n", json_field("class", slt.getClz()), json_field("line", slt.getLine()));
    }
    fp.printf("%s  %s,\n", indent, json_field("syscalls", syscalls));
    fp.printf("%s  %s,\n", indent, json_field("calls", calls));

    if ((contents != null) && (contents.length > 0)) {
      fp.printf("%s  %s,\n", indent, json_field("score", score));
      fp.printf("%s  %s [\n", indent, json_field("contents"));
      String delim = "";
      for (SourceCallChainInfo cci : contents) {
        fp.print(delim);
        delim = ",\n";
        cci.dump_json(fp, indent + "  ");
      }
      fp.printf("\n%s]}", indent);
    } else {
      fp.printf("%s  %s\n", indent, json_field("score", score));
      fp.printf("%s}", indent);
    }
  }
Beispiel #8
0
  /** For instance invokes */
  public static ArrayList<SootMethod> resolveAppCall(Type tgtType, SootMethodRef methodRef) {
    final NumberedString mSubsignature = methodRef.getSubSignature();
    if (tgtType instanceof RefType) {
      // find first class upwards in hierarchy, starting from cls, that implements method (i.e.,
      // *concrete* method)
      SootClass cls = ((RefType) tgtType).getSootClass();
      while (!cls.declaresMethod(mSubsignature))
        cls =
            cls
                .getSuperclass(); // if method not in this class, it HAS to be in a superclass, so a
                                  // superclass must exist

      if (!cls.hasTag(ClassTag.TAG_NAME)) return null; // not an app method

      // finally, store resolved app method
      SootMethod m = cls.getMethod(mSubsignature);
      assert m.hasTag(MethodTag.TAG_NAME);

      ArrayList<SootMethod> methods = new ArrayList<SootMethod>();
      methods.add(m); // just one element, directly resolved
      return methods;
    }

    if (tgtType instanceof AnySubType) {
      // return set of all app subtypes that implement referenced method
      SootClass baseCls = ((AnySubType) tgtType).getBase().getSootClass();
      List subClasses =
          baseCls.isInterface()
              ? Scene.v().getActiveHierarchy().getImplementersOf(baseCls)
              : Scene.v().getActiveHierarchy().getSubclassesOf(baseCls);
      ArrayList<SootMethod> methods = new ArrayList<SootMethod>();
      for (Object oSubCls : subClasses) {
        SootClass subCls = (SootClass) oSubCls;
        if (subCls.hasTag(ClassTag.TAG_NAME)) {
          try {
            SootMethod m = subCls.getMethod(mSubsignature);
            assert m.hasTag(MethodTag.TAG_NAME);
            if (!m.isAbstract()) methods.add(m);
          } catch (RuntimeException e) {
          }
        }
      }

      return methods;
    }

    assert tgtType instanceof ArrayType; // only other case observed so far
    return new ArrayList(); // no array class/method is in app
  }
Beispiel #9
0
 public boolean equivTo(Object o) {
   if (o instanceof JDynamicInvokeExpr) {
     JDynamicInvokeExpr ie = (JDynamicInvokeExpr) o;
     if (!(getMethod().equals(ie.getMethod()) && bsmArgBoxes.length == ie.bsmArgBoxes.length))
       return false;
     int i = 0;
     for (ValueBox element : bsmArgBoxes) {
       if (!(element.getValue().equivTo(ie.getBootstrapArg(i)))) return false;
       i++;
     }
     if (!(getMethod().equals(ie.getMethod()) && argBoxes.length == ie.argBoxes.length))
       return false;
     i = 0;
     for (ValueBox element : argBoxes) {
       if (!(element.getValue().equivTo(ie.getArg(i)))) return false;
       i++;
     }
     if (!methodRef.equals(ie.methodRef)) return false;
     if (!bsmRef.equals(ie.bsmRef)) return false;
     return true;
   }
   return false;
 }
 public void methodRef(SootMethodRef m) {
   handleIndent();
   output.append(m.name());
 }
 public BSpecialInvokeInst(SootMethodRef methodRef) {
   if (methodRef.isStatic()) throw new RuntimeException("wrong static-ness");
   this.methodRef = methodRef;
 }
 public Type getType() {
   return methodRef.returnType();
 }
 public SootMethod getMethod() {
   return methodRef.resolve();
 }
 private Value mutate(Value value) {
   if (value instanceof FieldRef) {
     FieldRef ref = (FieldRef) value;
     SootField field = ref.getField();
     Type type = field.getType();
     if (type instanceof RefType) {
       RefType ref_type = (RefType) type;
       SootClass soot_class = ref_type.getSootClass();
       if (shouldMap(soot_class)) {
         addField(field, ref);
       }
     } else if (type instanceof ArrayType) {
       ArrayType array_type = (ArrayType) type;
       Type base_type = array_type.baseType;
       if (base_type instanceof RefType) {
         RefType ref_type = (RefType) base_type;
         SootClass soot_class = ref_type.getSootClass();
         if (shouldMap(soot_class)) {
           addField(field, ref);
         }
       }
     }
     SootClass soot_class = field.getDeclaringClass();
     if (shouldMap(soot_class)) {
       addField(field, ref);
     }
     return value;
   } else if (value instanceof InvokeExpr) {
     InvokeExpr expr = (InvokeExpr) value;
     SootMethodRef ref = expr.getMethodRef();
     SootClass soot_class = ref.declaringClass();
     final NumberedString subSignature = ref.getSubSignature();
     if (shouldMap(soot_class)) {
       SootClass new_class = getMapping(soot_class);
       if (new_class.declaresMethod(subSignature)) {
         SootMethod new_method = RootbeerScene.v().getMethod(new_class, subSignature.getString());
         addAddedMethod(new_method);
         fixArguments(new_method);
         RootbeerScene.v().getDfsInfo().addReachableMethodSig(new_method.getSignature());
         expr.setMethodRef(new_method.makeRef());
       }
     } else {
       if (soot_class.declaresMethod(ref.getSubSignature())) {
         SootMethod method = soot_class.getMethod(ref.getSubSignature());
         fixArguments(method);
       }
     }
     ref = remapRef(ref);
     try {
       if (shouldMap(soot_class)) {
         soot_class = getMapping(soot_class);
       }
       SootMethod method = soot_class.getMethod(ref.getSubSignature());
       RootbeerScene.v().getDfsInfo().addReachableMethodSig(method.getSignature());
       expr.setMethodRef(method.makeRef());
     } catch (Exception ex) {
       // ex.printStackTrace();
     }
     return value;
   } else if (value instanceof NewExpr) {
     NewExpr expr = (NewExpr) value;
     RefType base_type = expr.getBaseType();
     SootClass soot_class = base_type.getSootClass();
     if (shouldMap(soot_class)) {
       SootClass new_class = getMapping(soot_class);
       expr.setBaseType(new_class.getType());
     }
     return value;
   } else if (value instanceof NewArrayExpr) {
     NewArrayExpr expr = (NewArrayExpr) value;
     Type base_type = expr.getBaseType();
     base_type = fixType(base_type);
     expr.setBaseType(base_type);
     return value;
   } else if (value instanceof NewMultiArrayExpr) {
     NewMultiArrayExpr expr = (NewMultiArrayExpr) value;
     ArrayType array_type = expr.getBaseType();
     Type base_type = array_type.baseType;
     if (base_type instanceof RefType) {
       RefType ref_type = (RefType) base_type;
       SootClass soot_class = ref_type.getSootClass();
       if (shouldMap(soot_class)) {
         SootClass new_class = getMapping(soot_class);
         ArrayType new_type = ArrayType.v(new_class.getType(), array_type.numDimensions);
         expr.setBaseType(new_type);
       }
     }
     return value;
   } else if (value instanceof CastExpr) {
     CastExpr expr = (CastExpr) value;
     Type cast_type = expr.getCastType();
     cast_type = fixType(cast_type);
     expr.setCastType(cast_type);
     return value;
   } else if (value instanceof ParameterRef) {
     ParameterRef ref = (ParameterRef) value;
     Type new_type = fixType(ref.getType());
     return new ParameterRef(new_type, ref.getIndex());
   } else if (value instanceof ThisRef) {
     ThisRef ref = (ThisRef) value;
     Type new_type = fixType(ref.getType());
     return new ThisRef((RefType) new_type);
   } else if (value instanceof Local) {
     Local local = (Local) value;
     Type type = local.getType();
     local.setType(fixType(type));
     return value;
   } else {
     return value;
   }
 }
Beispiel #15
0
 public SootMethod getBootstrapMethod() {
   return bsmRef.resolve();
 }
Beispiel #16
0
 @SuppressWarnings("unchecked")
 public static String getDescriptor(SootMethodRef methodRef) {
   return getDescriptor(methodRef.parameterTypes(), methodRef.returnType());
 }