SootUp
SootUp copied to clipboard
JimpleBasedInterproceduralCFG.getCalleesOfCallAt return callees is empty
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
@JonasKlauke is this addressed by your recent PR?
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.