2017-11-01 15 views
0

私はsootを使ってJava用の小さな副作用検出を書きました。私自身が書いた関数の期待出力を私に渡します。しかし、基本クラス(java.lang。、java.awt。)では動作しません。Sootは基本クラスのメソッド本体を取得します

私はすすで、次の機能を分析する:

public void testMeWithSoot(){ 
    Point p = new Point(1,1); 
    double q = Math.sqrt(p.getX() + 9); 
} 

私はちょうどjava.awt.Pointのからオブジェクトのx値を返しますが、すすは、以下のことを実現した出力を、期待していのgetX機能のためのコード:

public double getX(){ 
    java.awt.Point $r0; 
    java.lang.Error $r1; 
    $r0 :=> @this: java.awt.Point; 
    $r1 = new java.lang.Error; 
    specialinvoke $r1.<java.lang.Error: void <init>(java.lang.String)>("Unresolved 
    compilation error: Method <java.awt.Point: double getX()> does not exist!"); 
    throw $r1; 
} 

私は辺eを検出するために、次のコードを使用しますffects:

public static boolean hasSideEffects(SootMethod toAnalyse){ 
    HashSet<SootMethod> visited = new HashSet<>(); 
    Stack<SootMethod> toVisit = new Stack<>(); 
    toVisit.add(toAnalyse); 
    while (!toVisit.empty()){ 
     SootMethod current = toVisit.pop(); 
     if(visited.contains(current)) continue; 
     System.out.println(current.retrieveActiveBody()); 
     visited.add(current); 
     List<AssignStmt> assignments = current.retrieveActiveBody().getUnits().stream().filter(it -> it instanceof AssignStmt).map(it -> (AssignStmt) it).collect(Collectors.toList()); 
     if(assignments.stream().filter(it -> it.getLeftOp() instanceof FieldRef).findAny().orElse(null) != null){ 
      return true; 
     } 
     if(assignments.stream().filter(it -> it.getRightOp() instanceof FieldRef).findAny().orElse(null) != null){ 
      return true; 
     } 
     List<SootMethodRef> assignMethods = assignments.stream().filter(it -> it.getRightOp() instanceof InvokeExpr).map(it -> ((InvokeExpr) it.getRightOp()).getMethodRef()).collect(Collectors.toList()); 
     assignMethods.addAll(current.retrieveActiveBody().getUnits().stream().filter(it -> it instanceof InvokeStmt).map(it -> ((InvokeStmt) it).getInvokeExpr().getMethodRef()).collect(Collectors.toList())); 


     for (SootMethodRef ref: assignMethods) { 
      SootClass sootClass = bringClassToScene(ref.declaringClass().getName()); 
      sootClass.setApplicationClass(); 
      toVisit.add(ref.resolve()); 
     } 
    } 
    return false; 
} 

関数コール:私は手動でクラスをロードするために

classToAnalyse = Scene.v().loadClassAndSupport("ToAnalyseTest"); 
SootMethod method = classToAnalyse.getMethod("void testMeWithSoot()"); 
hasSideEffects(method); 

を持っていますか? はいの場合はどうすればよいですか?

答えて

0

それぞれのSootMethodでretrieveActiveBody()を呼び出してみましたか?

関連する問題