Skip to content

Commit

Permalink
Merge pull request #959 from soot-oss/doc/typehierarchy
Browse files Browse the repository at this point in the history
add TypeHierarchy doc
  • Loading branch information
swissiety authored Jul 1, 2024
2 parents 76dc30e + dcc56b3 commit c553f63
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 17 deletions.
28 changes: 21 additions & 7 deletions docs/analysisinputlocations.md → docs/analysisinput.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions docs/callgraphs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)"

Expand Down Expand Up @@ -136,6 +136,7 @@ You can construct a call graph with RTA as follows:
}
```

<!--
## Variable Type Analysis
(**WIP!**)
Expand Down Expand Up @@ -175,3 +176,4 @@ Spark requires an initial call graph to begin with. You can use one of the call
}
```
-->
10 changes: 5 additions & 5 deletions docs/tool_setup.md
Original file line number Diff line number Diff line change
@@ -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
<dependency>
Expand All @@ -28,7 +28,7 @@ Dependencies:
```java

class SootUpConfiguration{
// TODO incorporate
// TODO incorporate from downstream
}

```
Expand Down
91 changes: 91 additions & 0 deletions docs/typehierarchy.md
Original file line number Diff line number Diff line change
@@ -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<AnalysisInputLocation> 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);

```
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -19,6 +19,7 @@ nav:

- Advanced Topics:
- BodyInterceptors: bodyinterceptors.md
- TypeHierarchy: typehierarchy.md
- Callgraphs: callgraphs.md
- BuiltIn Analyses: builtin-analyses.md

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ClassType> subtypesOf(@Nonnull ClassType type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public Stream<ClassType> 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);
}
Expand Down

0 comments on commit c553f63

Please sign in to comment.