soot-oss / SootUp

A new version of Soot with a completely overhauled architecture
https://soot-oss.github.io/SootUp/
GNU Lesser General Public License v2.1
566 stars 73 forks source link

JimpleBasedInterproceduralCFG.getCalleesOfCallAt return callees is empty #678

Open struce2 opened 1 year ago

struce2 commented 1 year ago

Analysis Class

class Demo {
    interface abc {
        String Run(String s);
    }

    class abcImpl1 implements abc {

        public String Run(String s) {
            System.out.println("abcImpl1");
            return s;
        }
    }

    class abcImpl2 implements abc {
        public String s1;
        public String Run(String s) {
            System.out.println("abcImpl2");
            try {
                Runtime.getRuntime().exec(s);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
    }

    public void abc() {
        abc a = new abcImpl1();
        a.Run("aaa");
    }
}

Run javac Demo.java -d /tmp/samples/classes to build to class

Run the code below for analysis it

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sootup.analysis.interprocedural.icfg.JimpleBasedInterproceduralCFG;
import sootup.core.inputlocation.AnalysisInputLocation;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.Body;
import sootup.core.model.SootMethod;
import sootup.core.model.SourceType;
import sootup.core.signatures.MethodSignature;
import sootup.core.types.ClassType;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.bytecode.inputlocation.JavaModulePathAnalysisInputLocation;
import sootup.java.bytecode.inputlocation.PathBasedAnalysisInputLocation;
import sootup.java.core.JavaIdentifierFactory;
import sootup.java.core.JavaProject;
import sootup.java.core.JavaSootClass;
import sootup.java.core.language.JavaLanguage;
import sootup.java.core.views.JavaView;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

import static sootup.core.model.SourceType.Application;

public class Example {

    private static final Logger logger = LoggerFactory.getLogger(Example.class);

    public static void main(String[] args) {

        Path pathToBinary = Paths.get("/tmp/samples/classes");
        AnalysisInputLocation<JavaSootClass> inputLocation = PathBasedAnalysisInputLocation.create(pathToBinary, Application);
        JavaProject applicationProject = JavaProject.builder(new JavaLanguage(8)).addInputLocation(inputLocation)
                .build();

        ClassType classType = JavaIdentifierFactory.getInstance().getClassType("Demo");
        JavaView javaView = applicationProject.createOnDemandView();

        List<String> l = new ArrayList<>();
        MethodSignature entryMethodSignature = javaView.getIdentifierFactory().getMethodSignature(classType, "abc", "void", l);

        JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(javaView, entryMethodSignature, false, false);
        Optional<? extends SootMethod> entry = javaView.getMethod(entryMethodSignature);
        if (entry.isPresent()) {
            Body body = entry.get().getBody();
            List<Stmt> stmts = body.getStmts();
            for (Stmt stmt : stmts) {
                if (stmt.containsInvokeExpr()) {
                    Collection<SootMethod> sootMethods = icfg.getCalleesOfCallAt(stmt);
                    logger.info("call: " + sootMethods.toString());
                }
            }
        }
    }
}

Here is the log:

[main] WARN sootup.core.typehierarchy.TypeHierarchy - Could not find java.lang.Object and stopped there the resolve of superclasses of Demo$abcImpl1
[main] WARN sootup.core.typehierarchy.TypeHierarchy - Could not find java.lang.System and stopped there the resolve of superclasses of java.lang.System
[main] WARN sootup.core.typehierarchy.TypeHierarchy - Could not find java.lang.Runtime and stopped there the resolve of superclasses of java.lang.Runtime
[main] WARN sootup.core.typehierarchy.TypeHierarchy - Could not find java.lang.System and stopped there the resolve of superclasses of java.lang.System
[main] INFO Example - call: [<Demo$abcImpl1: void <init>(Demo)>]
[main] ERROR sootup.analysis.interprocedural.icfg.JimpleBasedInterproceduralCFG - Method <Demo$abc: java.lang.String Run(java.lang.String)> is referenced but has no body!
java.lang.Exception
    at sootup.analysis.interprocedural.icfg.JimpleBasedInterproceduralCFG$1.load(JimpleBasedInterproceduralCFG.java:84)
    at sootup.analysis.interprocedural.icfg.JimpleBasedInterproceduralCFG$1.load(JimpleBasedInterproceduralCFG.java:71)
    at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3570)
    at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2312)
    at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2189)
    at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2079)
    at com.google.common.cache.LocalCache.get(LocalCache.java:4011)
    at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4034)
    at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5010)
    at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5017)
    at sootup.analysis.interprocedural.icfg.JimpleBasedInterproceduralCFG.getCalleesOfCallAt(JimpleBasedInterproceduralCFG.java:193)
    at Example.main(Example.java:68)
[main] INFO Example - call: []

when stmt is a.Run("aaa"), getCalleesOfCallAt should return Demo.abcImpl1.Run and Demo.abcImpl2.Run ?

I am not sure

You should use v1.1.2 or earlier for test, see issue #677

swissiety commented 1 year ago

@JonasKlauke is this addressed by your recent PR?

JonasKlauke commented 1 year ago

that seems to be another issue. The interface method is considered as target. But it has no body, so it crashes. That is a bug in the Interprocedural CFG generation. The CFG generation should not consider the interface method (without a default method) as target.