コード例 #1
0
ファイル: ThrowableSet.java プロジェクト: safdariqbal/soot
    /**
     * Returns a <code>ThrowableSet</code> representing the set of exceptions included in <code>
     * include</code> minus the set of exceptions included in <code>exclude</code>. Creates a new
     * <code>ThrowableSet</code> only if there was not already one whose contents correspond to
     * <code>include</code> - <code>exclude</code>.
     *
     * @param include A set of {@link RefLikeType} objects representing exception types included in
     *     the result; may be <code>null</code> if there are no included types.
     * @param exclude A set of {@link AnySubType} objects representing exception types excluded from
     *     the result; may be <code>null</code> if there are no excluded types.
     * @return a <code>ThrowableSet</code> representing the set of exceptions corresponding to
     *     <code>include</code> - <code>exclude</code>.
     */
    private ThrowableSet registerSetIfNew(Set include, Set exclude) {
      if (INSTRUMENTING) {
        registrationCalls++;
      }
      if (include == null) {
        include = Collections.EMPTY_SET;
      }
      if (exclude == null) {
        exclude = Collections.EMPTY_SET;
      }
      int size = include.size() + exclude.size();
      Integer sizeKey = new Integer(size);

      List sizeList = (List) sizeToSets.get(sizeKey);
      if (sizeList == null) {
        sizeList = new LinkedList();
        sizeToSets.put(sizeKey, sizeList);
      }
      for (Iterator i = sizeList.iterator(); i.hasNext(); ) {
        ThrowableSet set = (ThrowableSet) i.next();
        if (set.exceptionsIncluded.equals(include) && set.exceptionsExcluded.equals(exclude)) {
          return set;
        }
      }
      if (INSTRUMENTING) {
        registeredSets++;
      }
      ThrowableSet result = new ThrowableSet(include, exclude);
      sizeList.add(result);
      return result;
    }
コード例 #2
0
ファイル: IfElseBreaker.java プロジェクト: GeneBlue/JAADAS
  /*
    The purpose of this method is to replace the ASTIfElseNode
    given by the var nodeNumber with the new ASTIfNode
    and to add the remianing list of bodies after this ASTIfNode

    The new body is then returned;

  */
  public List<Object> createNewBody(List<Object> oldSubBody, int nodeNumber) {
    if (newIfNode == null) return null;

    List<Object> newSubBody = new ArrayList<Object>();

    if (oldSubBody.size() <= nodeNumber) {
      // something is wrong since the oldSubBody has lesser nodes than nodeNumber
      return null;
    }

    Iterator<Object> oldIt = oldSubBody.iterator();
    int index = 0;
    while (index != nodeNumber) {
      newSubBody.add(oldIt.next());
      index++;
    }

    // check to see that the next is an ASTIfElseNode
    ASTNode temp = (ASTNode) oldIt.next();
    if (!(temp instanceof ASTIfElseNode)) return null;

    newSubBody.add(newIfNode);

    newSubBody.addAll(remainingBody);

    // copy any remaining nodes
    while (oldIt.hasNext()) {
      newSubBody.add(oldIt.next());
    }

    return newSubBody;
  }
コード例 #3
0
ファイル: Walker.java プロジェクト: safdariqbal/soot
  protected int processModifiers(List l) {
    int modifier = 0;
    Iterator it = l.iterator();

    while (it.hasNext()) {
      Object t = it.next();
      if (t instanceof AAbstractModifier) modifier |= Modifier.ABSTRACT;
      else if (t instanceof AFinalModifier) modifier |= Modifier.FINAL;
      else if (t instanceof ANativeModifier) modifier |= Modifier.NATIVE;
      else if (t instanceof APublicModifier) modifier |= Modifier.PUBLIC;
      else if (t instanceof AProtectedModifier) modifier |= Modifier.PROTECTED;
      else if (t instanceof APrivateModifier) modifier |= Modifier.PRIVATE;
      else if (t instanceof AStaticModifier) modifier |= Modifier.STATIC;
      else if (t instanceof ASynchronizedModifier) modifier |= Modifier.SYNCHRONIZED;
      else if (t instanceof ATransientModifier) modifier |= Modifier.TRANSIENT;
      else if (t instanceof AVolatileModifier) modifier |= Modifier.VOLATILE;
      else if (t instanceof AEnumModifier) modifier |= Modifier.ENUM;
      else if (t instanceof AAnnotationModifier) modifier |= Modifier.ANNOTATION;
      else
        throw new RuntimeException(
            "Impossible: modifier unknown - Have you added a new modifier and not updated this file?");
    }

    return modifier;
  }
