Сажи получают методическими органами основных классов

Я написал небольшое обнаружение побочных эффектов для Java с использованием сажи. это дает мне ожидаемый результат для функций, которые я написал самостоятельно. Но для базовых классов (java.lang., Java.awt.) Это не работает.

Я хочу проанализировать следующую функцию с помощью сажи:

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

Я ожидаю вывод, который просто возвращает значение x объекта из java.awt.Point, но Soot предоставляет следующий код для функции 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; 
}

Я использую следующий код для обнаружения побочных эффектов:

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);

Нужно ли загружать классы вручную? Если да, как я могу это сделать?

1 ответ

Вы пытались вызвать retrieveActiveBody() для соответствующего SootMethod?

Другие вопросы по тегам