示例#1
0
  public static HashSet<SootMethod> getAllImplementations(SootMethod method) {
    Chain appClasses = Scene.v().getApplicationClasses();
    HashSet<SootClass> implementingClasses = new HashSet<SootClass>(1);
    HashSet<SootMethod> overridingMethods = new HashSet<SootMethod>(1);

    SootClass t = method.getDeclaringClass();
    if (
    /*t.isAbstract() || */ t.isPhantom() || t.isPhantomClass()) {
      boolean b1 = t.isAbstract();
      boolean be = t.isPhantom();
      boolean b3 = t.isPhantomClass();

      try {
        throw new Exception("Need to implement for Plantom Classes");
      } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    if (t.isAbstract()) {
      for (Object object : appClasses) {
        SootClass clazz = (SootClass) object;
        SootClass superClass = clazz.getSuperclass();
        {
          if (superClass.getName().equals(t.toString())) {
            implementingClasses.add(clazz);
            SootMethod m2 =
                clazz.getMethod(
                    method.getName(), method.getParameterTypes(), method.getReturnType());
            overridingMethods.add(m2);
          }
        }
      }
    }
    if (t.isInterface()) {
      for (Object object : appClasses) {
        SootClass clazz = (SootClass) object;
        Chain<SootClass> interfaces = clazz.getInterfaces();
        for (SootClass sootClass : interfaces) {
          if (sootClass.getName().equals(t.toString())) {
            implementingClasses.add(clazz);
            SootMethod m2 =
                clazz.getMethod(
                    method.getName(), method.getParameterTypes(), method.getReturnType());
            overridingMethods.add(m2);
          }
        }
      }
    }
    return overridingMethods;
  }
示例#2
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
  }
  public void staticBlockInlining(SootClass sootClass) {
    this.sootClass = sootClass;
    // retrieve the clinit method if any for sootClass
    if (!sootClass.declaresMethod("void <clinit>()")) {
      System.out.println("no clinit");
      return;
    }

    SootMethod clinit = sootClass.getMethod("void <clinit>()");
    // System.out.println(clinit);

    // retireve the active body
    if (!clinit.hasActiveBody())
      throw new RuntimeException("method " + clinit.getName() + " has no active body!");

    Body clinitBody = clinit.getActiveBody();

    Chain units = ((DavaBody) clinitBody).getUnits();

    if (units.size() != 1) {
      throw new RuntimeException("DavaBody AST doesn't have single root.");
    }

    ASTNode AST = (ASTNode) units.getFirst();
    if (!(AST instanceof ASTMethodNode))
      throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode");

    AST.apply(new MethodCallFinder(this));
  }
  /**
   * Resolve the concrete target of a special invoke using our modified semantics for special invoke
   * expression.
   */
  private SootMethod resolveSpecialInvokeTarget(SpecialInvokeExpr si) {
    SootMethod target = null;

    try {
      target = SootUtils.resolve(si.getMethodRef());
    } catch (CannotFindMethodException e) {
      logger.error("Cannot find concrete method target for special invoke: {}", si);
      return null;
    }

    String targetSubSig = target.getSubSignature();

    SootClass current = target.getDeclaringClass();

    while (true) {
      if (current.declaresMethod(targetSubSig)) {
        return current.getMethod(targetSubSig);
      }

      // not a match in current, try superclass on next loop
      if (current.hasSuperclass()) current = current.getSuperclass();
      else {
        logger.error("Cannot find concrete method target for special invoke: {}", si);
        droidsafe.main.Main.exit(1);
        return null;
      }
    }
  }
示例#5
0
  public static SootMethod mockSootMethod(
      String clsName, String methodSubSignature, boolean isStatic) {
    SootClass sc = mockSootClass(clsName);

    SootMethod sm = null;

    try {
      sm = sc.getMethod(methodSubSignature);
    } catch (Exception ex) {
      sm = null;
    }

    if (null == sm) {
      int m = Modifier.PUBLIC;
      if (isStatic) {
        m = m | Modifier.STATIC;
      }

      List<Type> paramTypes = new ArrayList<Type>();
      paramTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));

      String[] strs = methodSubSignature.split(" ");
      String methodName = strs[1].trim().substring(0, strs[1].trim().indexOf("("));

      if (null == methodName || methodName.isEmpty()) {
        return null;
      }

      sm = new SootMethod(methodName, paramTypes, RefType.v("java.lang.Object"), m);
      sc.addMethod(sm);

      // Add body of sm
      JimpleBody b = Jimple.v().newBody(sm);
      sm.setActiveBody(b);
      // LocalGenerator lg = new LocalGenerator(b);
      {
        b.insertIdentityStmts();

        // Local rtLoc = lg.generateLocal(RefType.v("java.lang.Object"));

        // Local param0 = lg.generateLocal(ArrayType.v(RefType.v("java.lang.Object"), 1));
        // Unit param0U = Jimple.v().newIdentityStmt(rtLoc,
        // Jimple.v().newParameterRef(ArrayType.v(RefType.v("java.lang.Object"), 1), 0));

        // Unit rtLocAssignU = Jimple.v().newAssignStmt(rtLoc, param0);

        Unit returnU = Jimple.v().newReturnStmt(b.getParameterLocal(0));

        // b.getUnits().add(param0U);
        b.getUnits().add(returnU);
      }

      System.out.println("validation:" + b);
      b.validate();
    }

    return sm;
  }