コード例 #4
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
 protected void testList(List list) {
   //		System.out.println("test list");
   Iterator listIt = list.iterator();
   while (listIt.hasNext()) {
     System.out.println(listIt.next());
   }
 }
コード例 #5
0
ファイル: Hierarchy.java プロジェクト: Hounge/apkinspector
  /** Returns a list of possible targets for the given method and set of receiver types. */
  public List resolveAbstractDispatch(List classes, SootMethod m) {
    m.getDeclaringClass().checkLevel(SootClass.HIERARCHY);
    ArraySet s = new ArraySet();
    Iterator classesIt = classes.iterator();

    while (classesIt.hasNext()) s.addAll(resolveAbstractDispatch((SootClass) classesIt.next(), m));

    List l = new ArrayList();
    l.addAll(s);
    return Collections.unmodifiableList(l);
  }
コード例 #6
0
ファイル: ASTSwitchNode.java プロジェクト: GeneBlue/JAADAS
  public void replaceIndex2BodyList(Map<Object, List<Object>> index2BodyList) {
    this.index2BodyList = index2BodyList;

    subBodies = new ArrayList<Object>();
    Iterator<Object> it = indexList.iterator();
    while (it.hasNext()) {
      List body = index2BodyList.get(it.next());

      if (body != null) subBodies.add(body);
    }
  }
コード例 #7
0
ファイル: Walker.java プロジェクト: safdariqbal/soot
  public void outADeclaration(ADeclaration node) {
    List localNameList = (List) mProductions.removeLast();
    Type type = (Type) mProductions.removeLast();
    Iterator it = localNameList.iterator();
    List localList = new ArrayList();

    while (it.hasNext()) {
      Local l = Jimple.v().newLocal((String) it.next(), type);
      mLocals.put(l.getName(), l);
      localList.add(l);
    }
    mProductions.addLast(localList);
  }
コード例 #8
0
ファイル: Walker.java プロジェクト: safdariqbal/soot
  /*
    throws_clause =
    throws class_name_list;
  */
  public void outAThrowsClause(AThrowsClause node) {
    List l = (List) mProductions.removeLast();

    Iterator it = l.iterator();
    List exceptionClasses = new ArrayList(l.size());

    while (it.hasNext()) {
      String className = (String) it.next();

      exceptionClasses.add(mResolver.makeClassRef(className));
    }

    mProductions.addLast(exceptionClasses);
  }
コード例 #9
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
 protected void buildPreds() {
   buildPredecessor(mainPegChain);
   Set maps = getStartToThread().entrySet();
   for (Iterator iter = maps.iterator(); iter.hasNext(); ) {
     Map.Entry entry = (Map.Entry) iter.next();
     List runMethodChainList = (List) entry.getValue();
     Iterator it = runMethodChainList.iterator();
     while (it.hasNext()) {
       Chain chain = (Chain) it.next();
       //	System.out.println("chain is null: "+(chain == null));
       buildPredecessor(chain);
     }
   }
 }
コード例 #10
0
ファイル: ASTSwitchNode.java プロジェクト: GeneBlue/JAADAS
  public void toString(UnitPrinter up) {
    label_toString(up);

    up.literal("switch");
    up.literal(" ");
    up.literal("(");
    keyBox.toString(up);
    up.literal(")");
    up.newline();

    up.literal("{");
    up.newline();

    Iterator<Object> it = indexList.iterator();
    while (it.hasNext()) {

      Object index = it.next();

      up.incIndent();

      if (index instanceof String) up.literal("default");
      else {
        up.literal("case");
        up.literal(" ");
        up.literal(index.toString());
      }

      up.literal(":");
      up.newline();

      List<Object> subBody = index2BodyList.get(index);

      if (subBody != null) {
        up.incIndent();
        body_toString(up, subBody);

        if (it.hasNext()) up.newline();
        up.decIndent();
      }
      up.decIndent();
    }

    up.literal("}");
    up.newline();
  }
コード例 #11
0
ファイル: ASTSwitchNode.java プロジェクト: GeneBlue/JAADAS
  public ASTSwitchNode(
      SETNodeLabel label,
      Value key,
      List<Object> indexList,
      Map<Object, List<Object>> index2BodyList) {
    super(label);

    this.keyBox = Jimple.v().newRValueBox(key);
    this.indexList = indexList;
    this.index2BodyList = index2BodyList;

    Iterator<Object> it = indexList.iterator();
    while (it.hasNext()) {
      List body = index2BodyList.get(it.next());

      if (body != null) subBodies.add(body);
    }
  }
