diff --git a/docs/analysisinputlocations.md b/docs/analysisinput.md similarity index 57% rename from docs/analysisinputlocations.md rename to docs/analysisinput.md index 3c2773364b4..ad530b175b2 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinput.md @@ -2,24 +2,38 @@ i.e. What should be analyzed - an `AnalysisInputLocation` points to code input SootUp can analyze. We ship multiple Subclasses that can handle different code input. +You can specify a SourceType - which e.g. determines how far an analysis will go. +Additionally you can specify a List of [BodyInterceptors](bodyinterceptors.md), which will optimize the raw Jimple IR that was transformed from the input. + ### Java Runtime -- Java <=8: `DefaultRTJaAnalysisInputLocation` current rt.jar (or point to any rt.jar as its just a usual .jar file) -- Java >=9: `JRTFilesystemAnalysisInputLocation` +points to the runtime library of the executing JVM. + +- Java <=8: `DefaultRTJaAnalysisInputLocation` points to the rt.jar of the executing JVM. +- To include a different Java Runtime library point to any rt.jar via a `JavaClassPathAnalysisInputLocation` as its a usual .jar file. +- Java >=9: `JRTFilesystemAnalysisInputLocation` points to the jigsawed java runtime of the executing jvm. If you have errors like Java.lang.String, Java.lang.Object, ... you are most likely missing this AnalysisInput. -### Java Bytecode .class, .jar, .war +### Java Bytecode +File-Extensions: `.class, .jar, .war` + - `JavaClassPathAnalysisInputLocation` - its the equivalent of the classpath you would pass to the java executable i.e. point to root(s) of package(s). -### Java Sourcecode .java +### Java Sourcecode +File-Extensions: `.java` + - `OTFCompileAnalysisInputLocation` - you can point directly to .java files or pass a String with Java sourcecode, SootUp delegates to the `JavaCompiler` and transform the bytecode from the compiler to Jimple - `JavaSourcePathInputLocation` [***experimental!***]{Has huge problems with exceptional flow!} - points to a directory that is the root source directory (containing the package directory structure). -### Jimple .jimple +### Jimple +File-Extensions: `.jimple` + - `JimpleAnalysisInputLocation` - needs a Path to a .jimple file or a directory. -### Android Bytecode .dex -- `ApkAnalysisInputLocation` - currenlty uses dex2jar internally - A SootUp solution to directly generate Jimple is WIP! +### Android Bytecode +File-Extensions: `.apk` + +- `ApkAnalysisInputLocation` - currently uses dex2jar internally - A SootUp solution to directly generate Jimple is WIP! ### Java cli arguments to configure SootUp diff --git a/docs/callgraphs.md b/docs/callgraphs.md index dbfb503481d..35debb251ca 100644 --- a/docs/callgraphs.md +++ b/docs/callgraphs.md @@ -21,10 +21,10 @@ Below, we show how to create a type hierarchy: === "Soot" ```java - String targetTestClassName = target.exercise1.Hierarchy.class.getName(); - G.reset(); String userdir = System.getProperty("user.dir"); String sootCp = userdir + File.separator + "target" + File.separator + "test-classes"+ File.pathSeparator + "lib"+File.separator+"rt.jar"; + String targetTestClassName = target.exercise1.Hierarchy.class.getName(); + G.reset(); Options.v().set_whole_program(true); Options.v().set_soot_classpath(sootCp); Options.v().set_no_bodies_for_excluded(true); @@ -42,7 +42,7 @@ Below, we show how to create a type hierarchy: ``` ## Defining an Entry Method -All the call graph construction algorithms require an entry method to start with. In java application, you usually define the main method. However, it is possible to define arbitrary entry methods depending on your needs. Below, we show how to define such an entry method: +All call graph construction algorithms require an entry method to start with. In java application, you usually define the main method. However, it is possible to define arbitrary entry methods depending on your needs. Below, we show how to define such an entry method: === "SootUp (performant)" @@ -136,6 +136,7 @@ You can construct a call graph with RTA as follows: } ``` + diff --git a/docs/tool_setup.md b/docs/tool_setup.md index ee4445427f8..93c6d00dda8 100644 --- a/docs/tool_setup.md +++ b/docs/tool_setup.md @@ -1,14 +1,14 @@ # From Prototype to an intuitive Tool - -`How was the parameter order again?` +**How was the parameter order again?** For a lot of cli tools we see an arbitrary order of cli parameters, different options for giving a working directory etc.. -So in the wild you can see a lot from run.sh/run.bat to make files just to reorder arguments and calling a tool. +So in the wild you can see a lot from run.sh/run.bat to make files just to reorder arguments to execute a tool. In SootUp we thought we could help on improving this madness while saving your time. The command line parser mimics the options the java executable accepts - at least for what is supported by SootUp. +This makes it very simple to just copy the execution paramaters you use for execution, to use them more or less as is four the analysis tool. -Dependencies: +### Dependencies === "Maven" ```maven @@ -28,7 +28,7 @@ Dependencies: ```java class SootUpConfiguration{ - // TODO incorporate + // TODO incorporate from downstream } ``` diff --git a/docs/typehierarchy.md b/docs/typehierarchy.md new file mode 100644 index 00000000000..7c07b3c983d --- /dev/null +++ b/docs/typehierarchy.md @@ -0,0 +1,91 @@ +# TypeHierarchy +The TypeHierarchy models the relationship of Classes or Interfaces of a OOP program. + +## Creating TypeHierarchy + +=== "SootUp" + + ```java + String cpString = "src/test/resources/Callgraph/binary"; + List inputLocations = new ArrayList(); + inputLocations.add(new JavaClassPathAnalysisInputLocation(cpStr)); + inputLocations.add(new DefaultRTJarAnalysisInputLocation()); + + JavaView view = new JavaView(inputLocations); + TypeHierarchy typehierarchy = view.getTypeHierarchy(); + ``` + +=== "Soot" + + ```java + String userdir = System.getProperty("user.dir"); + String sootCp = userdir + File.separator + "target" + File.separator + "test-classes"+ File.pathSeparator + "lib"+File.separator+"rt.jar"; + + String targetTestClassName = target.exercise1.Hierarchy.class.getName(); + G.reset(); + Options.v().set_whole_program(true); + Options.v().set_soot_classpath(sootCp); + Options.v().set_no_bodies_for_excluded(true); + Options.v().process_dir(); + Options.v().set_allow_phantom_refs(true); + Options.v().setPhaseOption("jb", "use-original-names:true"); + Options.v().set_prepend_classpath(false); + SootClass c = Scene.v().forceResolve(targetTestClassName, SootClass.BODIES); + if (c != null) + c.setApplicationClass(); + Scene.v().loadNecessaryClasses(); + + Hierarchy hierarchy = new Hierarchy(); + + ``` + +## Create a JavaClassType + +=== "SootUp" + + ```java + JavaClassType classTypeA = view.getIdentifierFactory().getClassType("packageName.A"); + JavaClassType classTypeB = view.getIdentifierFactory().getClassType("packageName.B"); + JavaClassType classTypeC = view.getIdentifierFactory().getClassType("packageName.C"); + + ``` +=== "Soot" + + ```java + String targetTestClassName = "packageNameA.A"; + SootClass methodA = Scene.v().getSootClass(targetTestClassName); + + ``` + +## Query the TypeHierarchy +### Classes +```java + // if the assertion fails, the following methods will throw an Exception (you don't have to call it - it's just to illustrate the assumption) + assert typehierarchy.contains(classTypeA); + + typehierarchy.superclassOf(classTypeA); + + typehierarchy.subclassesOf(classTypeA); + + typehierarchy.isSubtypeOf(classTypeA, classTypeB); + +``` + +### Interfaces + +```java + JavaClassType iterableInterface = view.getIdentifierFactory().getClassType("java.lang.Iterable"); + + // if any of the assertions fail, the following methods will throw an Exception (you don't have to call these - it's just to illustrate the assumptions) + assert typehierarchy.contains(iterableInterface); + assert typehierarchy.isInterface(iterableInterface); + + // transitive relations as well + typehierarchy.implementedInterfacesOf(iterableInterface); + typehierarchy.implementersOf(iterableInterface); + + // only the direct related relations + typehierarchy.directlyImplementedInterfacesOf(iterableInterface); + typehierarchy.directlyExtendedInterfacesOf(iterableInterface); + +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 87633845ac6..c20dbc5db63 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,7 +7,7 @@ nav: - Getting Started: - Installation: installation.md - First Steps: getting-started.md - - Analysis Input: analysisinputlocations.md + - Analysis Input: analysisinput.md - Examples: examples.md - Basics: @@ -19,6 +19,7 @@ nav: - Advanced Topics: - BodyInterceptors: bodyinterceptors.md + - TypeHierarchy: typehierarchy.md - Callgraphs: callgraphs.md - BuiltIn Analyses: builtin-analyses.md diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java index d3fdd18d6e5..4dfa5a53a4b 100644 --- a/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java +++ b/sootup.core/src/main/java/sootup/core/typehierarchy/TypeHierarchy.java @@ -75,6 +75,7 @@ public interface TypeHierarchy { * For an interface type, this does the same as {@link #implementersOf(ClassType)}. For a class * type, this does the same as {@link #subclassesOf(ClassType)}. */ + // TODO: [ms] check! not sure this method makes sense in the interface.. @Nonnull Stream subtypesOf(@Nonnull ClassType type); diff --git a/sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java b/sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java index 192110019b5..6f7392529be 100644 --- a/sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java +++ b/sootup.core/src/main/java/sootup/core/typehierarchy/ViewTypeHierarchy.java @@ -183,7 +183,7 @@ public Stream directlyExtendedInterfacesOf(@Nonnull ClassType interfa throw new IllegalArgumentException("Could not find " + interfaceType + " in hierarchy."); } if (vertex.type != VertexType.Interface) { - throw new IllegalArgumentException(interfaceType + " is not a class."); + throw new IllegalArgumentException(interfaceType + " is not an interface."); } return directExtendedInterfacesOf(vertex).map(v -> v.javaClassType); }