示例#6
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();
  }
  public static void main(String[] args) {
    List<String> argsList = new ArrayList<String>(Arrays.asList(args));
    argsList.addAll(
        Arrays.asList(
            new String[] {
              "-w", // "-p", "cg.spark", "on-fly-cg:true",
              // "-main-class", "testers.CallGraphs",// main-class
              "testers.CallGraphs", // argument classes
              // "testers.A" //
            }));
    argsList.add("-soot-class-path");
    argsList.add(
        "/home/nnguyen/workspaceluna/CoGConstructor/bin:/usr/java/jdk1.7.0_79/jre/lib/rt.jar:/usr/java/jdk1.7.0_79/jre/lib/jce.jar");
    argsList.add("-p");
    argsList.add("cg");
    argsList.add("all-reachable:true");

    argsList.add("-p");
    argsList.add("cg.spark");
    argsList.add("on-fly-cg:true");
    argsList.add("-f");
    argsList.add("J");
    // argsList.add("-no-bodies-for-excluded");
    // argsList.add("pre-jimplify:true");

    System.out.println("JB " + PackManager.v().getPack("jb").getDefaultOptions());
    System.out.println("JBLS " + PackManager.v().getPhase("jb.ls").getDefaultOptions());
    System.out.println("JBDAE " + PackManager.v().getPhase("jb.dae").getDefaultOptions());
    System.out.println("CHCHA " + PackManager.v().getPhase("cg.cha").getDeclaredOptions());
    System.out.println("CG" + PackManager.v().getPack("cg").getDeclaredOptions());

    // PackManager.v().getPack("wjtp").add(new Transform("wjtp.myTrans", new SceneTransformer() {
    // // System.out.println(PackManager.v().getPhase("cg.spark").getDeclaredOptions());
    //
    // // PackManager.v().getPack("cg").add(new Transform("cg.myTrans", new SceneTransformer() {
    //
    // @Override
    // protected void internalTransform(String phaseName, Map options) {
    // CHATransformer.v().transform();
    // SootClass a = Scene.v().getSootClass("testers.A");
    //
    // SootMethod src = Scene.v().getMainClass().getMethodByName("doStuff");
    // CallGraph cg = Scene.v().getCallGraph();
    //
    // Iterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));
    //
    // while (targets.hasNext()) {
    // SootMethod tgt = (SootMethod) targets.next();
    // System.out.println(src + " may call " + tgt);
    // }
    //
    // Iterator<MethodOrMethodContext> sources = new Sources(cg.edgesInto(src));
    //
    // while (sources.hasNext()) {
    // SootMethod tgt = (SootMethod) sources.next();
    //
    // System.out.println(src + " may be called by " + tgt + " " + tgt.getName());
    // }
    //
    // }
    //
    // }));

    args = argsList.toArray(new String[0]);
    Options.v().parse(args); // disable if want to use soot.Main.main
    Options.v().set_keep_line_number(true);
    Options.v().set_whole_program(true);
    Options.v().set_allow_phantom_refs(true);
    Options.v().setPhaseOption("jb", "use-original-names:true");

    // soot.Main.main(args);

    List addedEntryPoints = new ArrayList();
    // for (String ePoint : customEntryPoints) {
    SootClass c = Scene.v().forceResolve("testers.CallGraphs", SootClass.BODIES);
    c.setApplicationClass();
    Scene.v().loadNecessaryClasses();
    SootMethod method;
    String methodName = "main";
    if (!methodName.contains("(")) {
      method = c.getMethodByName(methodName);
      System.out.println("FOUND IT");
    } else {
      // List<Type> types = new ArrayList<Type>();

      method = c.getMethod(methodName);
      System.out.println("FOUND IT");
    }
    addedEntryPoints.add(method);
    // }
    Scene.v().setEntryPoints(addedEntryPoints);
    PackManager.v().runPacks();

    JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG();
    IFDSTabulationProblem<
            Unit,
            Pair<Value, Set<DefinitionStmt>>,
            SootMethod,
            InterproceduralCFG<Unit, SootMethod>>
        problem = (IFDSTabulationProblem) new IFDSReachingDefinitions(icfg);
    System.out.println("Number of threads :" + problem.numThreads());

    JimpleIFDSSolver<Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>>
        solver =
            new JimpleIFDSSolver<
                Pair<Value, Set<DefinitionStmt>>, InterproceduralCFG<Unit, SootMethod>>(
                problem, true);

    System.out.println("Started Solving....");
    System.out.println(Scene.v().getMainMethod().getName());
    SootMethod mMethod = Scene.v().getSootClass("testers.CallGraphs").getMethodByName("main");
    // SootMethod mMethod = Scene.v().getMainClass().getMethodByName("doStuff2");
    BiDirICFGFactory icfgFactory = new DefaultBiDiICFGFactory();
    IInfoflowCFG iCfg = icfgFactory.buildBiDirICFG(CallgraphAlgorithm.AutomaticSelection, true);

    CallGraph cg = Scene.v().getCallGraph();
    // SootClass cl = Scene.v().getMainClass();
    for (SootClass cl : Scene.v().getClasses()) {
      for (SootMethod sm : cl.getMethods()) {
        if (sm.getSignature().contains("testers")
            || sm.getSignature().contains("java.lang.Object next()")) {
          // if
          // (sm.getSignature().equals("<testers.CallGraphs$CellIterator: java.lang.Object
          // next()>"))
          // {
          // if (sm.getSignature().equals("<testers.CallGraphs: void p4(int)>")) {
          System.out.println(
              "WE FOUND " + sm.getSignature() + " AT " + sm.getJavaSourceStartLineNumber());
          Iterator sources = new Sources(cg.edgesInto(sm));
          while (sources.hasNext()) {
            SootMethod sm2 = (SootMethod) sources.next();
            System.out.println("CALLED BY " + sm2.getSignature());
          }

          // sources = new Sources(cg.edgesOutOf(sm));
          // while (sources.hasNext()) {
          // SootMethod sm2 = (SootMethod) sources.next();
          // System.out.println("CALLS " + sm2.getSignature());
          // }
          // }
        }
      }
    }

    if (mMethod.hasActiveBody()) {
      System.out.println("YESSSSSSSSSSSSSSSSS");
      Body b = mMethod.getActiveBody();
      for (Unit u : b.getUnits()) {
        System.out.println(u + " AT " + u.getJavaSourceStartLineNumber());
      }
      System.out.println("===================");
      for (Unit u : b.getUnits()) {

        if (u instanceof IfStmt) {
          System.out.println("IF STMT AT " + u.getJavaSourceStartLineNumber());
          IfStmt stmt = (IfStmt) u;
          System.out.println(u);
          Value condition = stmt.getCondition();
          ValueBox conditionBox = stmt.getConditionBox();
          System.out.println(
              "Condition " + condition + " AT " + conditionBox.getJavaSourceStartLineNumber());
          System.out.println(
              "Target "
                  + stmt.getTarget()
                  + " AT "
                  + stmt.getTarget().getJavaSourceStartLineNumber());
          System.out.println(
              iCfg.getPostdominatorOf(u) + " AT " + u.getJavaSourceStartLineNumber());

          System.out.println(iCfg.getSuccsOf(u));

          System.out.println("=====");
        }

        if (u instanceof GotoStmt) {
          System.out.println("GOTO STMT AT " + u.getJavaSourceStartLineNumber());
          GotoStmt stmt = (GotoStmt) u;
          System.out.println(u);
          System.out.println(stmt.getTarget());
          System.out.println("=====");
        }
      }
    }

    // commented to test the IfStmt
    // if (!Scene.v().getMainMethod().hasActiveBody()) {
    // System.out.println("NONOOOOOOOOOOOOOOOOOOOOOOOOOOO");
    // }
    // // Scene.v().getMainMethod().getActiveBody()
    // solver.solve();
    // System.out.println("Completed Solving....");
    // solver.dumpResults();

  }