コード例 #12
0
ファイル: Hierarchy.java プロジェクト: Hounge/apkinspector
  /** Given a set of definite receiver types, returns a list of possible targets. */
  public List resolveConcreteDispatch(List classes, SootMethod m) {
    m.getDeclaringClass().checkLevel(SootClass.HIERARCHY);
    checkState();

    ArraySet s = new ArraySet();
    Iterator classesIt = classes.iterator();

    while (classesIt.hasNext()) {
      Object cls = classesIt.next();
      if (cls instanceof RefType) s.add(resolveConcreteDispatch(((RefType) cls).getSootClass(), m));
      else if (cls instanceof ArrayType) {
        s.add(resolveConcreteDispatch((RefType.v("java.lang.Object")).getSootClass(), m));
      } else throw new RuntimeException("Unable to resolve concrete dispatch of type " + cls);
    }

    List l = new ArrayList();
    l.addAll(s);
    return Collections.unmodifiableList(l);
  }
コード例 #13
0
ファイル: ASTSwitchNode.java プロジェクト: GeneBlue/JAADAS
  public String toString() {
    StringBuffer b = new StringBuffer();

    b.append(label_toString());

    b.append("switch (");
    b.append(get_Key());
    b.append(")");
    b.append(NEWLINE);

    b.append("{");
    b.append(NEWLINE);

    Iterator<Object> it = indexList.iterator();
    while (it.hasNext()) {

      Object index = it.next();

      b.append(TAB);

      if (index instanceof String) b.append("default");
      else {
        b.append("case ");
        b.append(((Integer) index).toString());
      }

      b.append(":");
      b.append(NEWLINE);

      List<Object> subBody = index2BodyList.get(index);

      if (subBody != null) {
        b.append(body_toString(subBody));

        if (it.hasNext()) b.append(NEWLINE);
      }
    }

    b.append("}");
    b.append(NEWLINE);

    return b.toString();
  }
コード例 #14
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
  protected void testUnitToSucc() {
    System.out.println("=====test unitToSucc ");
    Set maps = unitToSuccs.entrySet();
    for (Iterator iter = maps.iterator(); iter.hasNext(); ) {
      Map.Entry entry = (Map.Entry) iter.next();
      JPegStmt key = (JPegStmt) entry.getKey();
      Tag tag = (Tag) key.getTags().get(0);
      System.out.println("---key=  " + tag + " " + key);
      List list = (List) entry.getValue();
      if (list.size() > 0) {

        System.out.println("**succ set: size: " + list.size());
        Iterator it = list.iterator();
        while (it.hasNext()) {
          JPegStmt stmt = (JPegStmt) it.next();
          Tag tag1 = (Tag) stmt.getTags().get(0);
          System.out.println(tag1 + " " + stmt);
        }
      }
    }
    System.out.println("=========unitToSucc--ends--------");
  }
コード例 #15
0
ファイル: Walker.java プロジェクト: safdariqbal/soot
  public void outAFile(AFile node) {
    // not not pop members; they have been taken care of.
    List implementsList = null;
    String superClass = null;

    String classType = null;

    if (node.getImplementsClause() != null) {
      implementsList = (List) mProductions.removeLast();
    }
    if (node.getExtendsClause() != null) {
      superClass = (String) mProductions.removeLast();
    }

    classType = (String) mProductions.removeLast();

    int modifierCount = node.getModifier().size();

    int modifierFlags = processModifiers(node.getModifier());

    if (classType.equals("interface")) modifierFlags |= Modifier.INTERFACE;

    mSootClass.setModifiers(modifierFlags);

    if (superClass != null) {
      mSootClass.setSuperclass(mResolver.makeClassRef(superClass));
    }

    if (implementsList != null) {
      Iterator implIt = implementsList.iterator();
      while (implIt.hasNext()) {
        SootClass interfaceClass = mResolver.makeClassRef((String) implIt.next());
        mSootClass.addInterface(interfaceClass);
      }
    }

    mProductions.addLast(mSootClass);
  }
