Beispiel #1
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;
 }
  @Override
  public Type appliesInternal(AndroidMethod method) {
    SootMethod sm = getSootMethod(method);

    if (sm == null) {
      System.err.println("Method not declared: " + method);
      return Type.NOT_SUPPORTED;
    }

    // We are only interested in setters
    if (!sm.isConcrete()) return Type.NOT_SUPPORTED;

    try {
      Set<Value> paramVals = new HashSet<Value>();
      for (Unit u : sm.retrieveActiveBody().getUnits()) {
        // Collect the parameters
        if (u instanceof IdentityStmt) {
          IdentityStmt id = (IdentityStmt) u;
          if (id.getRightOp() instanceof ParameterRef) paramVals.add(id.getLeftOp());
        }

        // Check for invocations
        if (u instanceof Stmt) {
          Stmt stmt = (Stmt) u;
          if (stmt.containsInvokeExpr())
            if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) {
              InstanceInvokeExpr iinv = (InstanceInvokeExpr) stmt.getInvokeExpr();
              if (paramVals.contains(iinv.getBase()))
                if (iinv.getMethod().getName().startsWith(methodName)) return Type.TRUE;
            }
        }
      }
      return Type.FALSE;
    } catch (Exception ex) {
      System.err.println("Something went wrong:");
      ex.printStackTrace();
      return Type.NOT_SUPPORTED;
    }
  }
  public void assureAllSyncInCallGraph(Collection<JavaCriticalSection> criticalSections) {
    System.out.println("[assureAllSyncInCallgraph] starting");
    Date start = new Date();
    ReachableMethods oldReach = Scene.v().getReachableMethods();
    // Collection et = EntryPoints.v().all();
    // ReachableMethods reachableFromMain = new ReachableMethods(cg, et);
    // reachableFromMain.update();

    Set<SootMethod> notInCG = new HashSet<SootMethod>();
    for (JavaCriticalSection cs : criticalSections) {
      SootMethod m = cs.getSootMethod();
      if (!oldReach.contains(m)) notInCG.add(m);
    }
    Set<SootMethod> alreadyInCG = new HashSet<SootMethod>();
    for (Iterator<MethodOrMethodContext> it = oldReach.listener(); it.hasNext(); ) {
      alreadyInCG.add(it.next().method());
    }
    /*
     * for(Iterator<?> it=cg.sourceMethods();it.hasNext();){ SootMethod m =
     * (SootMethod)it.next(); alreadyInCG.add(m); if(notInCG.contains(m)){
     * notInCG.remove(m); } }
     */

    // add new methods to the call graph
    Stack<SootMethod> worklist = new Stack<SootMethod>();
    for (SootMethod m : notInCG) {
      worklist.push(m);
    }

    while (!worklist.isEmpty()) {
      SootMethod m = worklist.pop();
      if (alreadyInCG.contains(m) || m == null) {
        continue;
      }
      alreadyInCG.add(m);

      Body body = m.retrieveActiveBody();
      for (Unit u : body.getUnits()) {
        if (!(u instanceof Stmt)) {
          continue;
        }

        Stmt s = (Stmt) u;
        if (!s.containsInvokeExpr()) {
          continue;
        }

        InvokeExpr invoke = s.getInvokeExpr();
        SootMethod declCallee = invoke.getMethod();
        Collection<SootMethod> targets = new ArrayList<SootMethod>();
        if (declCallee.isStatic()) {
          targets.add(declCallee);
        } else {
          // XXX: pay attention to reflexive call, thread call, and
          // etc.
          // Here we do not add edges for implicit targets, as these
          // parts of methods is not reachable
          // from the entry, and they will most likely to be analyzed
          // in a very conservative ways.
          InstanceInvokeExpr iie = (InstanceInvokeExpr) invoke;
          Local receiver = (Local) iie.getBase();
          NumberedString subSig = iie.getMethodRef().getSubSignature();

          if (invoke instanceof SpecialInvokeExpr) {
            SootMethod tgt = VirtualCalls.v().resolveSpecial((SpecialInvokeExpr) invoke, subSig, m);
            targets.add(tgt);
          } else {
            Type t = receiver.getType();
            if (t instanceof ArrayType) {
              // t = RefType.v("java.lang.Object");
              targets.add(declCallee);
            }
            // BottomType bug
            else if (t instanceof soot.jimple.toolkits.typing.fast.BottomType) {
              System.out.println("BottomType:" + s);
            } else if (t instanceof soot.NullType) {
              System.out.println("NullType:" + s);
            } else {
              SootClass c = ((RefType) t).getSootClass();
              // Soot has a type resolving bug, and here may be
              // exceptions
              try {
                Set<SootMethod> callees =
                    Scene.v().getOrMakeFastHierarchy().resolveAbstractDispatch(c, declCallee);
                targets.addAll(callees);
              } catch (Exception e) {
                System.out.println(e.getMessage());
              }
            }
          }
        }

        for (SootMethod t : targets) {
          // add call edge
          Edge e = new Edge(m, s, t);
          Scene.v().getCallGraph().addEdge(e);

          // add to worklist
          if (t.isConcrete() && !alreadyInCG.contains(t)) {
            worklist.push(t);
          }
        }
      }
    }

    // infer entries for the methods not reachable from main entry
    List<SootMethod> entries = Scene.v().getEntryPoints();
    _patchedEntries = new ArrayList<SootMethod>(notInCG);
    for (SootMethod m : notInCG) {
      // XXX there can be recursive calls, so for simple processing, all
      // methods not in old
      // call graph should be added to the entry. Checking the
      // non-existence of incoming edges
      // may miss some recursively called methods
      // if(!cg.edgesInto(m).hasNext()){
      entries.add(m);
      // }
    }

    // update reachable methods
    Scene.v().setReachableMethods(null);
  }