示例#8
0
  private StructureConstant createClassInfoStruct() {
    int flags = 0;

    if (Modifier.isPublic(sootClass.getModifiers())) {
      flags |= CI_PUBLIC;
    }
    if (Modifier.isFinal(sootClass.getModifiers())) {
      flags |= CI_FINAL;
    }
    if (Modifier.isInterface(sootClass.getModifiers())) {
      flags |= CI_INTERFACE;
    }
    if (Modifier.isAbstract(sootClass.getModifiers())) {
      flags |= CI_ABSTRACT;
    }
    if ((sootClass.getModifiers() & 0x1000) > 0) {
      flags |= CI_SYNTHETIC;
    }
    if (Modifier.isAnnotation(sootClass.getModifiers())) {
      flags |= CI_ANNOTATION;
    }
    if (Modifier.isEnum(sootClass.getModifiers())) {
      flags |= CI_ENUM;
    }
    if (attributesEncoder.classHasAttributes()) {
      flags |= CI_ATTRIBUTES;
    }
    if (hasFinalizer(sootClass)) {
      flags |= CI_FINALIZABLE;
    }

    // Create the ClassInfoHeader structure.
    StructureConstantBuilder header = new StructureConstantBuilder();
    header.add(new NullConstant(I8_PTR)); // Points to the runtime Class struct
    header.add(new IntegerConstant(flags));
    header.add(getString(getInternalName(sootClass)));
    if (sootClass.declaresMethod("<clinit>", Collections.emptyList(), VoidType.v())) {
      SootMethod method = sootClass.getMethod("<clinit>", Collections.emptyList(), VoidType.v());
      header.add(new FunctionRef(mangleMethod(method), getFunctionType(method)));
    } else {
      header.add(new NullConstant(I8_PTR));
    }
    header.add(sizeof(classType));
    header.add(sizeof(instanceType));
    if (!instanceFields.isEmpty()) {
      header.add(offsetof(instanceType, 1, 1));
    } else {
      header.add(sizeof(instanceType));
    }
    header.add(new IntegerConstant((short) countReferences(classFields)));
    header.add(new IntegerConstant((short) countReferences(instanceFields)));

    PackedStructureConstantBuilder body = new PackedStructureConstantBuilder();
    body.add(new IntegerConstant((short) sootClass.getInterfaceCount()));
    body.add(new IntegerConstant((short) sootClass.getFieldCount()));
    body.add(new IntegerConstant((short) sootClass.getMethodCount()));

    if (!sootClass.isInterface()) {
      body.add(
          getStringOrNull(
              sootClass.hasSuperclass() ? getInternalName(sootClass.getSuperclass()) : null));
    }

    if (attributesEncoder.classHasAttributes()) {
      body.add(new ConstantBitcast(attributesEncoder.getClassAttributes().ref(), I8_PTR));
    }

    for (SootClass s : sootClass.getInterfaces()) {
      body.add(getString(getInternalName(s)));
    }

    for (SootField f : sootClass.getFields()) {
      flags = 0;
      soot.Type t = f.getType();
      if (t instanceof PrimType) {
        if (t.equals(BooleanType.v())) {
          flags |= DESC_Z;
        } else if (t.equals(ByteType.v())) {
          flags |= DESC_B;
        } else if (t.equals(ShortType.v())) {
          flags |= DESC_S;
        } else if (t.equals(CharType.v())) {
          flags |= DESC_C;
        } else if (t.equals(IntType.v())) {
          flags |= DESC_I;
        } else if (t.equals(LongType.v())) {
          flags |= DESC_J;
        } else if (t.equals(FloatType.v())) {
          flags |= DESC_F;
        } else if (t.equals(DoubleType.v())) {
          flags |= DESC_D;
        }
        flags <<= 12;
      }
      if (Modifier.isPublic(f.getModifiers())) {
        flags |= FI_PUBLIC;
      } else if (Modifier.isPrivate(f.getModifiers())) {
        flags |= FI_PRIVATE;
      } else if (Modifier.isProtected(f.getModifiers())) {
        flags |= FI_PROTECTED;
      }
      if (Modifier.isStatic(f.getModifiers())) {
        flags |= FI_STATIC;
      }
      if (Modifier.isFinal(f.getModifiers())) {
        flags |= FI_FINAL;
      }
      if (Modifier.isVolatile(f.getModifiers())) {
        flags |= FI_VOLATILE;
      }
      if (Modifier.isTransient(f.getModifiers())) {
        flags |= FI_TRANSIENT;
      }
      if ((f.getModifiers() & 0x1000) > 0) {
        flags |= FI_SYNTHETIC;
      }
      if (Modifier.isEnum(f.getModifiers())) {
        flags |= FI_ENUM;
      }
      if (attributesEncoder.fieldHasAttributes(f)) {
        flags |= FI_ATTRIBUTES;
      }
      body.add(new IntegerConstant((short) flags));
      body.add(getString(f.getName()));
      if (!(t instanceof PrimType)) {
        body.add(getString(getDescriptor(f)));
      }
      if (f.isStatic()) {
        int index = classFields.indexOf(f);
        body.add(offsetof(classType, 1, index, 1));
      } else {
        int index = instanceFields.indexOf(f);
        body.add(offsetof(instanceType, 1, 1 + index, 1));
      }
      if (attributesEncoder.fieldHasAttributes(f)) {
        body.add(new ConstantBitcast(attributesEncoder.getFieldAttributes(f).ref(), I8_PTR));
      }
    }

    for (SootMethod m : sootClass.getMethods()) {
      soot.Type t = m.getReturnType();
      flags = 0;
      if (Modifier.isPublic(m.getModifiers())) {
        flags |= MI_PUBLIC;
      } else if (Modifier.isPrivate(m.getModifiers())) {
        flags |= MI_PRIVATE;
      } else if (Modifier.isProtected(m.getModifiers())) {
        flags |= MI_PROTECTED;
      }
      if (Modifier.isStatic(m.getModifiers())) {
        flags |= MI_STATIC;
      }
      if (Modifier.isFinal(m.getModifiers())) {
        flags |= MI_FINAL;
      }
      if (Modifier.isSynchronized(m.getModifiers())) {
        flags |= MI_SYNCHRONIZED;
      }
      if ((m.getModifiers() & 0x0040) > 0) {
        flags |= MI_BRIDGE;
      }
      if ((m.getModifiers() & 0x0080) > 0) {
        flags |= MI_VARARGS;
      }
      if (Modifier.isNative(m.getModifiers())) {
        if (!isStruct(sootClass) && !isStructMember(m)) {
          flags |= MI_NATIVE;
        }
      }
      if (Modifier.isAbstract(m.getModifiers())) {
        flags |= MI_ABSTRACT;
      }
      if (Modifier.isStrictFP(m.getModifiers())) {
        flags |= MI_STRICT;
      }
      if ((m.getModifiers() & 0x1000) > 0) {
        flags |= MI_SYNTHETIC;
      }
      if (attributesEncoder.methodHasAttributes(m)) {
        flags |= MI_ATTRIBUTES;
      }
      if (isBridge(m)) {
        flags |= MI_BRO_BRIDGE;
      }
      if (isCallback(m)) {
        flags |= MI_BRO_CALLBACK;
      }
      if ((t instanceof PrimType || t == VoidType.v()) && m.getParameterCount() == 0) {
        flags |= MI_COMPACT_DESC;
      }
      body.add(new IntegerConstant((short) flags));

      body.add(getString(m.getName()));

      if ((flags & MI_COMPACT_DESC) > 0) {
        int desc = 0;
        if (t.equals(BooleanType.v())) {
          desc = DESC_Z;
        } else if (t.equals(ByteType.v())) {
          desc = DESC_B;
        } else if (t.equals(ShortType.v())) {
          desc = DESC_S;
        } else if (t.equals(CharType.v())) {
          desc = DESC_C;
        } else if (t.equals(IntType.v())) {
          desc = DESC_I;
        } else if (t.equals(LongType.v())) {
          desc = DESC_J;
        } else if (t.equals(FloatType.v())) {
          desc = DESC_F;
        } else if (t.equals(DoubleType.v())) {
          desc = DESC_D;
        } else if (t.equals(VoidType.v())) {
          desc = DESC_V;
        }
        body.add(new IntegerConstant((byte) desc));
      } else {
        body.add(getString(getDescriptor(m)));
      }
      if (attributesEncoder.methodHasAttributes(m)) {
        body.add(new ConstantBitcast(attributesEncoder.getMethodAttributes(m).ref(), I8_PTR));
      }
      if (!m.isAbstract()) {
        body.add(new ConstantBitcast(new FunctionRef(mangleMethod(m), getFunctionType(m)), I8_PTR));
        body.add(
            new IntegerConstant(
                DUMMY_METHOD_SIZE)); // Size of function. This value will be modified later by
                                     // patching the .s file.
        if (m.isSynchronized()) {
          body.add(
              new ConstantBitcast(
                  new FunctionRef(mangleMethod(m) + "_synchronized", getFunctionType(m)), I8_PTR));
        }
      }
      if (isBridge(m)) {
        body.add(new GlobalRef(BridgeMethodCompiler.getTargetFnPtrName(m), I8_PTR));
      }
      if (isCallback(m)) {
        body.add(
            new ConstantBitcast(
                new FunctionRef(mangleMethod(m) + "_callback", getCallbackFunctionType(m)),
                I8_PTR));
      }
    }

    // Return the struct {header, body}. To be compatible with the C code in classinfo.c
    // it is important that the header is padded the same as in C so that the body starts
    // after sizeof(ClassInfoHeader) bytes.
    return new StructureConstantBuilder().add(header.build()).add(body.build()).build();
  }