コード例 #16
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
  private void buildHeadsAndTails() {

    List tailList = new ArrayList();
    List headList = new ArrayList();

    // Build the sets
    {
      Iterator unitIt = mainPegChain.iterator();

      while (unitIt.hasNext()) {
        JPegStmt s = (JPegStmt) unitIt.next();

        List succs = unitToSuccs.get(s);
        if (succs.size() == 0) tailList.add(s);
        if (!unitToPreds.containsKey(s)) {
          System.err.println("unitToPreds does not contain key: " + s);
          System.exit(1);
        }
        List preds = unitToPreds.get(s);
        if (preds.size() == 0) headList.add(s);
        // System.out.println("head is:");
      }
    }
    tails = (List) tailList;
    heads = (List) headList;
    //	tails = Collections.unmodifiableList(tailList);
    // heads = Collections.unmodifiableList(headList);

    Iterator tmpIt = heads.iterator();

    while (tmpIt.hasNext()) {
      Object temp = tmpIt.next();
      // System.out.println(temp);
    }

    buildPredecessor(mainPegChain);
  }
コード例 #17
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
  /*
  private void deleteExitToException(){
  Iterator it = iterator();
  while (it.hasNext()){
  JPegStmt stmt = (JPegStmt)it.next();
  Unit unit = stmt.getUnit();
  UnitGraph unitGraph = stmt.getUnitGraph();
  if (unit instanceof ExitMonitorStmt){
  Iterator succIt = unitGraph.getSuccsOf(unit).iterator();
  while(succIt.next
  && exceHandlers.contains(un) ){
  System.out.println("====find it! unit: "+unit+"\n un: "+un);
  continue;
  }
  }
  }
  */
  private void buildPredecessor(Chain pegChain) {
    // System.out.println("==building predcessor===");

    // initialize the pred sets to empty
    {
      JPegStmt s = null;
      Iterator unitIt = pegChain.iterator();
      while (unitIt.hasNext()) {

        s = (JPegStmt) unitIt.next();

        unitToPreds.put(s, new ArrayList());
      }
    }
    //	System.out.println("==finish init of unitToPred===");
    {
      Iterator unitIt = pegChain.iterator();

      while (unitIt.hasNext()) {

        Object s = unitIt.next();
        //		System.out.println("s is: "+s);

        // Modify preds set for each successor for this statement
        if (unitToSuccs.containsKey(s)) {
          List succList = unitToSuccs.get(s);
          Iterator succIt = succList.iterator();
          //		    System.out.println("unitToSuccs contains "+s);
          //		    System.out.println("succList is: "+succList);
          while (succIt.hasNext()) {

            // Object successor =  succIt.next();
            JPegStmt successor = (JPegStmt) succIt.next();
            //			System.out.println("successor is: "+successor);
            List<Object> predList = unitToPreds.get(successor);
            //			System.out.println("predList is: "+predList);
            if (predList != null && !predList.contains(s)) {
              try {
                predList.add(s);
                /*
                Tag tag1 = (Tag)((JPegStmt)s).getTags().get(0);
                System.out.println("add "+tag1+" "+s+" to predListof");
                Tag tag2 = (Tag)((JPegStmt)successor).getTags().get(0);
                System.out.println(tag2+" "+successor);
                */
              } catch (NullPointerException e) {
                System.out.println(s + "successor: " + successor);
                throw e;
              }
              // if (((JPegStmt)successor).getName().equals("start")){
              if (successor instanceof StartStmt) {
                List runMethodChainList = startToThread.get(successor);
                if (runMethodChainList == null) {
                  throw new RuntimeException("null runmehtodchain: \n" + successor.getUnit());
                }
                Iterator possibleMethodIt = runMethodChainList.iterator();
                while (possibleMethodIt.hasNext()) {

                  Chain subChain = (Chain) possibleMethodIt.next();

                  buildPredecessor(subChain);
                }
              }
            } else {
              System.err.println("predlist of " + s + " is null");
              //							System.exit(1);
            }
            //			unitToPreds.put(successor, predList);

          }

        } else {
          System.err.println("unitToSuccs does not contains key" + s);
          System.exit(1);
        }
      }
    }
  }