示例#9
0
  public static void mockConstructor(SootClass sc) {
    SootMethod sm = null;

    // Without parameters
    String methodSubSignature = "void <init>()";

    try {
      sm = sc.getMethod(methodSubSignature);
    } catch (Exception ex) {
      sm = null;
    }

    int m = Modifier.PUBLIC;

    if (null == sm) {
      sm = new SootMethod("<init>", new ArrayList<Type>(), VoidType.v(), m);
      sc.addMethod(sm);

      // Add body
      JimpleBody b = Jimple.v().newBody(sm);
      sm.setActiveBody(b);
      {
        b.insertIdentityStmts();
        b.getUnits().add(Jimple.v().newReturnVoidStmt());
      }

      System.out.println("validation:" + b);
      b.validate();
    }

    // Static init
    /*
    methodSubSignature = "void <clinit>()";

    try
    {
    	sm = sc.getMethod(methodSubSignature);
    }
    catch (Exception ex)
    {
    	sm = null;
    }

    if (null == sm)
    {
    	sm = new SootMethod("<clinit>", new ArrayList<Type>(), VoidType.v(), m | Modifier.STATIC);
    	sc.addMethod(sm);

    	//Add body
    	JimpleBody b = Jimple.v().newBody(sm);
           sm.setActiveBody(b);
    	{
    		b.getUnits().add(Jimple.v().newReturnVoidStmt());
    	}

    	b.validate();
    	System.out.println("validation:" + b);
    }
    */

    // With parameter
    methodSubSignature = "void <init>(java.lang.Object[])";

    try {
      sm = sc.getMethod(methodSubSignature);
    } catch (Exception ex) {
      sm = null;
    }

    if (null == sm) {
      List<Type> paramTypes = new ArrayList<Type>();
      paramTypes.add(ArrayType.v(RefType.v("java.lang.Object"), 1));

      sm = new SootMethod("<init>", paramTypes, VoidType.v(), m);
      sc.addMethod(sm);

      // Add body
      JimpleBody b = Jimple.v().newBody(sm);
      sm.setActiveBody(b);
      // LocalGenerator lg = new LocalGenerator(b);
      {
        b.insertIdentityStmts();

        // Local rtLoc = lg.generateLocal(RefType.v("java.lang.Object"));
        // Local param0Loc = lg.generateLocal(ArrayType.v(RefType.v("java.lang.Object"), 1));
        // Unit param0U = Jimple.v().newIdentityStmt(rtLoc,
        // Jimple.v().newParameterRef(ArrayType.v(RefType.v("java.lang.Object"), 1), 0));
        // Unit assignU = Jimple.v().newAssignStmt(rtLoc, Jimple.v().newCastExpr(param0Loc,
        // RefType.v("java.lang.Object")));
        // b.getUnits().add(param0U);
        // b.getUnits().add(assignU);
        b.getUnits().add(Jimple.v().newReturnVoidStmt());
      }

      System.out.println("validation:" + b);
      b.validate();
    }
  }
示例#10
0
 /**
  * Returns method in given class or first upwards superclass, or null if not found in any class
  * (no interface checked)
  */
 private static SootMethod getMethodInClassOrSuperclass(
     SootClass cls, NumberedString subsignature) {
   if (cls.declaresMethod(subsignature)) return cls.getMethod(subsignature);
   if (cls.hasSuperclass()) return getMethodInClassOrSuperclass(cls.getSuperclass(), subsignature);
   return null;
 }
  @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++;
      }
    }
  }
  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;
  }
 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;
   }
 }
示例#14
0
  static {
    innerClass = Scene.v().getSootClass(innerClassStr);

    testMethodRef = innerClass.getMethod("void test()").makeRef();
  }