コード例 #18
0
ファイル: Hierarchy.java プロジェクト: Hounge/apkinspector
  /** Constructs a hierarchy from the current scene. */
  public Hierarchy() {
    this.sc = Scene.v();
    state = sc.getState();

    // Well, this used to be describable by 'Duh'.
    // Construct the subclasses hierarchy and the subinterfaces hierarchy.
    {
      Chain allClasses = sc.getClasses();

      classToSubclasses = new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);
      interfaceToSubinterfaces =
          new HashMap<SootClass, List<SootClass>>(allClasses.size() * 2 + 1, 0.7f);

      classToDirSubclasses = new HashMap<SootClass, List>(allClasses.size() * 2 + 1, 0.7f);
      interfaceToDirSubinterfaces = new HashMap<SootClass, List>(allClasses.size() * 2 + 1, 0.7f);
      interfaceToDirImplementers = new HashMap<SootClass, List>(allClasses.size() * 2 + 1, 0.7f);

      Iterator classesIt = allClasses.iterator();
      while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        if (c.resolvingLevel() < SootClass.HIERARCHY) continue;

        if (c.isInterface()) {
          interfaceToDirSubinterfaces.put(c, new ArrayList());
          interfaceToDirImplementers.put(c, new ArrayList());
        } else classToDirSubclasses.put(c, new ArrayList());
      }

      classesIt = allClasses.iterator();
      while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        if (c.resolvingLevel() < SootClass.HIERARCHY) continue;

        if (c.hasSuperclass()) {
          if (c.isInterface()) {
            Iterator subIt = c.getInterfaces().iterator();

            while (subIt.hasNext()) {
              SootClass i = (SootClass) subIt.next();
              if (c.resolvingLevel() < SootClass.HIERARCHY) continue;
              List<SootClass> l = interfaceToDirSubinterfaces.get(i);
              l.add(c);
            }
          } else {
            List<SootClass> l = classToDirSubclasses.get(c.getSuperclass());
            l.add(c);

            Iterator subIt = c.getInterfaces().iterator();

            while (subIt.hasNext()) {
              SootClass i = (SootClass) subIt.next();
              if (c.resolvingLevel() < SootClass.HIERARCHY) continue;
              l = interfaceToDirImplementers.get(i);
              l.add(c);
            }
          }
        }
      }

      // Fill the directImplementers lists with subclasses.
      {
        classesIt = allClasses.iterator();
        while (classesIt.hasNext()) {
          SootClass c = (SootClass) classesIt.next();
          if (c.resolvingLevel() < SootClass.HIERARCHY) continue;
          if (c.isInterface()) {
            List<SootClass> imp = interfaceToDirImplementers.get(c);
            Set<SootClass> s = new ArraySet();

            Iterator<SootClass> impIt = imp.iterator();
            while (impIt.hasNext()) {
              SootClass c0 = impIt.next();
              if (c.resolvingLevel() < SootClass.HIERARCHY) continue;
              s.addAll(getSubclassesOfIncluding(c0));
            }

            imp.clear();
            imp.addAll(s);
          }
        }
      }

      classesIt = allClasses.iterator();
      while (classesIt.hasNext()) {
        SootClass c = (SootClass) classesIt.next();
        if (c.resolvingLevel() < SootClass.HIERARCHY) continue;

        if (c.isInterface()) {
          interfaceToDirSubinterfaces.put(
              c, Collections.unmodifiableList(interfaceToDirSubinterfaces.get(c)));
          interfaceToDirImplementers.put(
              c, Collections.unmodifiableList(interfaceToDirImplementers.get(c)));
        } else
          classToDirSubclasses.put(c, Collections.unmodifiableList(classToDirSubclasses.get(c)));
      }
    }
  }
コード例 #19
0
  /*
    We know this method is called when there is a loop node which has a body
    consisting entirely of one ASTIfElseNode
  */
  public static List getNewNode(ASTNode loopNode, ASTIfElseNode ifElseNode) {
    // make sure that elsebody has only a stmtseq node
    List elseBody = ((ASTIfElseNode) ifElseNode).getElseBody();
    if (elseBody.size() != 1) {
      // this is more than one we need one stmtSeq Node
      return null;
    }
    ASTNode tempNode = (ASTNode) elseBody.get(0);
    if (!(tempNode instanceof ASTStatementSequenceNode)) {
      // not a stmtSeq
      return null;
    }

    List statements = ((ASTStatementSequenceNode) tempNode).getStatements();
    Iterator stmtIt = statements.iterator();
    while (stmtIt.hasNext()) {
      AugmentedStmt as = (AugmentedStmt) stmtIt.next();
      Stmt stmt = as.get_Stmt();
      if (stmt instanceof DAbruptStmt) {
        // this is a abrupt stmt
        DAbruptStmt abStmt = (DAbruptStmt) stmt;
        if (!(abStmt.is_Break())) {
          // we need a break
          return null;
        } else {
          if (stmtIt.hasNext()) {
            // a break should be the last stmt
            return null;
          }
          SETNodeLabel label = abStmt.getLabel();
          String labelBroken = label.toString();
          String loopLabel = ((ASTLabeledNode) loopNode).get_Label().toString();
          if (labelBroken != null && loopLabel != null) { // stmt breaks some label
            if (labelBroken.compareTo(loopLabel) == 0) {
              // we have found a break breaking this label

              // make sure that if the orignal was an ASTWhileNode then there was
              // ONLY a break statement
              if (loopNode instanceof ASTWhileNode) {
                if (statements.size() != 1) {
                  // more than 1 statement
                  return null;
                }
              }

              // pattern matched
              ASTWhileNode newWhileNode = makeWhileNode(ifElseNode, loopNode);
              if (newWhileNode == null) {
                return null;
              }
              List toReturn = new ArrayList();
              toReturn.add(newWhileNode);

              //  Add the statementSequenceNode AFTER the whileNode except for the laststmt
              if (statements.size() != 1) {
                // size 1 means that the only stmt is a break stmt

                Iterator tempIt = statements.iterator();
                List newStmts = new ArrayList();
                while (tempIt.hasNext()) {
                  Object tempStmt = tempIt.next();
                  if (tempIt.hasNext()) {
                    newStmts.add(tempStmt);
                  }
                }
                toReturn.add(new ASTStatementSequenceNode(newStmts));
              }
              return toReturn;
            } // labels matched
          } // non null labels
        } // end of break stmt
      } // stmt is an abrupt stmt
      else if (stmt instanceof ReturnStmt || stmt instanceof ReturnVoidStmt) {
        if (!(loopNode instanceof ASTUnconditionalLoopNode)) {
          // this pattern is only possible for while(true)
          return null;
        }

        if (stmtIt.hasNext()) {
          // returns should come in the end
          return null;
        }

        // pattern matched
        ASTWhileNode newWhileNode = makeWhileNode(ifElseNode, loopNode);
        if (newWhileNode == null) {
          return null;
        }
        List toReturn = new ArrayList();
        toReturn.add(newWhileNode);

        //  Add the statementSequenceNode AFTER the whileNode
        Iterator tempIt = statements.iterator();
        List newStmts = new ArrayList();
        while (tempIt.hasNext()) {
          Object tempStmt = tempIt.next();
          newStmts.add(tempStmt);
        }
        toReturn.add(new ASTStatementSequenceNode(newStmts));
        return toReturn;
      } // if stmt was a return stmt
    } // going through the stmts
    return null;
  } // end of method
コード例 #20
0
  private static boolean internalAggregate(
      StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) {
    LocalUses localUses;
    LocalDefs localDefs;
    ExceptionalUnitGraph graph;
    boolean hadAggregation = false;
    Chain<Unit> units = body.getUnits();

    graph = new ExceptionalUnitGraph(body);
    localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph));
    localUses = new SimpleLocalUses(graph, localDefs);

    List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false);
    for (Unit u : unitList) {
      if (!(u instanceof AssignStmt)) continue;
      AssignStmt s = (AssignStmt) u;

      Value lhs = s.getLeftOp();
      if (!(lhs instanceof Local)) continue;
      Local lhsLocal = (Local) lhs;

      if (onlyStackVars && !lhsLocal.getName().startsWith("$")) continue;

      List<UnitValueBoxPair> lu = localUses.getUsesOf(s);
      if (lu.size() != 1) continue;

      UnitValueBoxPair usepair = lu.get(0);
      Unit use = usepair.unit;
      ValueBox useBox = usepair.valueBox;

      List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use);
      if (ld.size() != 1) continue;

      // Check to make sure aggregation pair in the same zone
      if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) {
        continue;
      }

      /* we need to check the path between def and use */
      /* to see if there are any intervening re-defs of RHS */
      /* in fact, we should check that this path is unique. */
      /* if the RHS uses only locals, then we know what
      to do; if RHS has a method invocation f(a, b,
      c) or field access, we must ban field writes, other method
      calls and (as usual) writes to a, b, c. */

      boolean cantAggr = false;
      boolean propagatingInvokeExpr = false;
      boolean propagatingFieldRef = false;
      boolean propagatingArrayRef = false;
      ArrayList<FieldRef> fieldRefList = new ArrayList<FieldRef>();

      LinkedList<Value> localsUsed = new LinkedList<Value>();
      for (ValueBox vb : s.getUseBoxes()) {
        Value v = vb.getValue();
        if (v instanceof Local) localsUsed.add(v);
        else if (v instanceof InvokeExpr) propagatingInvokeExpr = true;
        else if (v instanceof ArrayRef) propagatingArrayRef = true;
        else if (v instanceof FieldRef) {
          propagatingFieldRef = true;
          fieldRefList.add((FieldRef) v);
        }
      }

      // look for a path from s to use in graph.
      // only look in an extended basic block, though.

      List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use);

      if (path == null) continue;

      Iterator<Unit> pathIt = path.iterator();

      // skip s.
      if (pathIt.hasNext()) pathIt.next();

      while (pathIt.hasNext() && !cantAggr) {
        Stmt between = (Stmt) (pathIt.next());

        if (between != use) {
          // Check for killing definitions

          for (ValueBox vb : between.getDefBoxes()) {
            Value v = vb.getValue();
            if (localsUsed.contains(v)) {
              cantAggr = true;
              break;
            }

            if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
              if (v instanceof FieldRef) {
                if (propagatingInvokeExpr) {
                  cantAggr = true;
                  break;
                } else if (propagatingFieldRef) {
                  // Can't aggregate a field access if passing a definition of a field
                  // with the same name, because they might be aliased
                  for (FieldRef fieldRef : fieldRefList) {
                    if (((FieldRef) v).getField() == fieldRef.getField()) {
                      cantAggr = true;
                      break;
                    }
                  }
                }
              } else if (v instanceof ArrayRef) {
                if (propagatingInvokeExpr) {
                  // Cannot aggregate an invoke expr past an array write
                  cantAggr = true;
                  break;
                } else if (propagatingArrayRef) {
                  // cannot aggregate an array read past a write
                  // this is somewhat conservative
                  // (if types differ they may not be aliased)

                  cantAggr = true;
                  break;
                }
              }
            }
          }

          // Make sure not propagating past a {enter,exit}Monitor
          if (propagatingInvokeExpr && between instanceof MonitorStmt) cantAggr = true;
        }

        // Check for intervening side effects due to method calls
        if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
          for (final ValueBox box : between.getUseBoxes()) {
            if (between == use && box == useBox) {
              // Reached use point, stop looking for
              // side effects
              break;
            }

            Value v = box.getValue();

            if (v instanceof InvokeExpr
                || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) {
              cantAggr = true;
              break;
            }
          }
        }
      }

      // we give up: can't aggregate.
      if (cantAggr) {
        continue;
      }
      /* assuming that the d-u chains are correct, */
      /* we need not check the actual contents of ld */

      Value aggregatee = s.getRightOp();

      if (usepair.valueBox.canContainValue(aggregatee)) {
        boolean wasSimpleCopy = isSimpleCopy(usepair.unit);
        usepair.valueBox.setValue(aggregatee);
        units.remove(s);
        hadAggregation = true;
        // clean up the tags. If s was not a simple copy, the new statement should get
        // the tags of s.
        // OK, this fix was wrong. The condition should not be
        // "If s was not a simple copy", but rather "If usepair.unit
        // was a simple copy". This way, when there's a load of a constant
        // followed by an invoke, the invoke gets the tags.
        if (wasSimpleCopy) {
          // usepair.unit.removeAllTags();
          usepair.unit.addAllTagsOf(s);
        }
      } else {
        /*
        if(Options.v().verbose())
        {
            G.v().out.println("[debug] failed aggregation");
              G.v().out.println("[debug] tried to put "+aggregatee+
                             " into "+usepair.stmt +
                             ": in particular, "+usepair.valueBox);
              G.v().out.println("[debug] aggregatee instanceof Expr: "
                             +(aggregatee instanceof Expr));
        }*/
      }
    }
    return hadAggregation;
  }
コード例 #21
0
ファイル: PegGraph.java プロジェクト: Hounge/apkinspector
  private void buildSuccessor(Chain pegChain) {

    // Add regular successors
    {
      HashMap unitToPeg = (HashMap) unitToPegMap.get(pegChain);
      Iterator pegIt = pegChain.iterator();
      JPegStmt currentNode, nextNode;
      currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next() : null;
      // June 19 add for begin node
      if (currentNode != null) {
        // System.out.println("currentNode: "+currentNode);
        // if the unit is "begin" node
        nextNode = pegIt.hasNext() ? (JPegStmt) pegIt.next() : null;

        if (currentNode.getName().equals("begin")) {
          List<JPegStmt> successors = new ArrayList<JPegStmt>();
          successors.add(nextNode);
          unitToSuccs.put(currentNode, successors);

          currentNode = nextNode;
        }
        // end June 19 add for begin node

        while (currentNode != null) {
          //		    System.out.println("currentNode: "+currentNode);
          /* If unitToSuccs contains currentNode, it is the point to inline methods,
           * we need not compute its successors again
           */

          if (unitToSuccs.containsKey(currentNode) && !currentNode.getName().equals("wait")) {
            currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next() : null;
            continue;
          }
          List<JPegStmt> successors = new ArrayList<JPegStmt>();
          Unit unit = currentNode.getUnit();

          UnitGraph unitGraph = currentNode.getUnitGraph();
          List unitSucc = unitGraph.getSuccsOf(unit);
          Iterator succIt = unitSucc.iterator();
          while (succIt.hasNext()) {
            Unit un = (Unit) succIt.next();

            // Don't build the edge from "monitor exit" to exception handler

            if (unit instanceof ExitMonitorStmt && exceHandlers.contains(un)) {
              // System.out.println("====find it! unit: "+unit+"\n un: "+un);
              continue;
            } else if (unitToPeg.containsKey(un)) {
              JPegStmt pp = (JPegStmt) (unitToPeg.get(un));
              if (pp != null && !successors.contains(pp)) successors.add(pp);
            }
          } // end while

          if (currentNode.getName().equals("wait")) {
            while (!(currentNode.getName().equals("notified-entry"))) {
              currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next() : null;
            }
            unitToSuccs.put(currentNode, successors);
            // System.out.println("put key: "+currentNode+" into unitToSucc");
          } else {
            unitToSuccs.put(currentNode, successors);
          }
          if (currentNode.getName().equals("start")) {

            //						System.out.println("-----build succ for start----");

            if (startToThread.containsKey(currentNode)) {
              List runMethodChainList = startToThread.get(currentNode);
              Iterator possibleMethodIt = runMethodChainList.iterator();
              while (possibleMethodIt.hasNext()) {

                Chain subChain = (Chain) possibleMethodIt.next();
                if (subChain != null) {
                  // System.out.println("build succ for subChain");
                  // buildSuccessor(subGraph, subChain, addExceptionEdges);
                  buildSuccessor(subChain);
                } else System.out.println("*********subgraph is null!!!");
              }
            }
          }

          currentNode = pegIt.hasNext() ? (JPegStmt) pegIt.next() : null;
        } // while

        // June 19 add for begin node
      }
      // end June 19 add for begin node
    }
  }
コード例 #22
0
  /**
   * This method pushes all newExpr down to be the stmt directly before every invoke of the init
   * only if they are in the types list
   */
  public void internalTransform(Body b, String phaseName, Map options) {
    JimpleBody body = (JimpleBody) b;

    if (Options.v().verbose())
      G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors...");

    Chain units = body.getUnits();
    List<Unit> stmtList = new ArrayList<Unit>();
    stmtList.addAll(units);

    Iterator<Unit> it = stmtList.iterator();
    Iterator<Unit> nextStmtIt = stmtList.iterator();
    // start ahead one
    nextStmtIt.next();

    SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body);
    UnitGraph graph = localDefs.getGraph();
    LocalUses localUses = new SimpleLocalUses(graph, localDefs);

    /* fold in NewExpr's with specialinvoke's */
    while (it.hasNext()) {
      Stmt s = (Stmt) it.next();

      if (!(s instanceof AssignStmt)) continue;

      /* this should be generalized to ArrayRefs */
      // only deal with stmts that are an local = newExpr
      Value lhs = ((AssignStmt) s).getLeftOp();
      if (!(lhs instanceof Local)) continue;

      Value rhs = ((AssignStmt) s).getRightOp();
      if (!(rhs instanceof NewExpr)) continue;

      // check if very next statement is invoke -->
      // this indicates there is no control flow between
      // new and invoke and should do nothing
      if (nextStmtIt.hasNext()) {
        Stmt next = (Stmt) nextStmtIt.next();
        if (next instanceof InvokeStmt) {
          InvokeStmt invoke = (InvokeStmt) next;

          if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
            SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr();
            if (invokeExpr.getBase() == lhs) {
              break;
            }
          }
        }
      }

      // check if new is in the types list - only process these
      if (!types.contains(((NewExpr) rhs).getType())) continue;

      List lu = localUses.getUsesOf(s);
      Iterator luIter = lu.iterator();
      boolean MadeNewInvokeExpr = false;

      while (luIter.hasNext()) {
        Unit use = ((UnitValueBoxPair) (luIter.next())).unit;
        if (!(use instanceof InvokeStmt)) continue;
        InvokeStmt is = (InvokeStmt) use;
        if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr)
            || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue;

        // make a new one here
        AssignStmt constructStmt =
            Jimple.v()
                .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp());
        constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType()));
        MadeNewInvokeExpr = true;

        // redirect jumps
        use.redirectJumpsToThisTo(constructStmt);
        // insert new one here
        units.insertBefore(constructStmt, use);

        constructStmt.addTag(s.getTag("SourceLnPosTag"));
      }
      if (MadeNewInvokeExpr) {
        units.remove(s);
      }
    }
  }