From 2d18d48f3187524b4f73c0f9183740284168d707 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 14 Jun 2024 10:46:48 +0200 Subject: [PATCH 01/23] navigation draft + doc directory structure --- README.md | 2 +- docs/advanced-topics.md | 4 +-- docs/{ => assets}/SootUp-paper.pdf | Bin .../figures/CopyPropagator Example_1.png | Bin .../figures/CopyPropagator Example_2.png | Bin .../figures/DominanceFinder Example.png | Bin .../figures/EmptySwitchEliminator Example.png | Bin .../figures/LocalLiveness Example.png | Bin .../figures/LocalPacker Example.png | Bin .../figures/LocalSplitter Example_1.png | Bin .../figures/LocalSplitter Example_2.png | Bin docs/{ => assets}/figures/SSA Example_1.png | Bin docs/{ => assets}/figures/SSA Example_2.png | Bin .../figures/TrapTightener Example.png | Bin .../UnreachableCodeEliminator Example.png | Bin docs/bodyinterceptors.md | 20 +++++------ docs/{ => img}/SootUpLogo.svg | 0 docs/{ => img}/icon.svg | 0 docs/tool_ux.md | 1 + mkdocs.yml | 33 ++++++++++-------- 20 files changed, 33 insertions(+), 27 deletions(-) rename docs/{ => assets}/SootUp-paper.pdf (100%) rename docs/{ => assets}/figures/CopyPropagator Example_1.png (100%) rename docs/{ => assets}/figures/CopyPropagator Example_2.png (100%) rename docs/{ => assets}/figures/DominanceFinder Example.png (100%) rename docs/{ => assets}/figures/EmptySwitchEliminator Example.png (100%) rename docs/{ => assets}/figures/LocalLiveness Example.png (100%) rename docs/{ => assets}/figures/LocalPacker Example.png (100%) rename docs/{ => assets}/figures/LocalSplitter Example_1.png (100%) rename docs/{ => assets}/figures/LocalSplitter Example_2.png (100%) rename docs/{ => assets}/figures/SSA Example_1.png (100%) rename docs/{ => assets}/figures/SSA Example_2.png (100%) rename docs/{ => assets}/figures/TrapTightener Example.png (100%) rename docs/{ => assets}/figures/UnreachableCodeEliminator Example.png (100%) rename docs/{ => img}/SootUpLogo.svg (100%) rename docs/{ => img}/icon.svg (100%) create mode 100644 docs/tool_ux.md diff --git a/README.md b/README.md index cda231d7048..d8bb2535dd1 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ You want to collaborate? Please read our [coding guidelines and the contributors ## Publications [the SootUp paper](https://doi.org/10.1007/978-3-031-57246-3_13) explains further details and the design decision behind SootUp. -[Preprint](/docs/SootUp-paper.pdf) is also available. +[Preprint](/docs/assets/SootUp-paper.pdf) is also available. If you use SootUp in your research work, feel free to cite it as follows: diff --git a/docs/advanced-topics.md b/docs/advanced-topics.md index 28e67ac89fc..273912b3b93 100644 --- a/docs/advanced-topics.md +++ b/docs/advanced-topics.md @@ -6,7 +6,7 @@ LocalLivenessAnalyser is used for querying for the list of live local variables Example: -![LocalLiveness Example](./figures/LocalLiveness%20Example.png) +![LocalLiveness Example](assets/figures/LocalLiveness%20Example.png) The live local variables before and after each Stmt will be calculated after generating an instance of LocalLivenessAnalyser as shown the example above. They can be queried by using the methods getLiveLocalsBeforeStmt and getLiveLocalsAfterStmt. @@ -14,6 +14,6 @@ The live local variables before and after each Stmt will be calcula DomianceFinder is used for querying for the immediate dominator and dominance frontiers for a given basic block. -Example: ![DominanceFinder Example](figures/DominanceFinder%20Example.png) +Example: ![DominanceFinder Example](assets/figures/DominanceFinder%20Example.png) After generating an instance of DominanceFinder for a BlockGraph, we will get the immediate dominator and dominance frontiers for each basic block. The both properties can be queried by using the methodsgetImmediateDominatorandgetDominanceFrontiers. diff --git a/docs/SootUp-paper.pdf b/docs/assets/SootUp-paper.pdf similarity index 100% rename from docs/SootUp-paper.pdf rename to docs/assets/SootUp-paper.pdf diff --git a/docs/figures/CopyPropagator Example_1.png b/docs/assets/figures/CopyPropagator Example_1.png similarity index 100% rename from docs/figures/CopyPropagator Example_1.png rename to docs/assets/figures/CopyPropagator Example_1.png diff --git a/docs/figures/CopyPropagator Example_2.png b/docs/assets/figures/CopyPropagator Example_2.png similarity index 100% rename from docs/figures/CopyPropagator Example_2.png rename to docs/assets/figures/CopyPropagator Example_2.png diff --git a/docs/figures/DominanceFinder Example.png b/docs/assets/figures/DominanceFinder Example.png similarity index 100% rename from docs/figures/DominanceFinder Example.png rename to docs/assets/figures/DominanceFinder Example.png diff --git a/docs/figures/EmptySwitchEliminator Example.png b/docs/assets/figures/EmptySwitchEliminator Example.png similarity index 100% rename from docs/figures/EmptySwitchEliminator Example.png rename to docs/assets/figures/EmptySwitchEliminator Example.png diff --git a/docs/figures/LocalLiveness Example.png b/docs/assets/figures/LocalLiveness Example.png similarity index 100% rename from docs/figures/LocalLiveness Example.png rename to docs/assets/figures/LocalLiveness Example.png diff --git a/docs/figures/LocalPacker Example.png b/docs/assets/figures/LocalPacker Example.png similarity index 100% rename from docs/figures/LocalPacker Example.png rename to docs/assets/figures/LocalPacker Example.png diff --git a/docs/figures/LocalSplitter Example_1.png b/docs/assets/figures/LocalSplitter Example_1.png similarity index 100% rename from docs/figures/LocalSplitter Example_1.png rename to docs/assets/figures/LocalSplitter Example_1.png diff --git a/docs/figures/LocalSplitter Example_2.png b/docs/assets/figures/LocalSplitter Example_2.png similarity index 100% rename from docs/figures/LocalSplitter Example_2.png rename to docs/assets/figures/LocalSplitter Example_2.png diff --git a/docs/figures/SSA Example_1.png b/docs/assets/figures/SSA Example_1.png similarity index 100% rename from docs/figures/SSA Example_1.png rename to docs/assets/figures/SSA Example_1.png diff --git a/docs/figures/SSA Example_2.png b/docs/assets/figures/SSA Example_2.png similarity index 100% rename from docs/figures/SSA Example_2.png rename to docs/assets/figures/SSA Example_2.png diff --git a/docs/figures/TrapTightener Example.png b/docs/assets/figures/TrapTightener Example.png similarity index 100% rename from docs/figures/TrapTightener Example.png rename to docs/assets/figures/TrapTightener Example.png diff --git a/docs/figures/UnreachableCodeEliminator Example.png b/docs/assets/figures/UnreachableCodeEliminator Example.png similarity index 100% rename from docs/figures/UnreachableCodeEliminator Example.png rename to docs/assets/figures/UnreachableCodeEliminator Example.png diff --git a/docs/bodyinterceptors.md b/docs/bodyinterceptors.md index 7963174a0fa..4f98e8e1fac 100644 --- a/docs/bodyinterceptors.md +++ b/docs/bodyinterceptors.md @@ -34,7 +34,7 @@ LocalSplitter is aBodyInterceptorthat attempts to identify and sepa Example 1: -![LocalSplitter Example_1](./figures/LocalSplitter%20Example_1.png) +![LocalSplitter Example_1](assets/figures/LocalSplitter%20Example_1.png) As shown in the example above, the local variablel1is defined twice. It can be split up into two new local variables: l1#1 and l1#2 because the both definitions are independent of each other. @@ -45,7 +45,7 @@ Look for foldable navigation and tabs for showing old vs new Example 2: -![LocalSplitter Example_2](./figures/LocalSplitter%20Example_2.png) +![LocalSplitter Example_2](assets/figures/LocalSplitter%20Example_2.png) In the second example, the local variablel2is defined thrice. But it cannot be split up into three new local variables as in the first example, because its definitions in the if-branches are not independent of each other. Therefore, it can only be split up into two local variables as shown in the figure. @@ -57,7 +57,7 @@ LocalPacker is aBodyInterceptorthat attempts to minimize the number Example: -![LocalPacker Example](./figures/LocalPacker%20Example.png) +![LocalPacker Example](assets/figures/LocalPacker%20Example.png) In the given example above, the local variablesl1,l3are summarized to be one local variablel1, because they have the same type without interference with each other. Likewise, the local variablesl2,l4andl5are summarized to be another local variablel2. Although the local variablel0doesn't interfere any other local variables, it cannot be summed up with other local variables because of its distinctive type. @@ -70,7 +70,7 @@ TrapTightener is aBodyInterceptorthat shrinks the protected area co Example: -![TrapTightener Example](./figures/TrapTightener%20Example.png) +![TrapTightener Example](assets/figures/TrapTightener%20Example.png) We assume in the example above that only theStmt:l2 := 2might throw an exception caught by theTrapwhich is labeled withlabel3. In the jimple body before running the TrapTightener, the protected area covered by the Trap contains threeStmts:l1 := 1; l2 := 2; l2 := 3. But an exception could only arise at theStmt:l2 := 2. After the implementation of TrapTightener, we will get a contractible protected area which contains only theStmtthat might throw an exception, namely theStmt:l2 := 2. @@ -82,7 +82,7 @@ EmptySwitchEliminator is aBodyInterceptorthat removes empty switch Example: -![EmptySwitchEliminator Example](./figures/EmptySwitchEliminator%20Example.png) +![EmptySwitchEliminator Example](assets/figures/EmptySwitchEliminator%20Example.png) As shown in the example above, the switch statement in the jimple body always takes the default action. After running EmptySwitchEliminator, the switch statement is replaced with aGotoStmtto the default case. @@ -94,7 +94,7 @@ UnreachableCodeEliminator is aBodyInterceptorthat removes all unrea Example: -![UnreachableCodeEliminator Example](./figures/UnreachableCodeEliminator%20Example.png) +![UnreachableCodeEliminator Example](assets/figures/UnreachableCodeEliminator%20Example.png) Obviously, the code segmentl2 = 2; l3 = 3;is unreachable. It will be removed after running the UreachableCodeEliminator. @@ -106,7 +106,7 @@ CopyPropagator is aBodyInterceptorthat supports the global copy pro Example for global copy propagation: -![UnreachableCodeEliminator Example](./figures/CopyPropagator%20Example_1.png) +![UnreachableCodeEliminator Example](assets/figures/CopyPropagator%20Example_1.png) Consider a code segment in the following form: @@ -125,7 +125,7 @@ In the example for global copy propagation, the first usedl1is repl Example for constant propagation: -![CopyPropagator Example_1](figures/CopyPropagator%20Example_2.png) +![CopyPropagator Example_1](assets/figures/CopyPropagator%20Example_2.png) Constant propagation is similar to copy propagation. Consider a code segment in the following form: @@ -169,8 +169,8 @@ StaticSingleAssignmentFormer is aBodyInterceptorthat transforms jim Example: -![SSA Example_1](./figures/SSA%20Example_1.png) +![SSA Example_1](assets/figures/SSA%20Example_1.png) -![SSA Example_2](./figures/SSA%20Example_2.png) +![SSA Example_2](assets/figures/SSA%20Example_2.png) In the given example, the StaticSingleAssignmentFormer assigns eachIdentityStmtandAssignStmtto a new local variable . And each use uses the local variable which is most recently defined. Sometimes, it is impossible to determine the most recently defined local variable for a use in a join block. In this case, the StaticSingleAssignmentFormer will insert aPhiStmtin the front of the join block to merge all most recently defined local variables and assign them a new local variable. \ No newline at end of file diff --git a/docs/SootUpLogo.svg b/docs/img/SootUpLogo.svg similarity index 100% rename from docs/SootUpLogo.svg rename to docs/img/SootUpLogo.svg diff --git a/docs/icon.svg b/docs/img/icon.svg similarity index 100% rename from docs/icon.svg rename to docs/img/icon.svg diff --git a/docs/tool_ux.md b/docs/tool_ux.md new file mode 100644 index 00000000000..4287ca86179 --- /dev/null +++ b/docs/tool_ux.md @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index baf4d12f4bf..d5cf2231d24 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,38 +5,43 @@ edit_uri: edit/develop/docs/ nav: - Home: index.md - - Announcements: announce.md - - Design Decisions: whatsnew.md - - Basics: - - Installation: installation.md -# - Configure your Input: analysisinputlocations.md - - Getting started: getting-started.md - - Jimple: jimple.md + - Getting Started: + - Installation: installation.md + - First Steps: getting-started.md + - Configure your Input: analysisinputlocations.md - - Advanced Topics: + - Basics: + - Jimple IR: jimple.md - BodyInterceptors: bodyinterceptors.md - - Call Graph Construction: call-graph-construction.md - - SootUp Utilities: advanced-topics.md + - Callgraph Construction: call-graph-construction.md + - Analyses: advanced-topics.md - How to..: - - Write an Analysis: write_analyses.md + - Write your own analysis: write_analyses.md + - Incorporate QilinPTA: qilin.md # - Modify a StmtGraph: mutable_stmtgraph.md # - Modify a View: mutable_view.md # - Implement a BodyInterceptor: body_interceptor.md # - Implement an AnalysisTool: write_analysis_tool.md + - From Prototype to Tool: tool_ux.md + + - Misc: + - Announcements: announce.md + - Design Decisions: whatsnew.md - More information: - - Javadoc: /SootUp/apidocs + - latest Javadoc: /SootUp/apidocs - Troubleshooting & FAQ: faq.md # - Based on SootUp: tools.md + theme: palette: primary: white name: material - logo: ./SootUpLogo.svg - favicon: ./icon.svg + logo: ./img/SootUpLogo.svg + favicon: ./img/icon.svg features: - navigation.sections From 6c7daef0c955fdecc780658cb1ab2e2d1a1748ac Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Fri, 14 Jun 2024 18:04:21 +0200 Subject: [PATCH 02/23] improve documentation --- .github/workflows/gh-pages.yml | 6 +- docs/analysisinputlocations.md | 25 +++++ docs/getting-started.md | 6 +- docs/installation.md | 173 ++++++++++++++------------------- docs/migration.md | 3 + docs/qilin.md | 11 +++ docs/tool_ux.md | 34 ++++++- mkdocs.yml | 11 ++- 8 files changed, 152 insertions(+), 117 deletions(-) create mode 100644 docs/analysisinputlocations.md create mode 100644 docs/migration.md create mode 100644 docs/qilin.md diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 01b15dc8dea..7958b55657e 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -51,11 +51,7 @@ jobs: python-version: 3.x # install dependencies - - run: pip install mike - - run: pip install mkdocs-material - - run: pip install mkdocs-tooltips - - run: pip install git+https://github.com/RedisLabs/mkdocs-include.git - - run: pip install git+https://github.com/swissiety/LspLexer4Pygments.git + - run: pip install mike mkdocs-material mkdocs-tooltips git+https://github.com/RedisLabs/mkdocs-include.git git+https://github.com/swissiety/LspLexer4Pygments.git # grab latest release url of the JimpleLSP jar and download it - run: curl -s -L -o ./jimplelsp.jar $(curl -s https://api.github.com/repos/swissiety/jimpleLsp/releases/latest | grep 'browser_download_url".*jar"' | cut -d ':' -f 2,3 | tr -d \") diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md new file mode 100644 index 00000000000..520dc5d3890 --- /dev/null +++ b/docs/analysisinputlocations.md @@ -0,0 +1,25 @@ +# AnalysisInputLocations +An AnalysisInputLocation tells SootUp what code input it should analyze. + +### Java Runtime +- Java <9: DefaultRTJaAnalysisInputLocation current rt.jar (or point to any rt.jar as its just a usual .jar file) +- Java >8: JRTFilesystemAnalysisInputLocation + +If you have errors like Java.lang.String, Java.lang.Object, ... you are most likely missing this AnalysisInput. + +### Java Bytecode .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 +- OTFCompileAnalysisInputLocation - you can point directly to .java files or pass a String with Java sourcecode +- JavaSourcePathInputLocation - points to a directory that is the root source directory (containing the package directory structure) + +### Jimple .jimple +- JimpleAnalysisInputLocation - needs a Path to a .jimple file or a directory. + +### Android Bytecode .dex +- ApkAnalysisInputLocation - currenlty uses dex2jar internally - SootUp solution is WIP! + + +### Java cli arguments to configure SootUp +We created a [Utility](tool_ux.md) that parses a String of java command line arguments and configures SootUp respectively. \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md index 2f9df6b80a4..b8b764a2977 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,8 +4,6 @@ This page walks you through the core data structures, as well as shows how to ge ## The core datastructures Before you get started with the SootUp library, it helps to learn about the following core data structures: -- `Language`: represents the programming language of the analyzed code. - - `AnalysisInputLocation`: points to the target code to be analyzed. !!! info "Soot Equivalent" @@ -18,15 +16,13 @@ Before you get started with the SootUp library, it helps to learn about the foll It corresponds to the `Scene` class, but it is not a singleton. So it is possible to instantiate multiple views simultaneously. -- `Scope`: defines the scope of the `View`. By default, the `View` is created with all code found on the `AnalysisInputLocation` specified for the `Project` instance. - - `SootClass`: represents a class loaded into the `View`. - `SootMethod`: represents a method of a class. - `SootField`: represents a field of a class. -- `Body`: represents a method body in Jimpe. +- `Body`: represents a method body in Jimple. - `StmtGraph`: represents the control flow graph of a method body in Jimple statements. diff --git a/docs/installation.md b/docs/installation.md index 35f840dec4a..824f968e7e1 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,105 +1,76 @@ # Installation -## Using the latest version on the develop branch -visit [SootUp on Jitpack.io](https://jitpack.io/#soot-oss/SootUp/develop-SNAPSHOT) for configuration options of your build tool. - -## Using the release -SootUp is available in maven central, you can include it in your project as follows. - -Below we only show how you can add the SootUp modules to your project. It is not necessary to add all the modules as dependency. -Depending on your needs you can import only the modules you need. -Take a look at the [Modules](whatsnew.md#modular-architecture) to learn more about which modules you might need. - -### Maven - - Add the following dependency in the ```pom.xml``` file of your project to include all SootUp modules into your project. - -``` - - - jitpack.io - https://jitpack.io - - - - - - org.soot-oss - sootup.core - {{ git_latest_release }} - - - org.soot-oss - sootup.java.core - {{ git_latest_release }} - - - org.soot-oss - sootup.java.sourcecode - {{ git_latest_release }} - - - org.soot-oss - sootup.java.bytecode - {{ git_latest_release }} - - - org.soot-oss - sootup.jimple.parser - {{ git_latest_release }} - - - org.soot-oss - sootup.callgraph - {{ git_latest_release }} - - - org.soot-oss - sootup.analysis - {{ git_latest_release }} - - -``` -### Gradle - -Add the following dependency in the ```build.gradle``` file of your project to include all SootUp modules into your project. - -``` -repositories { - mavenCentral() - google() - maven { - url "https://jitpack.io" +## Use the latest [develop branch](https://github.com/soot-oss/SootUp/tree/develop) +For configuration options of your build tool please visit [SootUp on Jitpack.io](https://jitpack.io/#soot-oss/SootUp/develop-SNAPSHOT) + + +## Use Releases on Maven Central +The code below shows you how to import all submodules of the SootUp repository. +You can import fewer modules if your use case allows it. + +Add the following dependencies to your ```pom.xml``` / ```build.gradle```. + +=== "Maven" + + ```mvn + + + org.soot-oss + sootup.core + {{ git_latest_release }} + + + org.soot-oss + sootup.java.core + {{ git_latest_release }} + + + org.soot-oss + sootup.java.sourcecode + {{ git_latest_release }} + + + org.soot-oss + sootup.java.bytecode + {{ git_latest_release }} + + + org.soot-oss + sootup.jimple.parser + {{ git_latest_release }} + + + org.soot-oss + sootup.callgraph + {{ git_latest_release }} + + + org.soot-oss + sootup.analysis + {{ git_latest_release }} + + + ``` + +=== "Gradle" + + ```gradle + repositories { + mavenCentral() + google() } -} - -compile "org.soot-oss:sootup.core:{{ git_latest_release }}" -compile "org.soot-oss:sootup.java.core:{{ git_latest_release }}" -compile "org.soot-oss:sootup.java.sourcecode:{{ git_latest_release }}" -compile "org.soot-oss:sootup.java.bytecode:{{ git_latest_release }}" -compile "org.soot-oss:sootup.jimple.parser:{{ git_latest_release }}" -compile "org.soot-oss:sootup.callgraph:{{ git_latest_release }}" -compile "org.soot-oss:sootup.analysis:{{ git_latest_release }}" -``` - -## Building from Source -Build from source if you'd like to get the most recent changes. -You can download the project as a zip file, or clone it using your favorite git client app or the command line: - -``` + + compile "org.soot-oss:sootup.core:{{ git_latest_release }}" + compile "org.soot-oss:sootup.java.core:{{ git_latest_release }}" + compile "org.soot-oss:sootup.java.sourcecode:{{ git_latest_release }}" + compile "org.soot-oss:sootup.java.bytecode:{{ git_latest_release }}" + compile "org.soot-oss:sootup.jimple.parser:{{ git_latest_release }}" + compile "org.soot-oss:sootup.callgraph:{{ git_latest_release }}" + compile "org.soot-oss:sootup.analysis:{{ git_latest_release }}" + ``` + +## Build from Source +If you'd like to get the most recent changes, you can build SootUp from source yourself and install it into your local maven repository. +```sh git clone https://github.com/secure-software-engineering/SootUp.git -``` - -SootUp is a maven project. You can import it into your favorite IDE as a maven project. Run maven clean and install tasks using your IDE's maven plugin to set up the project. - -Alternatively, you can execute the following command in the project directory: - -``` mvn install -``` - -Or if you want to skip tests while building: - -``` -mvn -Dskiptests install -``` - +``` \ No newline at end of file diff --git a/docs/migration.md b/docs/migration.md new file mode 100644 index 00000000000..c2dbf366e20 --- /dev/null +++ b/docs/migration.md @@ -0,0 +1,3 @@ +# From [Soot](https://github.com/soot-oss/Soot) + +// TODO \ No newline at end of file diff --git a/docs/qilin.md b/docs/qilin.md new file mode 100644 index 00000000000..efa54851cdc --- /dev/null +++ b/docs/qilin.md @@ -0,0 +1,11 @@ +# Incorporate Qilin Pointer Analysis +see [QilinPTA](https://github.com/QilinPTA/Qilin). + +### Dependencies +```maven + // TODO: add submodule +``` + +### How to + +// TODO \ No newline at end of file diff --git a/docs/tool_ux.md b/docs/tool_ux.md index 4287ca86179..76edebca727 100644 --- a/docs/tool_ux.md +++ b/docs/tool_ux.md @@ -1 +1,33 @@ -# \ No newline at end of file +# Prototype to user friendly tool + +`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. + +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. + +Dependencies: +```maven + + commons-cli + commons-cli + 1.8.0 + + +``` + +```gradle + implementation("commons-cli:commons-cli:1.8.0") +``` + +```java + +class SootUpConfiguration{ + // TODO incorporate +} + +``` + +We are happy if you steal the following code to create a tool where the setup is just simple. diff --git a/mkdocs.yml b/mkdocs.yml index d5cf2231d24..f73450910c7 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,17 +9,17 @@ nav: - Getting Started: - Installation: installation.md - First Steps: getting-started.md - - Configure your Input: analysisinputlocations.md + - Configure your Inputs: analysisinputlocations.md - Basics: - Jimple IR: jimple.md - BodyInterceptors: bodyinterceptors.md - Callgraph Construction: call-graph-construction.md - - Analyses: advanced-topics.md + - Shipped Analyses: advanced-topics.md - How to..: - - Write your own analysis: write_analyses.md - - Incorporate QilinPTA: qilin.md + - Write a Dataflow analysis: write_analyses.md + - Incorporate Pointer Analysis: qilin.md # - Modify a StmtGraph: mutable_stmtgraph.md # - Modify a View: mutable_view.md # - Implement a BodyInterceptor: body_interceptor.md @@ -29,9 +29,10 @@ nav: - Misc: - Announcements: announce.md - Design Decisions: whatsnew.md + - Migrating from Soot: migrating.md - More information: - - latest Javadoc: /SootUp/apidocs + - Latest Javadoc: /SootUp/apidocs - Troubleshooting & FAQ: faq.md # - Based on SootUp: tools.md From 4533d40efd3f82ae3b61a10fb365c5068b9d5812 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Sat, 15 Jun 2024 11:41:24 +0200 Subject: [PATCH 03/23] adapt regex of allowed version names --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 7958b55657e..60c5d17cc68 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -65,7 +65,7 @@ jobs: git config --local user.name "github-actions[bot]" # sanitive head_ref name - - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^[:alnum:]-]/_/g" )" >> $GITHUB_ENV + - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^[:alnum:]_-.#@]/_/g" )" >> $GITHUB_ENV # on push to develop branch - keep a doc around for develop to show the current state - name: deploy doc in subdirectory From fbc52ae6b7e9f9f389a442a32b7d55bac36bd520 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 13:31:22 +0200 Subject: [PATCH 04/23] restructuring & styling docs --- docs/css/customizetheme.css | 114 +++++++++++++++++ docs/examples.md | 84 ++++++++++++ docs/getting-started.md | 190 ---------------------------- docs/index.md | 4 +- docs/installation.md | 9 +- docs/migrating.md | 116 +++++++++++++++++ docs/migration.md | 3 - docs/overrides/partials/footer.html | 108 ++++++++++++++++ docs/overrides/partials/header.html | 106 ++++++++++++++++ docs/qilin.md | 17 ++- docs/tool_ux.md | 29 +++-- docs/write_analyses.md | 29 ++++- mkdocs.yml | 12 +- 13 files changed, 603 insertions(+), 218 deletions(-) create mode 100644 docs/css/customizetheme.css create mode 100644 docs/examples.md create mode 100644 docs/migrating.md delete mode 100644 docs/migration.md create mode 100644 docs/overrides/partials/footer.html create mode 100644 docs/overrides/partials/header.html diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css new file mode 100644 index 00000000000..fc2c8b184fa --- /dev/null +++ b/docs/css/customizetheme.css @@ -0,0 +1,114 @@ +:root { + --md-primary-fg-color: hsla(var(--md-hue), 0%, 100%, 1); + --md-primary-fg-color--light: hsla(var(--md-hue), 0%, 100%, 0.7); + --md-primary-fg-color--dark: hsla(var(--md-hue), 0%, 0%, 0.07); + --md-primary-bg-color: hsla(var(--md-hue), 0%, 0%, 0.87); + --md-primary-bg-color--light: hsla(var(--md-hue), 0%, 0%, 0.54); + + --md-accent-fg-color: rgba(255,140,0, 1); +} +[data-md-color-accent=indigo]{ + --md-accent-fg-color: rgba(255,140,0, 1); +} + + +.md-typeset a { + color: rgba(255,140,0, 0.8); +} + +.md-nav__link[for]:focus, .md-nav__link[for]:hover, .md-nav__link[href]:focus, .md-nav__link[href]:hover { + color: rgba(255,140,0, 0.8); +} + +.md-typeset h1>a, .md-typeset h2>a, .md-typeset h3>a { + text-decoration: underline; +} + +.md-typeset a:hover { + color: rgba(255,140,0, 0.4); +} + +.md-typeset h1, .md-typeset h2, .md-typeset h3{ + color:rgba(255,140,0, 1); + font-weight: normal; +} + +.md-typeset .admonition, .md-typeset .admonition.info, .md-typeset .admonition.example, .md-typeset .admonition{ + border-color: rgba(255,140,0, 0.2); + margin-bottom: 3em; +} + +.md-typeset .admonition>.admonition-title:before, .md-typeset .admonition>summary:before{ + background-color: rgba(255,140,0, 1); +} + +.md-typeset .admonition>.admonition-title, .md-typeset .admonition>.admonition-title{ + background: rgba(255,140,0, 0.2); +} +.md-typeset .admonition, .md-typeset details { + border-color: rgba(255,140,0, 1); +} + +.md-nav label.md-nav__title{ + color:rgba(255,140,0, 1); +} +.md-nav__item--section>.md-nav__link[for] { + color:rgba(255,140,0, 1); +} + + +.md-nav__item a{ + color: #222; +} + +.md-nav__link.md-nav__link--active{ + color: rgba(255,140,0, 1); +} + + +.md-sidebar.md-sidebar--primary .md-sidebar__scrollwrap{ + border-right: 1px solid #DDD; + margin-right: 2em; + padding-right: 2em; +} +.md-sidebar.md-sidebar--secondary .md-sidebar__scrollwrap{ + border-left: 1px solid #DDD; + margin-left: 2em; + padding-left: 2em; +} + +.md-search__form{ + background: #EEE; +} + +.md-typeset code { + padding:0.2em; + margin:0.2em; +} + +.tabbed-set.tabbed-alternate{ + background: #EEE; +} +.md-footer{ + margin-top: 2em; + padding:1em; + background: #EEE; +} + +.md-footer-meta.md-typeset, .md-footer-meta .md-copyright{ + background: none; + color:#000; +} + +html .md-footer-meta.md-typeset a{ + color:#666; +} + +.md-typeset table:not([class]), .md-typeset table:not([class]) td{ + border-collapse: collapse; + border:none; +} + +#developedBy{ + font-size: 11pt; +} \ No newline at end of file diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 00000000000..eb5a7149681 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,84 @@ +# SootUp Example projects +Example code to help getting start with SootUp +Here we will provide some examples that uses SootUp to provide insights about a Java program. +The Examples can be cloned or downloaded from our [Example Repository](https://github.com/soot-oss/SootUp-Examples.git). + +- BasicSetupExample +- BodyInterceptorExample +- CallGraphExample +- ClassHierarchyExample +- MutatingSootClassExample + +We have included all the five projects in 5 different branches under SootUp-Examples with detailed explanation about the project. + +### BasicSetupExample +1. package sootup.examples; - defines the package name for the Java class. +2. import statement - defines various classes and interfaces from different packages that the program uses. +3. public class BasicSetup - declares a public class named 'BasicSetup' which is the main class for this program. +4. Then we have created a main method which is the entry point of the progrram +5. Path pathToBinary object pointing to a directory that contains the binary files ie class files to be analyzed and Paths.get is a static method that converts string path to a 'Path' object. +6. AnalysisInputLocation object specifying where SootUp should look for classes to analyze. +7. View object is created for the project allowing the retrieal of classes from the specified input location. JavaView is specific implementation of View tailed for Java projects. +8. The ClassType object is created for the class name 'HelloWorld'. This object represents the type of class to be analyzed. +9. A MethodSignature object is created for the main method of the HelloWorld class. This signature specifies the method's return type (void) and its parameter types (a single parameter of type String[]). +10. The if statment checks for the presences of the class 'HelloWorld'. If not it prints "Class not ffound!" and exits the program. +11. Then it retrieves the SootClass object representing the HelloWorld class, assuming it is present. +12. view.getMethod(methodSignature); - Attempts to retrieve the specified method from the project. +13. The if statment after this, checks if the main method is present in the HelloWorld class. If not, it prints "Method not found!" and exits. +14. Then the next statment retrieves the SootMethod object for the main method and prints its body, which is in Jimple, a simplified version of Java bytecode used by Soot for analysis and transformation. +15. Then the next if condition checks if the method containts a specific statement called 'Hello World!'. + +### BodyInterceptor +1. package sootup.examples; - defines the package name for the Java class. +2. import statement - defines various classes and interfaces from different packages that the program uses. +3. public class BodyInterceptor - declares a public class named "BodyInterceptor". +4. Then we have created a main method in which is the entry point for the code. +5. Then we have created an AnalysisInputLocation pointing to a directory with class files to be loaded. It specifies that the DeadAssignmentEliminator interceptor should be applied to these classes. +6. Then created a View that initializes a JavaView with the specified inputLocation, allowing interaction with the classes for analysis. +7. Then have created a ClassType and MethodSignature which is used for analysis. The signature contains method name, return type and parameters. +8. Then we check for the existence of the class and method in the given view. +9. If they exist, a SootClass and SootMethod objects are used to retrieve the same. +10. Then prints the body of the SootMethod object. +11. Then we check if the interceptor worked. ie here we check if the DeadAssignmentEliminator interceptor has successfully removed a specific assignment (l1 = 3. from the method's body. It does this by looking through all statements (JAssignStmt) in the method body and checking if the assignment is not present. +12. Then it prints the result of the interceptor check. + + +### CallGraphExample +1. package sootup.examples; - defines the package name for the Java class. +2. import statement - defines various classes and interfaces from different packages that the program uses. +3. public class CallgraphExample - declares a public class named "CallGraphExample". +4. Then we have created a main method in which is the entry point for the code. +5. List inputLocations creates a list of AnalysisInputLocation objects. These specify where Soot should look for Java class files for analysis. +6. Then we have provided towo inputLocations.add() - one for the project's class file directory and another for Java's runtime library (rt.jar). +7. Then we have created a JavaView which is used for analysing the Java program. +8. Then we have created two ClassType for two classes ie 'A' and 'B'. They are used to create a MethodSignature for a method that will be analysed. +9. ViewTypeHierarchy - then we have set up a type hierarchy from the provided view and prints the subclasses of class 'A'. +10. Initializes a CallGraphAlgorithm using the ClassHierarchyAnalysisAlgorithm, which is a method for constructing call graphs. +11. Then we creates a call graph by initialising the Class Hierarchy Analysis (cha) with the entry method signature. +12. Prints information about calls from the entry method in the call graph. + +### ClassHierarchyExample +1. package sootup.examples; - defines the package name for the Java class. +2. import statement - defines various classes and interfaces from different packages that the program uses. +3. public class ClassHierarchy - declares a public class named "ClassHierarchy". +4. Then we have created a main method in which is the entry point for the code. +5. Then creates a list of AnalysisInputLocation objects. These specify where Soot should look for Java class files for analysis. Two locations are added: one for the project's binary directory and another for the default Java runtime library (rt.jar). +6. Initializes a JavaView object with the previously created input locations. +7. Initializes a ViewTypeHierarchy object using the view. This object will be used to analyze the class hierarchy. +8. Then we have created two ClassTypes. These lines get JavaClassType objects for classes "A" and "C". These types are used for further hierarchy analysis. +9. Checks the direct subclasses of class "C". It verifies if all direct subclasses are "D" using two different methods: comparing class names and fully qualified names. +10. Then prints a message based on whether all direct subtypes of "C" are correctly identified as "D". +11. Retrieves and checks the superclasses of class "C". It then verifies if these superclasses include class "A" and java.lang.Object, printing a message based on the result. + +### MutatingSootClassExample +1. package sootup.examples; - defines the package name for the Java class. +2. import statement - defines various classes and interfaces from different packages that the program uses. +3. public class MutatingSootClass - declares a public class named "MutatingSootClass". +4. Then we have created a main method in which is the entry point for the code. +5. First we have created an 'AnalysisInputLocation' which points to a directory which contains the class files to be analysed. +6. Then we have created a JavaView which allos us to retrievet the classes. +7. And also created a ClassType to get the class 'HelloWorld' and a method within that class ie main for analysis using MethodSignature. +8. THen we are checking and retrieving the class and method. +9. Then we retrives the existing body of the method and prints it. Then we create a new local variable to add it copy to the method body. +10. Then we are overriding the method body and class. ie this lines creates new sources that overrides teh original method body and class. It replaces the old method in the class with the new method having the modified body. +11. Prints the modified method body and checks if the new local variable (newLocal) exists in the modified method. Depending on the result, it prints a corresponding message. \ No newline at end of file diff --git a/docs/getting-started.md b/docs/getting-started.md index b8b764a2977..acb45e7ece4 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -182,193 +182,3 @@ Each `SootMethod` contains a Control-Flow Graph (CFG) which is represented via t !!! info "Access or Download all of the code used above" [BasicSetup.java](https://github.com/secure-software-engineering/soot-reloaded/blob/develop/sootup.examples/src/test/java/sootup/examples/basicSetup/BasicSetup.java) - -## SootUp vs Soot - -Below we show a comparison of the code so far with the same functionality in sootup. - -=== "SootUp" - - ``` java - AnalysisInputLocation inputLocation = - new JavaClassPathAnalysisInputLocation("path2Binary"); - - JavaView view = new JavaView(inputLocation); - - JavaClassType classType = - view.getIdentifierFactory().getClassType("HelloWorld"); - - MethodSignature methodSignature = - view - .getIdentifierFactory() - .getMethodSignature( - "main", classType, "void", - Collections.singletonList("java.lang.String[]")); - - JavaSootClass sootClass = view.getClass(classType).get(); - - JavaSootMethod sootMethod = sootClass.getMethod(methodSignature.getSubSignature()).get(); - - sootMethod.getBody().getStmts(); - ``` - -=== "Soot" - - ``` java - 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"; - - Options.v().set_soot_classpath(sootCp); - Options.v().set_whole_program(true); - Options.v().setPhaseOption("cg.cha", "on"); - Options.v().setPhaseOption("cg", "all-reachable:true"); - Options.v().set_no_bodies_for_excluded(true); - Options.v().set_allow_phantom_refs(true); - Options.v().setPhaseOption("jb", "use-original-names:true"); - Options.v().set_prepend_classpath(false); - - Scene.v().addBasicClass("java.lang.StringBuilder"); - SootClass c = - Scene.v().forceResolve(targetTestClassName, SootClass.BODIES); - if (c != null) { - c.setApplicationClass(); - } - Scene.v().loadNecessaryClasses(); - - SootMethod method; - for (SootClass c : Scene.v().getApplicationClasses()) { - if(c.getName().equals("example.HelloWorld")){ - for (SootMethod m : c.getMethods()) { - if (!m.hasActiveBody()) { - continue; - } - if (m.getName().equals("entryPoint")) { - method = m; - break; - } - } - } - } - - method.getActiveBody().getUnits(); - ``` - - - - - - - - - - -# SootUp-Examples -Example code to help getting start with SootUp - - -1) Here we will provide some examples that uses SootUp to provide insights about a Java program. The repository that contains the examples can be found in [https://github.com/soot-oss/SootUp-Examples.git]. -2) There are mainly 5 projects to be considered under SootUp. - a) *BasicSetupExample* - b) *BodyInterceptorExample* - c) *CallGraphExample* - d) *ClassHierarchyExample* - e) *MutatingSootClassExample*
- -3) We have included all the five projects in 5 different branches under SootUp-Examples with detailed explanation about the project. - - a) BasicSetupExample - 1) package sootup.examples; - defines the package name for the Java class. - 2) import statement - defines various classes and interfaces from different packages that the program uses. - 3) public class BasicSetup - declares a public class named 'BasicSetup' which is the main class for this program. - 4) Then we have created a main method which is the entry point of the progrram - 5) Path pathToBinary object pointing to a directory that contains the binary files ie class files to be analyzed and Paths.get is a static method that converts string path to a 'Path' object. - 6) AnalysisInputLocation object specifying where SootUp should look for classes to analyze. - 7) View object is created for the project allowing the retrieal of classes from the specified input location. JavaView is specific implementation of View tailed for Java projects. - 8) The ClassType object is created for the class name 'HelloWorld'. This object represents the type of class to be analyzed. - 9) A MethodSignature object is created for the main method of the HelloWorld class. This signature specifies the method's return type (void) and its parameter types (a single parameter of type String[]). - 10) The if statment checks for the presences of the class 'HelloWorld'. If not it prints "Class not ffound!" and exits the program. - 11) Then it retrieves the SootClass object representing the HelloWorld class, assuming it is present. - 12) view.getMethod(methodSignature); - Attempts to retrieve the specified method from the project. - 13) The if statment after this, checks if the main method is present in the HelloWorld class. If not, it prints "Method not found!" and exits. - 14) Then the next statment retrieves the SootMethod object for the main method and prints its body, which is in Jimple, a simplified version of Java bytecode used by Soot for analysis and transformation. - 15) Then the next if condition checks if the method containts a specific statement called 'Hello World!'. - - b) BodyInterceptor - 1) package sootup.examples; - defines the package name for the Java class. - 2) import statement - defines various classes and interfaces from different packages that the program uses. - 3) public class BodyInterceptor - declares a public class named "BodyInterceptor". - 4) Then we have created a main method in which is the entry point for the code. - 5) Then we have created an AnalysisInputLocation pointing to a directory with class files to be loaded. It specifies that the DeadAssignmentEliminator interceptor should be applied to these classes. - 6) Then created a View that initializes a JavaView with the specified inputLocation, allowing interaction with the classes for analysis. - 7) Then have created a ClassType and MethodSignature which is used for analysis. The signature contains method name, return type and parameters. - 8) Then we check for the existence of the class and method in the given view. - 9) If they exist, a SootClass and SootMethod objects are used to retrieve the same. - 10) Then prints the body of the SootMethod object. - 11) Then we check if the interceptor worked. ie here we check if the DeadAssignmentEliminator interceptor has successfully removed a specific assignment (l1 = 3) from the method's body. It does this by looking through all statements (JAssignStmt) in the method body and checking if the assignment is not present. - 12) Then it prints the result of the interceptor check. - - - c) CallGraphExample - 1) package sootup.examples; - defines the package name for the Java class. - 2) import statement - defines various classes and interfaces from different packages that the program uses. - 3) public class CallgraphExample - declares a public class named "CallGraphExample". - 4) Then we have created a main method in which is the entry point for the code. - 5) List inputLocations creates a list of AnalysisInputLocation objects. These specify where Soot should look for Java class files for analysis. - 6) Then we have provided towo inputLocations.add() - one for the project's class file directory and another for Java's runtime library (rt.jar). - 7) Then we have created a JavaView which is used for analysing the Java program. - 8) Then we have created two ClassType for two classes ie 'A' and 'B'. They are used to create a MethodSignature for a method that will be analysed. - 9) ViewTypeHierarchy - then we have set up a type hierarchy from the provided view and prints the subclasses of class 'A'. - 10) Initializes a CallGraphAlgorithm using the ClassHierarchyAnalysisAlgorithm, which is a method for constructing call graphs. - 11) Then we creates a call graph by initialising the Class Hierarchy Analysis (cha) with the entry method signature. - 12) Prints information about calls from the entry method in the call graph. - - d) ClassHierarchyExample - 1) package sootup.examples; - defines the package name for the Java class. - 2) import statement - defines various classes and interfaces from different packages that the program uses. - 3) public class ClassHierarchy - declares a public class named "ClassHierarchy". - 4) Then we have created a main method in which is the entry point for the code. - 5) Then creates a list of AnalysisInputLocation objects. These specify where Soot should look for Java class files for analysis. Two locations are added: one for the project's binary directory and another for the default Java runtime library (rt.jar). - 6) Initializes a JavaView object with the previously created input locations. - 7) Initializes a ViewTypeHierarchy object using the view. This object will be used to analyze the class hierarchy. - 8) Then we have created two ClassTypes. These lines get JavaClassType objects for classes "A" and "C". These types are used for further hierarchy analysis. - 9) Checks the direct subclasses of class "C". It verifies if all direct subclasses are "D" using two different methods: comparing class names and fully qualified names. - 10) Then prints a message based on whether all direct subtypes of "C" are correctly identified as "D". - 11) Retrieves and checks the superclasses of class "C". It then verifies if these superclasses include class "A" and java.lang.Object, printing a message based on the result. - - e) MutatingSootClassExample - - 1) package sootup.examples; - defines the package name for the Java class. - 2) import statement - defines various classes and interfaces from different packages that the program uses. - 3) public class MutatingSootClass - declares a public class named "MutatingSootClass". - 4) Then we have created a main method in which is the entry point for the code. - 5) First we have created an 'AnalysisInputLocation' which points to a directory which contains the class files to be analysed. - 6) Then we have created a JavaView which allos us to retrievet the classes. - 7) And also created a ClassType to get the class 'HelloWorld' and a method within that class ie main for analysis using MethodSignature. - 8) THen we are checking and retrieving the class and method. - 9) Then we retrives the existing body of the method and prints it. Then we create a new local variable to add it copy to the method body. - 10) Then we are overriding the method body and class. ie this lines creates new sources that overrides teh original method body and class. It replaces the old method in the class with the new method having the modified body. - 11) Prints the modified method body and checks if the new local variable (newLocal) exists in the modified method. Depending on the result, it prints a corresponding message. diff --git a/docs/index.md b/docs/index.md index cd61f29e954..69638181c58 100644 --- a/docs/index.md +++ b/docs/index.md @@ -32,11 +32,13 @@ The goal is a lighter library that can easily be understood and maintained to be The development of SootUp is financed by generous support from the German Research Foundation (DFG) and the Heinz Nixdorf Institute (HNI). - +
+
[Become a sponsor!](https://github.com/sponsors/soot-oss) + diff --git a/docs/installation.md b/docs/installation.md index 824f968e7e1..239f709f565 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,4 +1,5 @@ # Installation + ## Use the latest [develop branch](https://github.com/soot-oss/SootUp/tree/develop) For configuration options of your build tool please visit [SootUp on Jitpack.io](https://jitpack.io/#soot-oss/SootUp/develop-SNAPSHOT) @@ -48,12 +49,17 @@ Add the following dependencies to your ```pom.xml``` / ```build.gradle```. sootup.analysis {{ git_latest_release }} + + org.soot-oss + sootup.qilin + {{ git_latest_release }} + ``` === "Gradle" - ```gradle + ```groovy repositories { mavenCentral() google() @@ -66,6 +72,7 @@ Add the following dependencies to your ```pom.xml``` / ```build.gradle```. compile "org.soot-oss:sootup.jimple.parser:{{ git_latest_release }}" compile "org.soot-oss:sootup.callgraph:{{ git_latest_release }}" compile "org.soot-oss:sootup.analysis:{{ git_latest_release }}" + compile "org.soot-oss:sootup.qilin:{{ git_latest_release }}" ``` ## Build from Source diff --git a/docs/migrating.md b/docs/migrating.md new file mode 100644 index 00000000000..c7302e738a0 --- /dev/null +++ b/docs/migrating.md @@ -0,0 +1,116 @@ +# Migration Help + +### Version 1.3.0 +- The Typehierarchy API is now returning `Stream` instead of `Collection`. The simplest fix to have the same behaviour as before would be to collect the Stream on your own ( e.g. via `.collect(Collectors.toList())` ). +- Default Bodyinterceptors are added to improve Jimple. To mitigate that adapt the List of BodyInterceptors to your needs. +- + +### Version 1.2.0 +- The (Java)Project structure was removed. You can configure the (Java)View directly. +- Bodyinterceptors are now passed as arguments into AnalysisInputLocations. + +### From [Soot](https://github.com/soot-oss/Soot) +- The Scene singleton is dead. Long live the Scene. We have a central View object(!) now. +- Library first! No command line tool as primary goal. So you can configure parts of SootUp (near) where it is actually used. +- t.b.c. + +Below we show a comparison of the code so far with the same functionality in sootup. + +=== "SootUp" + + ``` java + AnalysisInputLocation inputLocation = + new JavaClassPathAnalysisInputLocation("path2Binary"); + + JavaView view = new JavaView(inputLocation); + + JavaClassType classType = + view.getIdentifierFactory().getClassType("HelloWorld"); + + MethodSignature methodSignature = + view + .getIdentifierFactory() + .getMethodSignature( + "main", classType, "void", + Collections.singletonList("java.lang.String[]")); + + JavaSootClass sootClass = view.getClass(classType).get(); + + JavaSootMethod sootMethod = sootClass.getMethod(methodSignature.getSubSignature()).get(); + + sootMethod.getBody().getStmts(); + ``` + +=== "Soot" + + ``` java + 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"; + + Options.v().set_soot_classpath(sootCp); + Options.v().set_whole_program(true); + Options.v().setPhaseOption("cg.cha", "on"); + Options.v().setPhaseOption("cg", "all-reachable:true"); + Options.v().set_no_bodies_for_excluded(true); + Options.v().set_allow_phantom_refs(true); + Options.v().setPhaseOption("jb", "use-original-names:true"); + Options.v().set_prepend_classpath(false); + + Scene.v().addBasicClass("java.lang.StringBuilder"); + SootClass c = + Scene.v().forceResolve(targetTestClassName, SootClass.BODIES); + if (c != null) { + c.setApplicationClass(); + } + Scene.v().loadNecessaryClasses(); + + SootMethod method; + for (SootClass c : Scene.v().getApplicationClasses()) { + if(c.getName().equals("example.HelloWorld")){ + for (SootMethod m : c.getMethods()) { + if (!m.hasActiveBody()) { + continue; + } + if (m.getName().equals("entryPoint")) { + method = m; + break; + } + } + } + } + + method.getActiveBody().getUnits(); + ``` + + + + + + + + + diff --git a/docs/migration.md b/docs/migration.md deleted file mode 100644 index c2dbf366e20..00000000000 --- a/docs/migration.md +++ /dev/null @@ -1,3 +0,0 @@ -# From [Soot](https://github.com/soot-oss/Soot) - -// TODO \ No newline at end of file diff --git a/docs/overrides/partials/footer.html b/docs/overrides/partials/footer.html new file mode 100644 index 00000000000..12330e0318a --- /dev/null +++ b/docs/overrides/partials/footer.html @@ -0,0 +1,108 @@ + + + + \ No newline at end of file diff --git a/docs/overrides/partials/header.html b/docs/overrides/partials/header.html new file mode 100644 index 00000000000..cf74cabac7e --- /dev/null +++ b/docs/overrides/partials/header.html @@ -0,0 +1,106 @@ + + + +{% set class = "md-header" %} +{% if "navigation.tabs.sticky" in features %} +{% set class = class ~ " md-header--shadow md-header--lifted" %} +{% elif "navigation.tabs" not in features %} +{% set class = class ~ " md-header--shadow" %} +{% endif %} + + +
+ + + + {% if "navigation.tabs.sticky" in features %} + {% if "navigation.tabs" in features %} + {% include "partials/tabs.html" %} + {% endif %} + {% endif %} +
diff --git a/docs/qilin.md b/docs/qilin.md index efa54851cdc..9c9971adbae 100644 --- a/docs/qilin.md +++ b/docs/qilin.md @@ -2,9 +2,20 @@ see [QilinPTA](https://github.com/QilinPTA/Qilin). ### Dependencies -```maven - // TODO: add submodule -``` +=== "Maven" + ```maven + + org.soot-oss + sootup.java.sourcecode + + + ``` + +=== "Gradle" + + ```groovy + compile "org.soot-oss:sootup.qilin:{{ git_latest_release }}" + ``` ### How to diff --git a/docs/tool_ux.md b/docs/tool_ux.md index 76edebca727..8528055cd3d 100644 --- a/docs/tool_ux.md +++ b/docs/tool_ux.md @@ -1,4 +1,4 @@ -# Prototype to user friendly tool +# From Prototype to user friendly tool `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.. @@ -9,18 +9,21 @@ In SootUp we thought we could help on improving this madness while saving your t The command line parser mimics the options the java executable accepts - at least for what is supported by SootUp. Dependencies: -```maven - - commons-cli - commons-cli - 1.8.0 - - -``` - -```gradle - implementation("commons-cli:commons-cli:1.8.0") -``` +=== "Maven" + ```maven + + commons-cli + commons-cli + 1.8.0 + + ``` + +=== "Gradle" + ```groovy + implementation("commons-cli:commons-cli:1.8.0") + ``` + +### Java Code ```java diff --git a/docs/write_analyses.md b/docs/write_analyses.md index 7ee09b1b10e..914b008d803 100644 --- a/docs/write_analyses.md +++ b/docs/write_analyses.md @@ -1,7 +1,30 @@ -# Writing Analyses +# Write your own Interprocedural Dataflow Analysis + +### Dependencies +=== "Maven" + ```maven + + org.soot-oss + sootup.analysis + + + ``` +=== "Gradle" + ```groovy + compile "org.soot-oss:sootup.analysis:{{ git_latest_release }}" + ``` + +### Useful Knowledge +Background Knowledge as online lectures are available on YouTube. + +- [IFDS Framework](https://www.youtube.com/watch?v=QkK79fT0TFU&ab_channel=SecureSoftwareEngineering) +- [IDE Framework](https://www.youtube.com/watch?v=0uMHX3UY9bg&ab_channel=SecureSoftwareEngineering) + +### Examples +Taint Analysis, TypeState Analysis, Linear Constant Propagation, ... ``` -// TODO improve tutorial! +// TODO incorporate & guide through examples ``` -If you wish to implement an interprocedural data-flow analysis via the IFDS or IDE Framework please have a look at the test cases in the sootup.analysis submodule. \ No newline at end of file +If you wish to implement an interprocedural data-flow analysis via the IFDS or IDE Framework please have a look at the test cases in the sootup.analysis submodule. diff --git a/mkdocs.yml b/mkdocs.yml index f73450910c7..b2a88399d17 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,6 +9,7 @@ nav: - Getting Started: - Installation: installation.md - First Steps: getting-started.md + - Examples: examples.md - Configure your Inputs: analysisinputlocations.md - Basics: @@ -29,7 +30,7 @@ nav: - Misc: - Announcements: announce.md - Design Decisions: whatsnew.md - - Migrating from Soot: migrating.md + - Migration Help: migrating.md - More information: - Latest Javadoc: /SootUp/apidocs @@ -38,14 +39,16 @@ nav: theme: - palette: - primary: white - name: material logo: ./img/SootUpLogo.svg favicon: ./img/icon.svg + palette: + primary: custom + custom_dir: ./docs/overrides + name: material features: - navigation.sections + plugins: - tooltips - search @@ -53,6 +56,7 @@ plugins: src_path: 'sootup.examples/src/test/java/sootup/examples' extra_css: + - css/customizetheme.css - css/hint.min.css markdown_extensions: From b009e5be1fc9542367c9adef222677fda6938d45 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 13:50:50 +0200 Subject: [PATCH 05/23] fix pr title sanitation --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 60c5d17cc68..9aefa61be04 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -65,7 +65,7 @@ jobs: git config --local user.name "github-actions[bot]" # sanitive head_ref name - - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^[:alnum:]_-.#@]/_/g" )" >> $GITHUB_ENV + - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^([[:alnum:]_.-]/_/g"" )" >> $GITHUB_ENV # on push to develop branch - keep a doc around for develop to show the current state - name: deploy doc in subdirectory From 60086d8858e4ce319bf2c7c906585815e9d8ff8e Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 14:44:11 +0200 Subject: [PATCH 06/23] split up Jimple sammelsurium into multiple documents --- docs/css/customizetheme.css | 23 +- docs/jimple-body.md | 140 +++ docs/jimple-stmts.md | 1166 ++++++++++++++++++ docs/jimple-types.md | 539 +++++++++ docs/jimple-values.md | 178 +++ docs/jimple.md | 2279 ++++------------------------------- mkdocs.yml | 5 + 7 files changed, 2251 insertions(+), 2079 deletions(-) create mode 100644 docs/jimple-body.md create mode 100644 docs/jimple-stmts.md create mode 100644 docs/jimple-types.md create mode 100644 docs/jimple-values.md diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index fc2c8b184fa..e3652403932 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -11,7 +11,6 @@ --md-accent-fg-color: rgba(255,140,0, 1); } - .md-typeset a { color: rgba(255,140,0, 0.8); } @@ -87,8 +86,14 @@ } .tabbed-set.tabbed-alternate{ - background: #EEE; + background: rgba(255,140,0, 0.1); + color: rgba(255,140,0, 1); +} + +.md-typeset .tabbed-labels>label>[href]:first-child{ + color: rgba(255,140,0, 1); } + .md-footer{ margin-top: 2em; padding:1em; @@ -109,6 +114,20 @@ html .md-footer-meta.md-typeset a{ border:none; } +.highlighttable{ + border-bottom:1px solid rgba(255,140,0, 0.1); + border-right:1px solid rgba(255,140,0, 0.1); +} + +.highlighttable .linenos{ + background-color:#EEE; + border-color: rgba(255,140,0, 0.1); +} + +.md-typeset code { + background-color: #FFF; +} + #developedBy{ font-size: 11pt; } \ No newline at end of file diff --git a/docs/jimple-body.md b/docs/jimple-body.md new file mode 100644 index 00000000000..10ae286516d --- /dev/null +++ b/docs/jimple-body.md @@ -0,0 +1,140 @@ +# Jimple MethodBody +A Methodbody consists of the Modifiers and its StmtGraph - SootUps Control Flow Graph Structure. +The StmtGraph organizes the flow of [Stmts](jimple-stmts.md). + +### Control Flow Graph +- unexceptional flow -> like FallsThroughStmts and BranchingStmts for if,goto etc. +- exceptional flow -> for exceptions, handled by traps. + +### Stmts +Learn more about the types of [Stmts](jimple-stmts.md). + +### Traps +A Trap is a mechanism to model exceptional flow. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void divideExample(int, int) + { + int x, y, $stack4; + java.io.PrintStream $stack5, $stack7; + java.lang.Exception $stack6; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + y := @parameter1: int; + + label1: + $stack5 = ; + $stack4 = x / y; + virtualinvoke $stack5.($stack4); + + label2: + goto label4; + + label3: + $stack6 := @caughtexception; + $stack7 = ; + virtualinvoke $stack7.("Exception caught"); + + label4: + return; + + catch java.lang.Exception from label1 to label2 with label3; + } + } + /* + By calling getTraps() method, we can get the Trap. + For the above jimple code, we have the below trap: + Trap : + begin : $stack5 = + end : goto [?= return] + handler: $stack6 := @caughtexception + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void divideExample(int x, int y){ + try { + System.out.println(x / y); + }catch (Exception e){ + System.out.println("Exception caught"); + } + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public divideExample(II)V + TRYCATCHBLOCK L0 L1 L2 java/lang/Exception + L0 + LINENUMBER 6 L0 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 1 + ILOAD 2 + IDIV + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L1 + LINENUMBER 9 L1 + GOTO L3 + L2 + LINENUMBER 7 L2 + FRAME SAME1 java/lang/Exception + ASTORE 3 + L4 + LINENUMBER 8 L4 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Exception caught" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L3 + LINENUMBER 10 L3 + FRAME SAME + RETURN + L5 + LOCALVARIABLE e Ljava/lang/Exception; L4 L3 3 + LOCALVARIABLE this Land Ttarget/exercise1/DemoClass; L0 L5 0 + LOCALVARIABLE x I L0 L5 1 + LOCALVARIABLE y I L0 L5 2 + MAXSTACK = 3 + MAXLOCALS = 4 + } + ``` diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md new file mode 100644 index 00000000000..0fb058a1665 --- /dev/null +++ b/docs/jimple-stmts.md @@ -0,0 +1,1166 @@ +# Jimple Stmt ("Statements") +The main piece of Jimple is a Statement (Stmt). [**Stmts**]{formerly known as Units} represent that can be executed by the JVM. + + +## Branching Statements +A BranchingStmt's job is to model the jumps or conditional branching flow between Stmts. + +##### JGotoStmt +for unconditional flow. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + public static void sampleMethod() + { + int i; + i = 0; + + label1: + if i >= 5 goto label3; + if i != 3 goto label2; + goto label3; + + label2: + i = i + 1; + goto label1; + + label3: + return; + } + } + /* + Here for statements "goto label3;" and "goto label1;", + we have two instances of JGotoStmt : + "goto[?=return]" and "goto[?=(branch)]". + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public static void sampleMethod(){ + label1: + for (int i = 0; i < 5; i++){ + if(i == 3){ + break label1; + } + } + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x9 + public static sampleMethod()V + L0 + LINENUMBER 6 L0 + ICONST_0 + ISTORE 0 + L1 + FRAME APPEND [I] + ILOAD 0 + ICONST_5 + IF_ICMPGE L2 + L3 + LINENUMBER 7 L3 + ILOAD 0 + ICONST_3 + IF_ICMPNE L4 + L5 + LINENUMBER 8 L5 + GOTO L2 + L4 + LINENUMBER 6 L4 + FRAME SAME + IINC 0 1 + GOTO L1 + L2 + LINENUMBER 11 L2 + FRAME CHOP 1 + RETURN + LOCALVARIABLE i I L1 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + } + ``` + +##### JIfStmt +for conditional flow depending on boolean Expression (AbstractConditionExpr) so they have two successor Stmt's. +note: The JIfStmt is also a FallsthroughStmt if the branching condition is not met. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public static void sampleMethod(int) + { + int x, $stack1; + java.io.PrintStream $stack2, $stack3; + + x := @parameter0: int; + + $stack1 = x % 2; + if $stack1 != 0 goto label1; + + $stack3 = ; + virtualinvoke $stack3.("Even"); + goto label2; + + label1: + $stack2 = ; + virtualinvoke $stack2.("Odd"); + + label2: + return; + } + } + /* + For statement "if $stack1 != 0 goto label1;", + we have an instance of JIfStmt : + "if $stack1 != 0 goto $stack2 + = ". + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public static void sampleMethod(int x){ + if(x % 2 == 0){ + System.out.println("Even"); + }else{ + System.out.println("Odd"); + } + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x9 + public static sampleMethod(I)V + L0 + LINENUMBER 5 L0 + ILOAD 0 + ICONST_2 + IREM + IFNE L1 + L2 + LINENUMBER 6 L2 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Even" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + GOTO L3 + L1 + LINENUMBER 8 L1 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Odd" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L3 + LINENUMBER 10 L3 + FRAME SAME + RETURN + L4 + LOCALVARIABLE x I L0 L4 0 + MAXSTACK = 2 + MAXLOCALS = 1 + } + ``` + +##### JSwitchStmt +for conditional flow that behaves like a switch-case. It has #numberOfCaseLabels+1 (for default) successor Stmt's. + +All other Stmts are not manipulating the flow, which means they have a single successor Stmt as long as they are not exiting the flow inside a method. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void switchExample(int) + { + int x; + java.io.PrintStream $stack2, $stack3, $stack4; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + + lookupswitch(x) + { + case 1: goto label1; + case 2: goto label2; + default: goto label3; + }; + + label1: + $stack3 = ; + virtualinvoke $stack3.("Input 1"); + goto label4; + + label2: + $stack2 = ; + virtualinvoke $stack2.("Input 2"); + goto label4; + + label3: + $stack4 = ; + virtualinvoke $stack4.("Input more than 2"); + + label4: + return; + } + } + /* + Here for below statement: + lookupswitch(x) + { + case 1: goto label1; + case 2: goto label2; + default: goto label3; + }; + + we have an instance of JLookupSwitchStmt : + lookupswitch(x) + { + case 1: goto $stack3 + = ; + case 2: goto $stack2 + = ; + default: goto $stack4 + = ; + } + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void switchExample(int x){ + switch (x){ + case 1: + System.out.println("Input 1"); + break; + + case 2: + System.out.println("Input 2"); + break; + + default: + System.out.println("Input more than 2"); + break; + + } + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public switchExample(I)V + L0 + LINENUMBER 5 L0 + ILOAD 1 + LOOKUPSWITCH + 1: L1 + 2: L2 + default: L3 + L1 + LINENUMBER 7 L1 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Input 1" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L4 + LINENUMBER 8 L4 + GOTO L5 + L2 + LINENUMBER 11 L2 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Input 2" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L6 + LINENUMBER 12 L6 + GOTO L5 + L3 + LINENUMBER 15 L3 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Input more than 2" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L5 + LINENUMBER 19 L5 + FRAME SAME + RETURN + L7 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L7 0 + LOCALVARIABLE x I L0 L7 1 + MAXSTACK = 2 + MAXLOCALS = 2 + } + ``` + +## FallsThrough Statements +The execution of a FallsthroughStmt goes on with the following Stmt (when no exception was thrown). + +##### JReturnStmt & JReturnVoidStmt +They end the execution/flow inside the current method and return (a value) to its caller. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public int increment(int) + { + int x, $stack2; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + + $stack2 = x + 1; + return $stack2; + } + + public void print() + { + java.io.PrintStream $stack1; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + $stack1 = ; + virtualinvoke $stack1.("Inside method print"); + return; + } + } + /* + "return $stack2" is JReturnStmt. + "return" is JReturnVoidStmt. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public int increment(int x){ + return x + 1; + } + public void print(){ + System.out.println("Inside method print"); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public increment(I)I + L0 + LINENUMBER 5 L0 + ILOAD 1 + ICONST_1 + IADD + IRETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + LOCALVARIABLE x I L0 L1 1 + MAXSTACK = 2 + MAXLOCALS = 2 + + // access flags 0x1 + public print()V + L0 + LINENUMBER 8 L0 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Inside method print" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L1 + LINENUMBER 9 L1 + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + } + ``` + + +##### JThrowStmt +Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler. + + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void divideExample(int, int) + { + int y, x, $stack6; + java.lang.StringBuilder $stack3, $stack5, $stack7; + java.io.PrintStream $stack4; + java.lang.String $stack8; + java.lang.RuntimeException $stack9; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + y := @parameter1: int; + + if y != 0 goto label1; + + $stack9 = new java.lang.RuntimeException; + specialinvoke $stack9.(java.lang.String)>("Divide by zero error"); + throw $stack9; + + label1: + $stack4 = ; + $stack3 = new java.lang.StringBuilder; + specialinvoke $stack3.()>(); + + $stack5 = virtualinvoke $stack3.("Divide result : "); + $stack6 = x / y; + $stack7 = virtualinvoke $stack5.($stack6); + $stack8 = virtualinvoke $stack7.(); + + virtualinvoke $stack4.($stack8); + return; + } + } + /* + "throw $stack9" is JThrowStmt. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void divideExample(int x, int y){ + if(y == 0){ + throw new RuntimeException("Divide by zero error"); + } + System.out.println("Divide result : " + x / y); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public divideExample(II)V + L0 + LINENUMBER 5 L0 + ILOAD 2 + IFNE L1 + L2 + LINENUMBER 6 L2 + NEW java/lang/RuntimeException + DUP + LDC "Divide by zero error" + INVOKESPECIAL java/lang/RuntimeException. + (Ljava/lang/String;)V + ATHROW + L1 + LINENUMBER 8 L1 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + NEW java/lang/StringBuilder + DUP + INVOKESPECIAL java/lang/StringBuilder. ()V + LDC "Divide result : " + INVOKEVIRTUAL java/lang/StringBuilder.append + (Ljava/lang/String;)Ljava/lang/StringBuilder; + ILOAD 1 + ILOAD 2 + IDIV + INVOKEVIRTUAL java/lang/StringBuilder.append + (I)Ljava/lang/StringBuilder; + INVOKEVIRTUAL java/lang/StringBuilder.toString + ()Ljava/lang/String; + INVOKEVIRTUAL java/io/PrintStream.println + (Ljava/lang/String;)V + L3 + LINENUMBER 9 L3 + RETURN + L4 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 + LOCALVARIABLE x I L0 L4 1 + LOCALVARIABLE y I L0 L4 2 + MAXSTACK = 4 + MAXLOCALS = 3 + } + ``` + + +##### JInvokeStmt +transfers the control flow to another method until the called method returns. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void print(int) + { + target.exercise1.DemoClass this; + int x, a; + java.io.PrintStream $stack4, $stack6; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + + a = virtualinvoke this.(x); + $stack4 = ; + virtualinvoke $stack4.(a); + + a = virtualinvoke this.(a); + $stack6 = ; + virtualinvoke $stack6.(a); + + return; + } + + public int increment(int) + { + int x, $stack2; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + + $stack2 = x + 1; + return $stack2; + } + } + /* + "specialinvoke this.()>()", + "virtualinvoke this.(x)", + "virtualinvoke this.(a)" + are JInvokeStmts. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void print(int x){ + int a = increment(x); + System.out.println(a); + a = increment(a); + System.out.println(a); + } + public int increment(int x){ + return x + 1; + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public print(I)V + L0 + LINENUMBER 5 L0 + ALOAD 0 + ILOAD 1 + INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I + ISTORE 2 + L1 + LINENUMBER 6 L1 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 2 + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L2 + LINENUMBER 7 L2 + ALOAD 0 + ILOAD 2 + INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I + ISTORE 2 + L3 + LINENUMBER 8 L3 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 2 + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L4 + LINENUMBER 9 L4 + RETURN + L5 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0 + LOCALVARIABLE x I L0 L5 1 + LOCALVARIABLE a I L1 L5 2 + MAXSTACK = 2 + MAXLOCALS = 3 + + // access flags 0x1 + public increment(I)I + L0 + LINENUMBER 11 L0 + ILOAD 1 + ICONST_1 + IADD + IRETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + LOCALVARIABLE x I L0 L1 1 + MAXSTACK = 2 + MAXLOCALS = 2 + } + ``` + + +##### JAssignStmt +assigns a Value from the right hand-side to the left hand-side. +Left hand-side of an assignment can be a Local referencing a variable (i.e. a Local) or a FieldRef referencing a Field. +Right hand-side of an assignment can be an expression (Expr), a Local, a FieldRef or a Constant. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + this. = 0; + return; + } + + public int updateCounter() + { + target.exercise1.DemoClass this; + int $stack1, $stack2, $stack3; + + this := @this: target.exercise1.DemoClass; + + $stack1 = this.; + $stack2 = $stack1 + 1; + this. = $stack2; + $stack3 = this.; + + return $stack3; + } + } + /* + "this. = 0", + "$stack1 = this.", + "$stack2 = $stack1 + 1" + "this. = $stack2" + "$stack3 = this." + are JAssignStmts. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + private int counter = 0; + public int updateCounter(){ + counter = counter + 1; + return counter; + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x2 + private I counter + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + L1 + LINENUMBER 4 L1 + ALOAD 0 + ICONST_0 + PUTFIELD target/exercise1/DemoClass.counter : I + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + + // access flags 0x1 + public updateCounter()I + L0 + LINENUMBER 6 L0 + ALOAD 0 + ALOAD 0 + GETFIELD target/exercise1/DemoClass.counter : I + ICONST_1 + IADD + PUTFIELD target/exercise1/DemoClass.counter : I + L1 + LINENUMBER 7 L1 + ALOAD 0 + GETFIELD target/exercise1/DemoClass.counter : I + IRETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 3 + MAXLOCALS = 1 + } + ``` + + +##### JIdentityStmt +is semantically like the JAssignStmt and handles assignments of IdentityRef's to make implicit assignments explicit into the StmtGraph. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void DemoClass(int) + { + target.exercise1.DemoClass this; + int counter; + + this := @this: target.exercise1.DemoClass; + counter := @parameter0: int; + this. = counter; + return; + } + } + /* + "this := @this: target.exercise1.DemoClass" and + "counter := @parameter0: int" are JIdentityStmts + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + private int counter; + public void DemoClass(int counter){ + this.counter = counter; + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x2 + private I counter + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public DemoClass(I)V + L0 + LINENUMBER 6 L0 + ALOAD 0 + ILOAD 1 + PUTFIELD target/exercise1/DemoClass.counter : I + L1 + LINENUMBER 7 L1 + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + LOCALVARIABLE counter I L0 L2 1 + MAXSTACK = 2 + MAXLOCALS = 2 + } + ``` + + +#####JEnterMonitorStmt & JExitMonitorStmt +marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + this. = 0; + return; + } + + public int updateCounter() + { + target.exercise1.DemoClass this; + int $stack4, $stack5, $stack7; + java.lang.Throwable $stack8; + + this := @this: target.exercise1.DemoClass; + + entermonitor this; + + label1: + $stack4 = this.; + $stack5 = $stack4 + 1; + this. = $stack5; + + exitmonitor this; + + label2: + goto label5; + + label3: + $stack8 := @caughtexception; + + exitmonitor this; + + label4: + throw $stack8; + + label5: + $stack7 = this.; + return $stack7; + + catch java.lang.Throwable from label1 to label2 with label3; + catch java.lang.Throwable from label3 to label4 with label3; + } + } + /* + "entermonitor this" is JEnterMonitorStmt. + "exitmonitor this" is JExitMonitorStmt. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + private int counter = 0; + public int updateCounter(){ + synchronized (this) { + counter = counter + 1; + } + return counter; + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x2 + private I counter + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + L1 + LINENUMBER 4 L1 + ALOAD 0 + ICONST_0 + PUTFIELD target/exercise1/DemoClass.counter : I + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + + // access flags 0x1 + public updateCounter()I + TRYCATCHBLOCK L0 L1 L2 null + TRYCATCHBLOCK L2 L3 L2 null + L4 + LINENUMBER 6 L4 + ALOAD 0 + DUP + ASTORE 1 + MONITORENTER + L0 + LINENUMBER 7 L0 + ALOAD 0 + ALOAD 0 + GETFIELD target/exercise1/DemoClass.counter : I + ICONST_1 + IADD + PUTFIELD target/exercise1/DemoClass.counter : I + L5 + LINENUMBER 8 L5 + ALOAD 1 + MONITOREXIT + L1 + GOTO L6 + L2 + FRAME FULL [target/exercise1/DemoClass java/lang/Object] + [java/lang/Throwable] + ASTORE 2 + ALOAD 1 + MONITOREXIT + L3 + ALOAD 2 + ATHROW + L6 + LINENUMBER 9 L6 + FRAME CHOP 1 + ALOAD 0 + GETFIELD target/exercise1/DemoClass.counter : I + IRETURN + L7 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L4 L7 0 + MAXSTACK = 3 + MAXLOCALS = 3 + } + ``` + + +##### JRetStmt +##### JBreakpointStmt +models a Breakpoint set by a Debugger (usually not relevant for static analyses) diff --git a/docs/jimple-types.md b/docs/jimple-types.md new file mode 100644 index 00000000000..fc073396599 --- /dev/null +++ b/docs/jimple-types.md @@ -0,0 +1,539 @@ +#Jimple Types + +#### PrimaryType +- BooleanType +- ByteType +- CharType +- ShortType +- IntType +- LongType +- DoubleType +- FloatType + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + + public void display() + { + java.io.PrintStream $stack11, $stack13, $stack15, + $stack17, $stack19, $stack21, $stack23, $stack25; + int $stack12, $stack14, $stack16, $stack18; + long $stack20; + double $stack22; + float $stack24; + target.exercise1.DemoClass this; + boolean $stack26; + + this := @this: target.exercise1.DemoClass; + + $stack11 = ; + + goto label1; + + label1: + $stack26 = 0; + virtualinvoke $stack11.($stack26); + + $stack13 = ; + $stack12 = 127 - 1; + virtualinvoke $stack13.($stack12); + + $stack15 = ; + $stack14 = 97 + 1; + virtualinvoke $stack15.($stack14); + + $stack17 = ; + $stack16 = 1123 + 1; + virtualinvoke $stack17.($stack16); + + $stack19 = ; + $stack18 = 123456 + 1; + virtualinvoke $stack19.($stack18); + + $stack21 = ; + $stack20 = 10L + 1L; + virtualinvoke $stack21.($stack20); + + $stack23 = ; + $stack22 = 10.1 + 1.0; + virtualinvoke $stack23.($stack22); + + $stack25 = ; + $stack24 = 10.1F + 1.0F; + virtualinvoke $stack25.($stack24); + + return; + } + } + /* + The JimpleLocal $stack12, $stack14, $stack16, $stack18 are of IntType. + Similarly, $stack20 is of LongType, $stack22 is of DoubleType and so on. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void display(){ + boolean varBoolean = true; + byte varByte = 127; + char varChar = 'a'; + short varShort = 1123; + int varInt = 123456; + long varLong = 10L; + double varDouble = 10.10; + float varFloat = 10.10f; + + System.out.println(!varBoolean); + System.out.println(varByte-1); + System.out.println(varChar+1); + System.out.println(varShort+1); + System.out.println(varInt+1); + System.out.println(varLong+1); + System.out.println(varDouble+1); + System.out.println(varFloat+1); + + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public display()V + L0 + LINENUMBER 5 L0 + ICONST_1 + ISTORE 1 + L1 + LINENUMBER 6 L1 + BIPUSH 127 + ISTORE 2 + L2 + LINENUMBER 7 L2 + BIPUSH 97 + ISTORE 3 + L3 + LINENUMBER 8 L3 + SIPUSH 1123 + ISTORE 4 + L4 + LINENUMBER 9 L4 + LDC 123456 + ISTORE 5 + L5 + LINENUMBER 10 L5 + LDC 10 + LSTORE 6 + L6 + LINENUMBER 11 L6 + LDC 10.1 + DSTORE 8 + L7 + LINENUMBER 12 L7 + LDC 10.1 + FSTORE 10 + L8 + LINENUMBER 14 L8 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 1 + IFNE L9 + ICONST_1 + GOTO L10 + L9 + FRAME FULL [target/exercise1/DemoClass I I I I I J D F] + [java/io/PrintStream] + ICONST_0 + L10 + FRAME FULL [target/exercise1/DemoClass I I I I I J D F] + [java/io/PrintStream I] + INVOKEVIRTUAL java/io/PrintStream.println (Z)V + L11 + LINENUMBER 15 L11 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 2 + ICONST_1 + ISUB + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L12 + LINENUMBER 16 L12 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 3 + ICONST_1 + IADD + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L13 + LINENUMBER 17 L13 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 4 + ICONST_1 + IADD + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L14 + LINENUMBER 18 L14 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 5 + ICONST_1 + IADD + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L15 + LINENUMBER 19 L15 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LLOAD 6 + LCONST_1 + LADD + INVOKEVIRTUAL java/io/PrintStream.println (J)V + L16 + LINENUMBER 20 L16 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + DLOAD 8 + DCONST_1 + DADD + INVOKEVIRTUAL java/io/PrintStream.println (D)V + L17 + LINENUMBER 21 L17 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + FLOAD 10 + FCONST_1 + FADD + INVOKEVIRTUAL java/io/PrintStream.println (F)V + L18 + LINENUMBER 23 L18 + RETURN + L19 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L19 0 + LOCALVARIABLE varBoolean Z L1 L19 1 + LOCALVARIABLE varByte B L2 L19 2 + LOCALVARIABLE varChar C L3 L19 3 + LOCALVARIABLE varShort S L4 L19 4 + LOCALVARIABLE varInt I L5 L19 5 + LOCALVARIABLE varLong J L6 L19 6 + LOCALVARIABLE varDouble D L7 L19 8 + LOCALVARIABLE varFloat F L8 L19 10 + MAXSTACK = 5 + MAXLOCALS = 11 + } + ``` + + +#### ReferenceType +- ClassType +- ArrayType +- NullType + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public target.exercise1.DemoClass getObject(target.exercise1.DemoClass) + { + target.exercise1.DemoClass obj, this; + this := @this: target.exercise1.DemoClass; + obj := @parameter0: target.exercise1.DemoClass; + return obj; + } + + public void compute(boolean) + { + int[] b; + java.io.PrintStream $stack5, $stack6; + boolean check; + target.exercise1.DemoClass this; + int i; + null_type r0; + java.lang.NullPointerException soot0; + this := @this: target.exercise1.DemoClass; + check := @parameter0: boolean; + b = newarray (int)[5]; + i = 0; + + label1: + if i >= 5 goto label3; + if check == 0 goto label2; + r0 = (null_type) i; + soot0 = new java.lang.NullPointerException; + specialinvoke soot0.(java.lang.String)> + ("This statement would have triggered an Exception: a[i#1] = r0"); + throw soot0; + + label2: + b[i] = i; + i = i + 1; + goto label1; + + label3: + $stack5 = ; + virtualinvoke $stack5.(b); + $stack6 = ; + virtualinvoke $stack6.(null); + return; + } + } + /* + The JimpleLocal b is of ArrayType, + and JimpleLocal r0 is of NullType. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + + public DemoClass getObject(DemoClass obj){ + return obj; + } + + public void compute(boolean check){ + int a[] = null; + int b[] = new int[5]; + for (int i = 0; i < 5; i++) { + if(check){ + a[i] = i; + } + b[i] = i; + } + System.out.println(b); + System.out.println(a); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public getObject(Ltarget/exercise1/DemoClass;)Ltarget/exercise1/DemoClass; + L0 + LINENUMBER 6 L0 + ALOAD 1 + ARETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + LOCALVARIABLE obj Ltarget/exercise1/DemoClass; L0 L1 1 + MAXSTACK = 1 + MAXLOCALS = 2 + + // access flags 0x1 + public compute(Z)V + L0 + LINENUMBER 10 L0 + ACONST_NULL + ASTORE 2 + L1 + LINENUMBER 11 L1 + ICONST_5 + NEWARRAY T_INT + ASTORE 3 + L2 + LINENUMBER 12 L2 + ICONST_0 + ISTORE 4 + L3 + FRAME APPEND [[I [I I] + ILOAD 4 + ICONST_5 + IF_ICMPGE L4 + L5 + LINENUMBER 13 L5 + ILOAD 1 + IFEQ L6 + L7 + LINENUMBER 14 L7 + ALOAD 2 + ILOAD 4 + ILOAD 4 + IASTORE + L6 + LINENUMBER 16 L6 + FRAME SAME + ALOAD 3 + ILOAD 4 + ILOAD 4 + IASTORE + L8 + LINENUMBER 12 L8 + IINC 4 1 + GOTO L3 + L4 + LINENUMBER 18 L4 + FRAME CHOP 1 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ALOAD 3 + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V + L9 + LINENUMBER 19 L9 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ALOAD 2 + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V + L10 + LINENUMBER 20 L10 + RETURN + L11 + LOCALVARIABLE i I L3 L4 4 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L11 0 + LOCALVARIABLE check Z L0 L11 1 + LOCALVARIABLE a [I L1 L11 2 + LOCALVARIABLE b [I L2 L11 3 + MAXSTACK = 3 + MAXLOCALS = 5 + } + ``` + + +#### VoidType +Only used as a possible return type of a method. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void voidMethod() + { + java.io.PrintStream $stack1; + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + $stack1 = ; + virtualinvoke $stack1.("In voidMethod()."); + return; + } + } + /* + For the SootMethod - , + returnType is instance of VoidType. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void voidMethod(){ + System.out.println("In voidMethod()."); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public voidMethod()V + L0 + LINENUMBER 5 L0 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "In voidMethod()." + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L1 + LINENUMBER 6 L1 + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + } + ``` + diff --git a/docs/jimple-values.md b/docs/jimple-values.md new file mode 100644 index 00000000000..fa49fd97c8f --- /dev/null +++ b/docs/jimple-values.md @@ -0,0 +1,178 @@ +# Jimple Values + +### Immediate +An Immediate has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). + +#### Local +```jimple +i0 +``` +A Local is a variable and its scope is inside its method i.e. no referencing from outside a method. +Values can be assigned to Locals via JIdentityStmt or JAssignStmt. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void compute() + { + java.io.PrintStream $stack2, $stack3; + target.exercise1.DemoClass this; + int local#2; + + this := @this: target.exercise1.DemoClass; + $stack2 = ; + virtualinvoke $stack2.(1); + + local#2 = this.; + $stack3 = ; + virtualinvoke $stack3.(local#2); + return; + } + } + /* + $stack2, this, $stack3, local#2 are all JimpleLocal. + + "this := @this: target.exercise1.DemoClass" is JIdentityStmt + + "$stack2 = ", + "local#2 = this.", + "$stack3 = " + are JAssignStmt + + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + + private int global; + + public void compute(){ + int local; + local = 1; + System.out.println(local); + local = this.global; + System.out.println(local); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x2 + private I global + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public compute()V + L0 + LINENUMBER 9 L0 + ICONST_1 + ISTORE 1 + L1 + LINENUMBER 10 L1 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 1 + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L2 + LINENUMBER 11 L2 + ALOAD 0 + GETFIELD target/exercise1/DemoClass.global : I + ISTORE 1 + L3 + LINENUMBER 12 L3 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 1 + INVOKEVIRTUAL java/io/PrintStream.println (I)V + L4 + LINENUMBER 14 L4 + RETURN + L5 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0 + LOCALVARIABLE local I L1 L5 1 + MAXSTACK = 2 + MAXLOCALS = 2 + } + ``` + + + +#### Constant +represents a value itself. don't confuse it with a variable/Local which has a immutable (i.e. final) attribute. + +There exists a constant entity for every Type - that way all value types can have a representation. + + +### Expr +An expression is a language construct that returns a value. E.g. a binary operation such as addition. + + +### Ref +#### JArrayRef +```jimple +$arr[1] +``` +referencing a position inside an array. + +#### JFieldRef (JStaticFieldRef & JInstanceFieldRef) +```jimple + +// or +r1. +``` +referencing a Field via its FieldSignature and if necessary (i.e. with JInstanceFieldRef) the corresponding Local instance that points to the object instance. + +#### IdentityRef +The IdentityRef makes those implicit special value assignments explicit. + +##### JThisRef +```jimple +@this: package.fruit.Banana +``` +represents the this pointer of the current class. + +##### JCaughtExceptionRef +```jimple +@caughtexception +``` +represents the value of the thrown exception (caught by this exceptionhandler). + +##### JParameterRef +```jimple +i0 := @parameter0 +i1 := @parameter1 +``` +represents a parameter of a method, identified by its index. + diff --git a/docs/jimple.md b/docs/jimple.md index 007cd9baff8..a0ffe406f2e 100644 --- a/docs/jimple.md +++ b/docs/jimple.md @@ -55,7 +55,7 @@ It might help to visualize how the Jimple version of a Java code looks like. Hav } ``` -=== "Byte Code" +=== "Bytecode" ``` // class version 52.0 (52) @@ -103,9 +103,147 @@ Three-Address-Code which means there are no nested expressions. (nested expressions can be modeled via Locals that store intermediate calculation results.) +### Signatures and ClassTypes +Signatures are used to identify Classes,Methods or Fields uniquely/globally. +Sidenote: Locals, do not have a signature, since they are referenced within method boundaries. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + + specialinvoke this.()>(); + this. = 3.14; + return; + } + + public void demoMethod() + { + java.io.PrintStream $stack3, $stack5; + java.lang.StringBuilder $stack4, $stack6, $stack7; + java.lang.String $stack8; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + $stack3 = ; + + virtualinvoke $stack3.("pi : 3.14"); + $stack5 = ; + $stack4 = new java.lang.StringBuilder; + + specialinvoke $stack4.()>(); + $stack6 = virtualinvoke $stack4. + ("pi : "); + $stack7 = virtualinvoke $stack6.(3.1415); + $stack8 = virtualinvoke $stack7.(); + + virtualinvoke $stack5.($stack8); + return; + } + } + /* + For JInstanceFieldRef "this." + signature is + Similarly, we have other signatures like + ()>, + + and so on. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + private final double pi = 3.14; + + public void demoMethod(){ + double localPi = 3.1415; + System.out.println("pi : " + pi); + System.out.println("pi : " + localPi); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x12 + private final D pi = 3.14 + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + L1 + LINENUMBER 4 L1 + ALOAD 0 + LDC 3.14 + PUTFIELD target/exercise1/DemoClass.pi : D + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 3 + MAXLOCALS = 1 + + // access flags 0x1 + public demoMethod()V + L0 + LINENUMBER 6 L0 + LDC 3.1415 + DSTORE 1 + L1 + LINENUMBER 7 L1 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "pi : 3.14" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L2 + LINENUMBER 8 L2 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + NEW java/lang/StringBuilder + DUP + INVOKESPECIAL java/lang/StringBuilder. ()V + LDC "pi : " + INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) + Ljava/lang/StringBuilder; + DLOAD 1 + INVOKEVIRTUAL java/lang/StringBuilder.append (D)Ljava/lang/StringBuilder; + INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L3 + LINENUMBER 9 L3 + RETURN + L4 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 + LOCALVARIABLE localPi D L1 L4 1 + MAXSTACK = 4 + MAXLOCALS = 3 + } + ``` + ### Class (or Interface) A class consists of Fields and Methods. -It is referenced by its ClassType. +It is referenced by its ClassType. === "Jimple" @@ -130,7 +268,7 @@ It is referenced by its ClassType. public class DemoClass {} ``` -=== "Byte Code" +=== "Bytecode" ``` // class version 52.0 (52) @@ -156,7 +294,7 @@ It is referenced by its ClassType. ### Field A Field is a piece of memory which can store a value that is accessible according to its visibility modifier. -It is referenced by its FieldSignature. +It is referenced by its FieldSignature. === "Jimple" @@ -187,7 +325,7 @@ It is referenced by its FieldSignature. } ``` -=== "Byte Code" +=== "Bytecode" ``` // class version 52.0 (52) @@ -219,9 +357,9 @@ It is referenced by its FieldSignature. ``` -### Method and the Body +### Method and its Body The interesting part is a method. A method is a "piece of code" that can be executed. -It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control flow graph} that models the sequence of single instructions/statements (Stmts). +It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control flow graph} that models the sequence of single instructions/statements (Stmts). === "Jimple" @@ -273,7 +411,7 @@ It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control } ``` -=== "Byte Code" +=== "Bytecode" ``` // class version 52.0 (52) @@ -318,9 +456,8 @@ It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control ``` -### Signatures -Signatures are required for identifying or referencing things across a method, such as Classes, Interfaces, Methods or Fields. -Locals, on the other hand, do not need signatures, since they are referenced within method boundaries. +### Traps +A Trap is a mechanism to model exceptional flow. === "Jimple" @@ -331,48 +468,48 @@ Locals, on the other hand, do not need signatures, since they are referenced wit { target.exercise1.DemoClass this; this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - this. = 3.14; return; } - public void demoMethod() + public void divideExample(int, int) { - java.io.PrintStream $stack3, $stack5; - java.lang.StringBuilder $stack4, $stack6, $stack7; - java.lang.String $stack8; + int x, y, $stack4; + java.io.PrintStream $stack5, $stack7; + java.lang.Exception $stack6; target.exercise1.DemoClass this; this := @this: target.exercise1.DemoClass; - $stack3 = ; + x := @parameter0: int; + y := @parameter1: int; - virtualinvoke $stack3.("pi : 3.14"); - $stack5 = ; - $stack4 = new java.lang.StringBuilder; + label1: + $stack5 = ; + $stack4 = x / y; + virtualinvoke $stack5.($stack4); - specialinvoke $stack4.()>(); - $stack6 = virtualinvoke $stack4. - ("pi : "); - $stack7 = virtualinvoke $stack6.(3.1415); - $stack8 = virtualinvoke $stack7.(); + label2: + goto label4; - virtualinvoke $stack5.($stack8); - return; + label3: + $stack6 := @caughtexception; + $stack7 = ; + virtualinvoke $stack7.("Exception caught"); + + label4: + return; + + catch java.lang.Exception from label1 to label2 with label3; } } /* - For JInstanceFieldRef "this." - signature is - Similarly, we have other signatures like - ()>, - - and so on. + By calling getTraps() method, we can get the Traip chain. + For the above jimple code, we have the below trap: + Trap : + begin : $stack5 = + end : goto [?= return] + handler: $stack6 := @caughtexception */ ``` @@ -382,17 +519,17 @@ Locals, on the other hand, do not need signatures, since they are referenced wit package target.exercise1; public class DemoClass { - private final double pi = 3.14; - - public void demoMethod(){ - double localPi = 3.1415; - System.out.println("pi : " + pi); - System.out.println("pi : " + localPi); + public void divideExample(int x, int y){ + try { + System.out.println(x / y); + }catch (Exception e){ + System.out.println("Exception caught"); + } } } ``` -=== "Byte Code" +=== "Bytecode" ``` // class version 52.0 (52) @@ -401,172 +538,35 @@ Locals, on the other hand, do not need signatures, since they are referenced wit // compiled from: DemoClass.java - // access flags 0x12 - private final D pi = 3.14 - - // access flags 0x1 + // access flags 0x1 public ()V L0 LINENUMBER 3 L0 ALOAD 0 INVOKESPECIAL java/lang/Object. ()V - L1 - LINENUMBER 4 L1 - ALOAD 0 - LDC 3.14 - PUTFIELD target/exercise1/DemoClass.pi : D RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 3 - MAXLOCALS = 1 + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 // access flags 0x1 - public demoMethod()V + public divideExample(II)V + TRYCATCHBLOCK L0 L1 L2 java/lang/Exception L0 - LINENUMBER 6 L0 - LDC 3.1415 - DSTORE 1 + LINENUMBER 6 L0 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + ILOAD 1 + ILOAD 2 + IDIV + INVOKEVIRTUAL java/io/PrintStream.println (I)V L1 - LINENUMBER 7 L1 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "pi : 3.14" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + LINENUMBER 9 L1 + GOTO L3 L2 - LINENUMBER 8 L2 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - NEW java/lang/StringBuilder - DUP - INVOKESPECIAL java/lang/StringBuilder. ()V - LDC "pi : " - INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;) - Ljava/lang/StringBuilder; - DLOAD 1 - INVOKEVIRTUAL java/lang/StringBuilder.append (D)Ljava/lang/StringBuilder; - INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L3 - LINENUMBER 9 L3 - RETURN - L4 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 - LOCALVARIABLE localPi D L1 L4 1 - MAXSTACK = 4 - MAXLOCALS = 3 - } - ``` - -### Trap -A Trap is a mechanism to model exceptional flow. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void divideExample(int, int) - { - int x, y, $stack4; - java.io.PrintStream $stack5, $stack7; - java.lang.Exception $stack6; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - y := @parameter1: int; - - label1: - $stack5 = ; - $stack4 = x / y; - virtualinvoke $stack5.($stack4); - - label2: - goto label4; - - label3: - $stack6 := @caughtexception; - $stack7 = ; - virtualinvoke $stack7.("Exception caught"); - - label4: - return; - - catch java.lang.Exception from label1 to label2 with label3; - } - } - /* - By calling getTraps() method, we can get the Traip chain. - For the above jimple code, we have the below trap: - Trap : - begin : $stack5 = - end : goto [?= return] - handler: $stack6 := @caughtexception - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void divideExample(int x, int y){ - try { - System.out.println(x / y); - }catch (Exception e){ - System.out.println("Exception caught"); - } - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public divideExample(II)V - TRYCATCHBLOCK L0 L1 L2 java/lang/Exception - L0 - LINENUMBER 6 L0 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 1 - ILOAD 2 - IDIV - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L1 - LINENUMBER 9 L1 - GOTO L3 - L2 - LINENUMBER 7 L2 - FRAME SAME1 java/lang/Exception - ASTORE 3 + LINENUMBER 7 L2 + FRAME SAME1 java/lang/Exception + ASTORE 3 L4 LINENUMBER 8 L4 GETSTATIC java/lang/System.out : Ljava/io/PrintStream; @@ -578,1885 +578,10 @@ A Trap is a mechanism to model exceptional flow. RETURN L5 LOCALVARIABLE e Ljava/lang/Exception; L4 L3 3 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0 + LOCALVARIABLE this Land Ttarget/exercise1/DemoClass; L0 L5 0 LOCALVARIABLE x I L0 L5 1 LOCALVARIABLE y I L0 L5 2 MAXSTACK = 3 MAXLOCALS = 4 } ``` - -### Stmt -The main piece of Jimple is a Statement (Stmt). [**Stmts**]{formerly known as Units} represent that can be executed by the JVM. - - -#### Branching Statements -A BranchingStmt's job is to model the flow between Stmts. - - -##### JGotoStmt -for unconditional flow. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - public static void sampleMethod() - { - int i; - i = 0; - - label1: - if i >= 5 goto label3; - if i != 3 goto label2; - goto label3; - - label2: - i = i + 1; - goto label1; - - label3: - return; - } - } - /* - Here for statements "goto label3;" and "goto label1;", - we have two instances of JGotoStmt : - "goto[?=return]" and "goto[?=(branch)]". - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public static void sampleMethod(){ - label1: - for (int i = 0; i < 5; i++){ - if(i == 3){ - break label1; - } - } - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x9 - public static sampleMethod()V - L0 - LINENUMBER 6 L0 - ICONST_0 - ISTORE 0 - L1 - FRAME APPEND [I] - ILOAD 0 - ICONST_5 - IF_ICMPGE L2 - L3 - LINENUMBER 7 L3 - ILOAD 0 - ICONST_3 - IF_ICMPNE L4 - L5 - LINENUMBER 8 L5 - GOTO L2 - L4 - LINENUMBER 6 L4 - FRAME SAME - IINC 0 1 - GOTO L1 - L2 - LINENUMBER 11 L2 - FRAME CHOP 1 - RETURN - LOCALVARIABLE i I L1 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - } - ``` - -##### JIfStmt -for conditional flow depending on boolean Expression (AbstractConditionExpr) so they have two successor Stmt's. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public static void sampleMethod(int) - { - int x, $stack1; - java.io.PrintStream $stack2, $stack3; - - x := @parameter0: int; - - $stack1 = x % 2; - if $stack1 != 0 goto label1; - - $stack3 = ; - virtualinvoke $stack3.("Even"); - goto label2; - - label1: - $stack2 = ; - virtualinvoke $stack2.("Odd"); - - label2: - return; - } - } - /* - For statement "if $stack1 != 0 goto label1;", - we have an instance of JIfStmt : - "if $stack1 != 0 goto $stack2 - = ". - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public static void sampleMethod(int x){ - if(x % 2 == 0){ - System.out.println("Even"); - }else{ - System.out.println("Odd"); - } - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x9 - public static sampleMethod(I)V - L0 - LINENUMBER 5 L0 - ILOAD 0 - ICONST_2 - IREM - IFNE L1 - L2 - LINENUMBER 6 L2 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Even" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - GOTO L3 - L1 - LINENUMBER 8 L1 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Odd" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L3 - LINENUMBER 10 L3 - FRAME SAME - RETURN - L4 - LOCALVARIABLE x I L0 L4 0 - MAXSTACK = 2 - MAXLOCALS = 1 - } - ``` - -##### JSwitchStmt -for conditional flow that behaves like a switch-case. It has #numberOfCaseLabels+1 (for default) successor Stmt's. - -All other Stmts are not manipulating the flow, which means they have a single successor Stmt as long as they are not exiting the flow inside a method. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void switchExample(int) - { - int x; - java.io.PrintStream $stack2, $stack3, $stack4; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - - lookupswitch(x) - { - case 1: goto label1; - case 2: goto label2; - default: goto label3; - }; - - label1: - $stack3 = ; - virtualinvoke $stack3.("Input 1"); - goto label4; - - label2: - $stack2 = ; - virtualinvoke $stack2.("Input 2"); - goto label4; - - label3: - $stack4 = ; - virtualinvoke $stack4.("Input more than 2"); - - label4: - return; - } - } - /* - Here for below statement: - lookupswitch(x) - { - case 1: goto label1; - case 2: goto label2; - default: goto label3; - }; - - we have an instance of JLookupSwitchStmt : - lookupswitch(x) - { - case 1: goto $stack3 - = ; - case 2: goto $stack2 - = ; - default: goto $stack4 - = ; - } - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void switchExample(int x){ - switch (x){ - case 1: - System.out.println("Input 1"); - break; - - case 2: - System.out.println("Input 2"); - break; - - default: - System.out.println("Input more than 2"); - break; - - } - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public switchExample(I)V - L0 - LINENUMBER 5 L0 - ILOAD 1 - LOOKUPSWITCH - 1: L1 - 2: L2 - default: L3 - L1 - LINENUMBER 7 L1 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Input 1" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L4 - LINENUMBER 8 L4 - GOTO L5 - L2 - LINENUMBER 11 L2 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Input 2" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L6 - LINENUMBER 12 L6 - GOTO L5 - L3 - LINENUMBER 15 L3 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Input more than 2" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L5 - LINENUMBER 19 L5 - FRAME SAME - RETURN - L7 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L7 0 - LOCALVARIABLE x I L0 L7 1 - MAXSTACK = 2 - MAXLOCALS = 2 - } - ``` - - -##### JReturnStmt & JReturnVoidStmt -They end the execution/flow inside the current method and return (a value) to its caller. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public int increment(int) - { - int x, $stack2; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - - $stack2 = x + 1; - return $stack2; - } - - public void print() - { - java.io.PrintStream $stack1; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - $stack1 = ; - virtualinvoke $stack1.("Inside method print"); - return; - } - } - /* - "return $stack2" is JReturnStmt. - "return" is JReturnVoidStmt. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public int increment(int x){ - return x + 1; - } - public void print(){ - System.out.println("Inside method print"); - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public increment(I)I - L0 - LINENUMBER 5 L0 - ILOAD 1 - ICONST_1 - IADD - IRETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - LOCALVARIABLE x I L0 L1 1 - MAXSTACK = 2 - MAXLOCALS = 2 - - // access flags 0x1 - public print()V - L0 - LINENUMBER 8 L0 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Inside method print" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L1 - LINENUMBER 9 L1 - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - } - ``` - - -##### JThrowStmt -Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler. - - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void divideExample(int, int) - { - int y, x, $stack6; - java.lang.StringBuilder $stack3, $stack5, $stack7; - java.io.PrintStream $stack4; - java.lang.String $stack8; - java.lang.RuntimeException $stack9; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - y := @parameter1: int; - - if y != 0 goto label1; - - $stack9 = new java.lang.RuntimeException; - specialinvoke $stack9.(java.lang.String)>("Divide by zero error"); - throw $stack9; - - label1: - $stack4 = ; - $stack3 = new java.lang.StringBuilder; - specialinvoke $stack3.()>(); - - $stack5 = virtualinvoke $stack3.("Divide result : "); - $stack6 = x / y; - $stack7 = virtualinvoke $stack5.($stack6); - $stack8 = virtualinvoke $stack7.(); - - virtualinvoke $stack4.($stack8); - return; - } - } - /* - "throw $stack9" is JThrowStmt. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void divideExample(int x, int y){ - if(y == 0){ - throw new RuntimeException("Divide by zero error"); - } - System.out.println("Divide result : " + x / y); - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public divideExample(II)V - L0 - LINENUMBER 5 L0 - ILOAD 2 - IFNE L1 - L2 - LINENUMBER 6 L2 - NEW java/lang/RuntimeException - DUP - LDC "Divide by zero error" - INVOKESPECIAL java/lang/RuntimeException. - (Ljava/lang/String;)V - ATHROW - L1 - LINENUMBER 8 L1 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - NEW java/lang/StringBuilder - DUP - INVOKESPECIAL java/lang/StringBuilder. ()V - LDC "Divide result : " - INVOKEVIRTUAL java/lang/StringBuilder.append - (Ljava/lang/String;)Ljava/lang/StringBuilder; - ILOAD 1 - ILOAD 2 - IDIV - INVOKEVIRTUAL java/lang/StringBuilder.append - (I)Ljava/lang/StringBuilder; - INVOKEVIRTUAL java/lang/StringBuilder.toString - ()Ljava/lang/String; - INVOKEVIRTUAL java/io/PrintStream.println - (Ljava/lang/String;)V - L3 - LINENUMBER 9 L3 - RETURN - L4 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 - LOCALVARIABLE x I L0 L4 1 - LOCALVARIABLE y I L0 L4 2 - MAXSTACK = 4 - MAXLOCALS = 3 - } - ``` - - -##### JInvokeStmt -transfers the control flow to another method until the called method returns. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void print(int) - { - target.exercise1.DemoClass this; - int x, a; - java.io.PrintStream $stack4, $stack6; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - - a = virtualinvoke this.(x); - $stack4 = ; - virtualinvoke $stack4.(a); - - a = virtualinvoke this.(a); - $stack6 = ; - virtualinvoke $stack6.(a); - - return; - } - - public int increment(int) - { - int x, $stack2; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - - $stack2 = x + 1; - return $stack2; - } - } - /* - "specialinvoke this.()>()", - "virtualinvoke this.(x)", - "virtualinvoke this.(a)" - are JInvokeStmts. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void print(int x){ - int a = increment(x); - System.out.println(a); - a = increment(a); - System.out.println(a); - } - public int increment(int x){ - return x + 1; - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public print(I)V - L0 - LINENUMBER 5 L0 - ALOAD 0 - ILOAD 1 - INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I - ISTORE 2 - L1 - LINENUMBER 6 L1 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 2 - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L2 - LINENUMBER 7 L2 - ALOAD 0 - ILOAD 2 - INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I - ISTORE 2 - L3 - LINENUMBER 8 L3 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 2 - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L4 - LINENUMBER 9 L4 - RETURN - L5 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0 - LOCALVARIABLE x I L0 L5 1 - LOCALVARIABLE a I L1 L5 2 - MAXSTACK = 2 - MAXLOCALS = 3 - - // access flags 0x1 - public increment(I)I - L0 - LINENUMBER 11 L0 - ILOAD 1 - ICONST_1 - IADD - IRETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - LOCALVARIABLE x I L0 L1 1 - MAXSTACK = 2 - MAXLOCALS = 2 - } - ``` - - -##### JAssignStmt -assigns a Value from the right hand-side to the left hand-side. -Left hand-side of an assignment can be a Local referencing a variable (i.e. a Local) or a FieldRef referencing a Field. -Right hand-side of an assignment can be an expression (Expr), a Local, a FieldRef or a Constant. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - this. = 0; - return; - } - - public int updateCounter() - { - target.exercise1.DemoClass this; - int $stack1, $stack2, $stack3; - - this := @this: target.exercise1.DemoClass; - - $stack1 = this.; - $stack2 = $stack1 + 1; - this. = $stack2; - $stack3 = this.; - - return $stack3; - } - } - /* - "this. = 0", - "$stack1 = this.", - "$stack2 = $stack1 + 1" - "this. = $stack2" - "$stack3 = this." - are JAssignStmts. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - private int counter = 0; - public int updateCounter(){ - counter = counter + 1; - return counter; - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x2 - private I counter - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - L1 - LINENUMBER 4 L1 - ALOAD 0 - ICONST_0 - PUTFIELD target/exercise1/DemoClass.counter : I - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - - // access flags 0x1 - public updateCounter()I - L0 - LINENUMBER 6 L0 - ALOAD 0 - ALOAD 0 - GETFIELD target/exercise1/DemoClass.counter : I - ICONST_1 - IADD - PUTFIELD target/exercise1/DemoClass.counter : I - L1 - LINENUMBER 7 L1 - ALOAD 0 - GETFIELD target/exercise1/DemoClass.counter : I - IRETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 3 - MAXLOCALS = 1 - } - ``` - - -##### JIdentityStmt -is semantically like the JAssignStmt and handles assignments of IdentityRef's to make implicit assignments explicit into the StmtGraph. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void DemoClass(int) - { - target.exercise1.DemoClass this; - int counter; - - this := @this: target.exercise1.DemoClass; - counter := @parameter0: int; - this. = counter; - return; - } - } - /* - "this := @this: target.exercise1.DemoClass" and - "counter := @parameter0: int" are JIdentityStmts - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - private int counter; - public void DemoClass(int counter){ - this.counter = counter; - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x2 - private I counter - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public DemoClass(I)V - L0 - LINENUMBER 6 L0 - ALOAD 0 - ILOAD 1 - PUTFIELD target/exercise1/DemoClass.counter : I - L1 - LINENUMBER 7 L1 - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - LOCALVARIABLE counter I L0 L2 1 - MAXSTACK = 2 - MAXLOCALS = 2 - } - ``` - - -#####JEnterMonitorStmt & JExitMonitorStmt -marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - this. = 0; - return; - } - - public int updateCounter() - { - target.exercise1.DemoClass this; - int $stack4, $stack5, $stack7; - java.lang.Throwable $stack8; - - this := @this: target.exercise1.DemoClass; - - entermonitor this; - - label1: - $stack4 = this.; - $stack5 = $stack4 + 1; - this. = $stack5; - - exitmonitor this; - - label2: - goto label5; - - label3: - $stack8 := @caughtexception; - - exitmonitor this; - - label4: - throw $stack8; - - label5: - $stack7 = this.; - return $stack7; - - catch java.lang.Throwable from label1 to label2 with label3; - catch java.lang.Throwable from label3 to label4 with label3; - } - } - /* - "entermonitor this" is JEnterMonitorStmt. - "exitmonitor this" is JExitMonitorStmt. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - private int counter = 0; - public int updateCounter(){ - synchronized (this) { - counter = counter + 1; - } - return counter; - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x2 - private I counter - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - L1 - LINENUMBER 4 L1 - ALOAD 0 - ICONST_0 - PUTFIELD target/exercise1/DemoClass.counter : I - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - - // access flags 0x1 - public updateCounter()I - TRYCATCHBLOCK L0 L1 L2 null - TRYCATCHBLOCK L2 L3 L2 null - L4 - LINENUMBER 6 L4 - ALOAD 0 - DUP - ASTORE 1 - MONITORENTER - L0 - LINENUMBER 7 L0 - ALOAD 0 - ALOAD 0 - GETFIELD target/exercise1/DemoClass.counter : I - ICONST_1 - IADD - PUTFIELD target/exercise1/DemoClass.counter : I - L5 - LINENUMBER 8 L5 - ALOAD 1 - MONITOREXIT - L1 - GOTO L6 - L2 - FRAME FULL [target/exercise1/DemoClass java/lang/Object] - [java/lang/Throwable] - ASTORE 2 - ALOAD 1 - MONITOREXIT - L3 - ALOAD 2 - ATHROW - L6 - LINENUMBER 9 L6 - FRAME CHOP 1 - ALOAD 0 - GETFIELD target/exercise1/DemoClass.counter : I - IRETURN - L7 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L4 L7 0 - MAXSTACK = 3 - MAXLOCALS = 3 - } - ``` - - -##### JRetStmt -##### JBreakpointStmt -models a Breakpoint set by a Debugger (usually not relevant for static analyses) - - -### Immediate -An Immediate has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). - - -### Type -VoidType - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void voidMethod() - { - java.io.PrintStream $stack1; - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - $stack1 = ; - virtualinvoke $stack1.("In voidMethod()."); - return; - } - } - /* - For the SootMethod - , - returnType is instance of VoidType. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void voidMethod(){ - System.out.println("In voidMethod()."); - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public voidMethod()V - L0 - LINENUMBER 5 L0 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "In voidMethod()." - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L1 - LINENUMBER 6 L1 - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - } - ``` - - -#### PrimaryType -BooleanType, ByteType, CharType, ShortType, IntType, LongType, DoubleType, FloatType - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - - public void display() - { - java.io.PrintStream $stack11, $stack13, $stack15, - $stack17, $stack19, $stack21, $stack23, $stack25; - int $stack12, $stack14, $stack16, $stack18; - long $stack20; - double $stack22; - float $stack24; - target.exercise1.DemoClass this; - boolean $stack26; - - this := @this: target.exercise1.DemoClass; - - $stack11 = ; - - goto label1; - - label1: - $stack26 = 0; - virtualinvoke $stack11.($stack26); - - $stack13 = ; - $stack12 = 127 - 1; - virtualinvoke $stack13.($stack12); - - $stack15 = ; - $stack14 = 97 + 1; - virtualinvoke $stack15.($stack14); - - $stack17 = ; - $stack16 = 1123 + 1; - virtualinvoke $stack17.($stack16); - - $stack19 = ; - $stack18 = 123456 + 1; - virtualinvoke $stack19.($stack18); - - $stack21 = ; - $stack20 = 10L + 1L; - virtualinvoke $stack21.($stack20); - - $stack23 = ; - $stack22 = 10.1 + 1.0; - virtualinvoke $stack23.($stack22); - - $stack25 = ; - $stack24 = 10.1F + 1.0F; - virtualinvoke $stack25.($stack24); - - return; - } - } - /* - The JimpleLocal $stack12, $stack14, $stack16, $stack18 are of IntType. - Similarly, $stack20 is of LongType, $stack22 is of DoubleType and so on. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void display(){ - boolean varBoolean = true; - byte varByte = 127; - char varChar = 'a'; - short varShort = 1123; - int varInt = 123456; - long varLong = 10L; - double varDouble = 10.10; - float varFloat = 10.10f; - - System.out.println(!varBoolean); - System.out.println(varByte-1); - System.out.println(varChar+1); - System.out.println(varShort+1); - System.out.println(varInt+1); - System.out.println(varLong+1); - System.out.println(varDouble+1); - System.out.println(varFloat+1); - - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public display()V - L0 - LINENUMBER 5 L0 - ICONST_1 - ISTORE 1 - L1 - LINENUMBER 6 L1 - BIPUSH 127 - ISTORE 2 - L2 - LINENUMBER 7 L2 - BIPUSH 97 - ISTORE 3 - L3 - LINENUMBER 8 L3 - SIPUSH 1123 - ISTORE 4 - L4 - LINENUMBER 9 L4 - LDC 123456 - ISTORE 5 - L5 - LINENUMBER 10 L5 - LDC 10 - LSTORE 6 - L6 - LINENUMBER 11 L6 - LDC 10.1 - DSTORE 8 - L7 - LINENUMBER 12 L7 - LDC 10.1 - FSTORE 10 - L8 - LINENUMBER 14 L8 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 1 - IFNE L9 - ICONST_1 - GOTO L10 - L9 - FRAME FULL [target/exercise1/DemoClass I I I I I J D F] - [java/io/PrintStream] - ICONST_0 - L10 - FRAME FULL [target/exercise1/DemoClass I I I I I J D F] - [java/io/PrintStream I] - INVOKEVIRTUAL java/io/PrintStream.println (Z)V - L11 - LINENUMBER 15 L11 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 2 - ICONST_1 - ISUB - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L12 - LINENUMBER 16 L12 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 3 - ICONST_1 - IADD - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L13 - LINENUMBER 17 L13 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 4 - ICONST_1 - IADD - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L14 - LINENUMBER 18 L14 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 5 - ICONST_1 - IADD - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L15 - LINENUMBER 19 L15 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LLOAD 6 - LCONST_1 - LADD - INVOKEVIRTUAL java/io/PrintStream.println (J)V - L16 - LINENUMBER 20 L16 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - DLOAD 8 - DCONST_1 - DADD - INVOKEVIRTUAL java/io/PrintStream.println (D)V - L17 - LINENUMBER 21 L17 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - FLOAD 10 - FCONST_1 - FADD - INVOKEVIRTUAL java/io/PrintStream.println (F)V - L18 - LINENUMBER 23 L18 - RETURN - L19 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L19 0 - LOCALVARIABLE varBoolean Z L1 L19 1 - LOCALVARIABLE varByte B L2 L19 2 - LOCALVARIABLE varChar C L3 L19 3 - LOCALVARIABLE varShort S L4 L19 4 - LOCALVARIABLE varInt I L5 L19 5 - LOCALVARIABLE varLong J L6 L19 6 - LOCALVARIABLE varDouble D L7 L19 8 - LOCALVARIABLE varFloat F L8 L19 10 - MAXSTACK = 5 - MAXLOCALS = 11 - } - ``` - - -#### ReferenceType -ClassType, -ArrayType -NullType - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public target.exercise1.DemoClass getObject(target.exercise1.DemoClass) - { - target.exercise1.DemoClass obj, this; - this := @this: target.exercise1.DemoClass; - obj := @parameter0: target.exercise1.DemoClass; - return obj; - } - - public void compute(boolean) - { - int[] b; - java.io.PrintStream $stack5, $stack6; - boolean check; - target.exercise1.DemoClass this; - int i; - null_type r0; - java.lang.NullPointerException soot0; - this := @this: target.exercise1.DemoClass; - check := @parameter0: boolean; - b = newarray (int)[5]; - i = 0; - - label1: - if i >= 5 goto label3; - if check == 0 goto label2; - r0 = (null_type) i; - soot0 = new java.lang.NullPointerException; - specialinvoke soot0.(java.lang.String)> - ("This statement would have triggered an Exception: a[i#1] = r0"); - throw soot0; - - label2: - b[i] = i; - i = i + 1; - goto label1; - - label3: - $stack5 = ; - virtualinvoke $stack5.(b); - $stack6 = ; - virtualinvoke $stack6.(null); - return; - } - } - /* - The JimpleLocal b is of ArrayType, - and JimpleLocal r0 is of NullType. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - - public DemoClass getObject(DemoClass obj){ - return obj; - } - - public void compute(boolean check){ - int a[] = null; - int b[] = new int[5]; - for (int i = 0; i < 5; i++) { - if(check){ - a[i] = i; - } - b[i] = i; - } - System.out.println(b); - System.out.println(a); - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public getObject(Ltarget/exercise1/DemoClass;)Ltarget/exercise1/DemoClass; - L0 - LINENUMBER 6 L0 - ALOAD 1 - ARETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - LOCALVARIABLE obj Ltarget/exercise1/DemoClass; L0 L1 1 - MAXSTACK = 1 - MAXLOCALS = 2 - - // access flags 0x1 - public compute(Z)V - L0 - LINENUMBER 10 L0 - ACONST_NULL - ASTORE 2 - L1 - LINENUMBER 11 L1 - ICONST_5 - NEWARRAY T_INT - ASTORE 3 - L2 - LINENUMBER 12 L2 - ICONST_0 - ISTORE 4 - L3 - FRAME APPEND [[I [I I] - ILOAD 4 - ICONST_5 - IF_ICMPGE L4 - L5 - LINENUMBER 13 L5 - ILOAD 1 - IFEQ L6 - L7 - LINENUMBER 14 L7 - ALOAD 2 - ILOAD 4 - ILOAD 4 - IASTORE - L6 - LINENUMBER 16 L6 - FRAME SAME - ALOAD 3 - ILOAD 4 - ILOAD 4 - IASTORE - L8 - LINENUMBER 12 L8 - IINC 4 1 - GOTO L3 - L4 - LINENUMBER 18 L4 - FRAME CHOP 1 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ALOAD 3 - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V - L9 - LINENUMBER 19 L9 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ALOAD 2 - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V - L10 - LINENUMBER 20 L10 - RETURN - L11 - LOCALVARIABLE i I L3 L4 4 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L11 0 - LOCALVARIABLE check Z L0 L11 1 - LOCALVARIABLE a [I L1 L11 2 - LOCALVARIABLE b [I L2 L11 3 - MAXSTACK = 3 - MAXLOCALS = 5 - } - ``` - - -#### Local -```jimple -i0 -``` -A Local is a variable and its scope is inside its method i.e. no referencing from outside a method. -Values can be assigned to Locals via JIdentityStmt or JAssignStmt. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void compute() - { - java.io.PrintStream $stack2, $stack3; - target.exercise1.DemoClass this; - int local#2; - - this := @this: target.exercise1.DemoClass; - $stack2 = ; - virtualinvoke $stack2.(1); - - local#2 = this.; - $stack3 = ; - virtualinvoke $stack3.(local#2); - return; - } - } - /* - $stack2, this, $stack3, local#2 are all JimpleLocal. - - "this := @this: target.exercise1.DemoClass" is JIdentityStmt - - "$stack2 = ", - "local#2 = this.", - "$stack3 = " - are JAssignStmt - - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - - private int global; - - public void compute(){ - int local; - local = 1; - System.out.println(local); - local = this.global; - System.out.println(local); - } - } - ``` - -=== "Byte Code" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x2 - private I global - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public compute()V - L0 - LINENUMBER 9 L0 - ICONST_1 - ISTORE 1 - L1 - LINENUMBER 10 L1 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 1 - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L2 - LINENUMBER 11 L2 - ALOAD 0 - GETFIELD target/exercise1/DemoClass.global : I - ISTORE 1 - L3 - LINENUMBER 12 L3 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 1 - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L4 - LINENUMBER 14 L4 - RETURN - L5 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0 - LOCALVARIABLE local I L1 L5 1 - MAXSTACK = 2 - MAXLOCALS = 2 - } - ``` - - - -#### Constant -represents a value itself. don't confuse it with a variable/Local which has a immutable (i.e. final) attribute. - -There exists a constant entity for every Type - that way all value types can have a representation. - - -### Expr -An expression is a language construct that returns a value. E.g. a binary operation such as addition. - - -### Ref -#### JArrayRef -```jimple -$arr[1] -``` -referencing a position inside an array. - -#### JFieldRef (JStaticFieldRef & JInstanceFieldRef) -```jimple - -// or -r1. -``` -referencing a Field via its FieldSignature and if necessary (i.e. with JInstanceFieldRef) the corresponding Local instance that points to the object instance. - -#### IdentityRef -The IdentityRef makes those implicit special value assignments explicit. - -##### JThisRef -```jimple -@this: package.fruit.Banana -``` -represents the this pointer of the current class. - -##### JCaughtExceptionRef -```jimple -@caughtexception -``` -represents the value of the thrown exception (caught by this exceptionhandler). - -##### JParameterRef -```jimple -i0 := @parameter0 -i1 := @parameter1 -``` -represents a parameter of a method, identified by its index. - diff --git a/mkdocs.yml b/mkdocs.yml index b2a88399d17..8045d12d043 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -14,6 +14,11 @@ nav: - Basics: - Jimple IR: jimple.md + - Jimple Body: jimple-body.md + - Jimple Statements: jimple-stmts.md + - Jimple Types: jimple-types.md + - Jimple Values: jimple-values.md + - BodyInterceptors: bodyinterceptors.md - Callgraph Construction: call-graph-construction.md - Shipped Analyses: advanced-topics.md From 610c531e386851d9254d2d37f2be6c881b52bc0b Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 14:57:33 +0200 Subject: [PATCH 07/23] update doc --- docs/css/customizetheme.css | 15 ++-- docs/jimple-stmts.md | 2 +- docs/overrides/partials/header.html | 106 -------------------------- docs/overrides/partials/outdated.html | 8 ++ 4 files changed, 18 insertions(+), 113 deletions(-) delete mode 100644 docs/overrides/partials/header.html create mode 100644 docs/overrides/partials/outdated.html diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index e3652403932..56d694ec604 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -83,6 +83,8 @@ .md-typeset code { padding:0.2em; margin:0.2em; + font-size: 10pt; + background-color: #FCFCFC; } .tabbed-set.tabbed-alternate{ @@ -115,19 +117,20 @@ html .md-footer-meta.md-typeset a{ } .highlighttable{ + border-left:1px solid rgba(255,140,0, 0.1); border-bottom:1px solid rgba(255,140,0, 0.1); border-right:1px solid rgba(255,140,0, 0.1); } .highlighttable .linenos{ - background-color:#EEE; - border-color: rgba(255,140,0, 0.1); -} - -.md-typeset code { - background-color: #FFF; + background-color: #FCFCFC;; + font-size: 10pt; } #developedBy{ font-size: 11pt; +} + +.tooltip{ + color: rgba(255,140,0, 0.8); } \ No newline at end of file diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index 0fb058a1665..ea068877bc2 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1,5 +1,5 @@ # Jimple Stmt ("Statements") -The main piece of Jimple is a Statement (Stmt). [**Stmts**]{formerly known as Units} represent that can be executed by the JVM. +[Stmts]{formerly known as Units} represent instructions of the JVM. ## Branching Statements diff --git a/docs/overrides/partials/header.html b/docs/overrides/partials/header.html deleted file mode 100644 index cf74cabac7e..00000000000 --- a/docs/overrides/partials/header.html +++ /dev/null @@ -1,106 +0,0 @@ - - - -{% set class = "md-header" %} -{% if "navigation.tabs.sticky" in features %} -{% set class = class ~ " md-header--shadow md-header--lifted" %} -{% elif "navigation.tabs" not in features %} -{% set class = class ~ " md-header--shadow" %} -{% endif %} - - -
- - - - {% if "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} -
diff --git a/docs/overrides/partials/outdated.html b/docs/overrides/partials/outdated.html new file mode 100644 index 00000000000..36a4967d7de --- /dev/null +++ b/docs/overrides/partials/outdated.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block outdated %} +You're not viewing the latest version. + + Click here to go to latest version. + +{% endblock %} \ No newline at end of file From f2f8fcb220ed85ecd0480f7e457037c49d31a867 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 15:52:59 +0200 Subject: [PATCH 08/23] improve readability --- docs/css/customizetheme.css | 17 +++++++++-- docs/getting-started.md | 59 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index 56d694ec604..273eec6f066 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -116,10 +116,21 @@ html .md-footer-meta.md-typeset a{ border:none; } + +.admonition .highlighttable{ + margin: 0; + border: none; +} +.md-typeset .admonition .highlighttable, .md-typeset details .highlighttable{ + +} + .highlighttable{ - border-left:1px solid rgba(255,140,0, 0.1); - border-bottom:1px solid rgba(255,140,0, 0.1); - border-right:1px solid rgba(255,140,0, 0.1); + border:1px solid rgba(255,140,0, 0.1); +} + +.admonition .highlighttable, .tabbed-set .highlighttable{ + border-top:none; } .highlighttable .linenos{ diff --git a/docs/getting-started.md b/docs/getting-started.md index acb45e7ece4..8dd6b44160b 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,20 +1,10 @@ -# General Usage of SootUp -This page walks you through the core data structures, as well as shows how to get started with SootUp. - -## The core datastructures +# First Steps with SootUp Before you get started with the SootUp library, it helps to learn about the following core data structures: -- `AnalysisInputLocation`: points to the target code to be analyzed. - -!!! info "Soot Equivalent" - - It corresponds to the `cp` option, which specifies the classpath for Soot to find classes to be analyzed. - -- `View`: presents the code/classes under analysis. +- [`AnalysisInputLocation`]{It corresponds to the `cp` option, which specifies the classpath for Soot to find classes to be analyzed.} + : points to the target code to be analyzed. -!!! info "Soot Equivalent" - - It corresponds to the `Scene` class, but it is not a singleton. So it is possible to instantiate multiple views simultaneously. +- [`View`]{Corresponds to the `Scene` class, but it is not a singleton. So it is possible to instantiate multiple views simultaneously.}: presents the code/classes under analysis. - `SootClass`: represents a class loaded into the `View`. @@ -56,7 +46,7 @@ If you have access to the source code, it is also possible to create a view for If you have a [Jimple](../jimple) file, you can create a view for analyzing jimple code directly. Following example shows how to create a view for analyzing jimple code. -!!! example "Create a project to analyze jimple code" +!!! example "Create a view to analyze jimple code" ~~~java Path pathToJimple = Paths.get("path2Jimple"); @@ -132,17 +122,25 @@ Once we have a `ClassType` that identifies the `HelloWorld` class, we can use it Like the classes, methods also have an identifier which we call `MethodSignature`. For instance, we can define the method signature for identifying the `main` method of the `HelloWorld` class as follows: !!! example "Defining a MethodSignature" - - ```java - MethodSignature methodSignature = - view - .getIdentifierFactory() - .getMethodSignature( - "main", // method name - classType, - "void", // return type - Collections.singletonList("java.lang.String[]")); // args - ``` + === "Pure" + ```java + MethodSignature methodSignature = + view + .getIdentifierFactory() + .getMethodSignature( + "main", // method name + classType, + "void", // return type + Collections.singletonList("java.lang.String[]")); // args + ``` + === "Parse from String" + ```java + MethodSignature methodSignature = + view + .getIdentifierFactory() + .parseMethodSignature( + ""); + ``` Once we have a `MethodSignature` that identifies the `main` method of the `HelloWorld` class, we can use it to retrieve the corresponding `SootMethod` object from the `view` as shown below: @@ -160,7 +158,8 @@ Alternatively, we can also retrieve a `SootMethod` from `SootClass` that contain !!! example "Retrieving a SootMethod from a SootClass" ```java - Optional opt = sootClass.getMethod(methodSignature.getSubSignature()); + MethodSubSignature mss = methodSignature.getSubSignature() + Optional opt = sootClass.getMethod(mss); if(opt.isPresent()){ JavaSootMethod method = opt.get(); @@ -174,11 +173,11 @@ Each `SootMethod` contains a Control-Flow Graph (CFG) which is represented via t !!! example "Retrieving the CFG of a SootMethod" ```java - sootMethod.getBody().getStmts(); + sootMethod.getBody().getStmtGraph(); ``` -!!! info "Access or Download all of the code used above" +!!! info "Access a complete example of the code used above" - [BasicSetup.java](https://github.com/secure-software-engineering/soot-reloaded/blob/develop/sootup.examples/src/test/java/sootup/examples/basicSetup/BasicSetup.java) + Download [BasicSetup.java](https://github.com/secure-software-engineering/soot-reloaded/blob/develop/sootup.examples/src/test/java/sootup/examples/basicSetup/BasicSetup.java) From 365160f2e911a8bf908d06acd39782646362875c Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Mon, 17 Jun 2024 16:47:44 +0200 Subject: [PATCH 09/23] fix ci --- .github/workflows/gh-pages.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 9aefa61be04..463ccc35a2b 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -64,8 +64,8 @@ jobs: git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - # sanitive head_ref name - - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^([[:alnum:]_.-]/_/g"" )" >> $GITHUB_ENV + # sanitize head_ref name + - run: echo "DOC_VERSION_NAME=$(echo ${{ github.head_ref }} | sed "s/[^([[:alnum:]_.-]/_/g" )" >> $GITHUB_ENV # on push to develop branch - keep a doc around for develop to show the current state - name: deploy doc in subdirectory From c6e176b4615cf8e345cc77a89d7d7727e443db97 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 08:06:22 +0200 Subject: [PATCH 10/23] progress --- docs/css/customizetheme.css | 13 +- docs/jimple-stmts.md | 537 +++++++++--------- docs/jimple.md | 8 +- docs/tool_ux.md | 14 +- .../jimple/javabytecode/stmt/JRetStmt.java | 4 +- 5 files changed, 299 insertions(+), 277 deletions(-) diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index 273eec6f066..2ecd037a9a7 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -11,6 +11,10 @@ --md-accent-fg-color: rgba(255,140,0, 1); } +.md-typeset{ + font-size: 12pt; +} + .md-typeset a { color: rgba(255,140,0, 0.8); } @@ -46,6 +50,8 @@ } .md-typeset .admonition, .md-typeset details { border-color: rgba(255,140,0, 1); + box-shadow: none; + } .md-nav label.md-nav__title{ @@ -90,6 +96,7 @@ .tabbed-set.tabbed-alternate{ background: rgba(255,140,0, 0.1); color: rgba(255,140,0, 1); + margin-bottom: 3em; } .md-typeset .tabbed-labels>label>[href]:first-child{ @@ -116,7 +123,6 @@ html .md-footer-meta.md-typeset a{ border:none; } - .admonition .highlighttable{ margin: 0; border: none; @@ -127,6 +133,7 @@ html .md-footer-meta.md-typeset a{ .highlighttable{ border:1px solid rgba(255,140,0, 0.1); + border-top: 6px solid rgba(255,140,0, 0.1); } .admonition .highlighttable, .tabbed-set .highlighttable{ @@ -144,4 +151,8 @@ html .md-footer-meta.md-typeset a{ .tooltip{ color: rgba(255,140,0, 0.8); +} + +p{ + margin-bottom:1.5em; } \ No newline at end of file diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index ea068877bc2..6066ae39f60 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1,12 +1,16 @@ # Jimple Stmt ("Statements") [Stmts]{formerly known as Units} represent instructions of the JVM. +Stmts can be roughly grouped by the amount of successors (in the `StmtGraph` of a `Body` of a `Method`). +- A `FallsThroughStmt` has always one successor - it basically represents `program counter++`. +- A `BranchingStmt` can have one, two or even n successors. +- All others (neither FallsThrough nor BranchingStmt) have no successors and therefore end the execution of the current method. -## Branching Statements +## Branching Stmts A BranchingStmt's job is to model the jumps or conditional branching flow between Stmts. ##### JGotoStmt -for unconditional flow. +represents unconditional jumps to another Stmt. === "Jimple" @@ -118,8 +122,9 @@ for unconditional flow. ``` ##### JIfStmt -for conditional flow depending on boolean Expression (AbstractConditionExpr) so they have two successor Stmt's. -note: The JIfStmt is also a FallsthroughStmt if the branching condition is not met. +For conditional jumps depending on the result of the conditional expression `AbstractConditionExpr` which needs to have boolean result. +If the conditional expression is false, the next Stmt is the successor as the JIFStmt is also a `FallsthroughStmt`. +Therefore, the JIfStmt has two successor Stmt's. === "Jimple" @@ -237,8 +242,6 @@ note: The JIfStmt is also a FallsthroughStmt if the branching condition is not m ##### JSwitchStmt for conditional flow that behaves like a switch-case. It has #numberOfCaseLabels+1 (for default) successor Stmt's. -All other Stmts are not manipulating the flow, which means they have a single successor Stmt as long as they are not exiting the flow inside a method. - === "Jimple" ```jimple @@ -402,264 +405,8 @@ All other Stmts are not manipulating the flow, which means they have a single su } ``` -## FallsThrough Statements -The execution of a FallsthroughStmt goes on with the following Stmt (when no exception was thrown). - -##### JReturnStmt & JReturnVoidStmt -They end the execution/flow inside the current method and return (a value) to its caller. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public int increment(int) - { - int x, $stack2; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - - $stack2 = x + 1; - return $stack2; - } - - public void print() - { - java.io.PrintStream $stack1; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - $stack1 = ; - virtualinvoke $stack1.("Inside method print"); - return; - } - } - /* - "return $stack2" is JReturnStmt. - "return" is JReturnVoidStmt. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public int increment(int x){ - return x + 1; - } - public void print(){ - System.out.println("Inside method print"); - } - } - ``` - -=== "Bytecode" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public increment(I)I - L0 - LINENUMBER 5 L0 - ILOAD 1 - ICONST_1 - IADD - IRETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - LOCALVARIABLE x I L0 L1 1 - MAXSTACK = 2 - MAXLOCALS = 2 - - // access flags 0x1 - public print()V - L0 - LINENUMBER 8 L0 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Inside method print" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L1 - LINENUMBER 9 L1 - RETURN - L2 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 - MAXSTACK = 2 - MAXLOCALS = 1 - } - ``` - - -##### JThrowStmt -Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler. - - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void divideExample(int, int) - { - int y, x, $stack6; - java.lang.StringBuilder $stack3, $stack5, $stack7; - java.io.PrintStream $stack4; - java.lang.String $stack8; - java.lang.RuntimeException $stack9; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - y := @parameter1: int; - - if y != 0 goto label1; - - $stack9 = new java.lang.RuntimeException; - specialinvoke $stack9.(java.lang.String)>("Divide by zero error"); - throw $stack9; - - label1: - $stack4 = ; - $stack3 = new java.lang.StringBuilder; - specialinvoke $stack3.()>(); - - $stack5 = virtualinvoke $stack3.("Divide result : "); - $stack6 = x / y; - $stack7 = virtualinvoke $stack5.($stack6); - $stack8 = virtualinvoke $stack7.(); - - virtualinvoke $stack4.($stack8); - return; - } - } - /* - "throw $stack9" is JThrowStmt. - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void divideExample(int x, int y){ - if(y == 0){ - throw new RuntimeException("Divide by zero error"); - } - System.out.println("Divide result : " + x / y); - } - } - ``` - -=== "Bytecode" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public divideExample(II)V - L0 - LINENUMBER 5 L0 - ILOAD 2 - IFNE L1 - L2 - LINENUMBER 6 L2 - NEW java/lang/RuntimeException - DUP - LDC "Divide by zero error" - INVOKESPECIAL java/lang/RuntimeException. - (Ljava/lang/String;)V - ATHROW - L1 - LINENUMBER 8 L1 - FRAME SAME - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - NEW java/lang/StringBuilder - DUP - INVOKESPECIAL java/lang/StringBuilder. ()V - LDC "Divide result : " - INVOKEVIRTUAL java/lang/StringBuilder.append - (Ljava/lang/String;)Ljava/lang/StringBuilder; - ILOAD 1 - ILOAD 2 - IDIV - INVOKEVIRTUAL java/lang/StringBuilder.append - (I)Ljava/lang/StringBuilder; - INVOKEVIRTUAL java/lang/StringBuilder.toString - ()Ljava/lang/String; - INVOKEVIRTUAL java/io/PrintStream.println - (Ljava/lang/String;)V - L3 - LINENUMBER 9 L3 - RETURN - L4 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 - LOCALVARIABLE x I L0 L4 1 - LOCALVARIABLE y I L0 L4 2 - MAXSTACK = 4 - MAXLOCALS = 3 - } - ``` - +## FallsThrough Stmts +The execution of a FallsthroughStmt goes on with the following Stmt (if no exception was thrown). ##### JInvokeStmt transfers the control flow to another method until the called method returns. @@ -1160,7 +907,265 @@ marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt. } ``` - ##### JRetStmt +// TODO: [java 1.6 spec](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret) + ##### JBreakpointStmt -models a Breakpoint set by a Debugger (usually not relevant for static analyses) +models a Breakpoint set by a Debugger. Therefore, not really relevant for static analyses but useful for code generation. + +## Other Stmts + +##### JReturnStmt & JReturnVoidStmt +They end the execution/flow inside the current method and return (a value) to its caller. + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public int increment(int) + { + int x, $stack2; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + + $stack2 = x + 1; + return $stack2; + } + + public void print() + { + java.io.PrintStream $stack1; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + $stack1 = ; + virtualinvoke $stack1.("Inside method print"); + return; + } + } + /* + "return $stack2" is JReturnStmt. + "return" is JReturnVoidStmt. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public int increment(int x){ + return x + 1; + } + public void print(){ + System.out.println("Inside method print"); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public increment(I)I + L0 + LINENUMBER 5 L0 + ILOAD 1 + ICONST_1 + IADD + IRETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + LOCALVARIABLE x I L0 L1 1 + MAXSTACK = 2 + MAXLOCALS = 2 + + // access flags 0x1 + public print()V + L0 + LINENUMBER 8 L0 + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + LDC "Inside method print" + INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V + L1 + LINENUMBER 9 L1 + RETURN + L2 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0 + MAXSTACK = 2 + MAXLOCALS = 1 + } + ``` + + +##### JThrowStmt +Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler. + + +=== "Jimple" + + ```jimple + public class target.exercise1.DemoClass extends java.lang.Object + { + public void () + { + target.exercise1.DemoClass this; + this := @this: target.exercise1.DemoClass; + specialinvoke this.()>(); + return; + } + + public void divideExample(int, int) + { + int y, x, $stack6; + java.lang.StringBuilder $stack3, $stack5, $stack7; + java.io.PrintStream $stack4; + java.lang.String $stack8; + java.lang.RuntimeException $stack9; + target.exercise1.DemoClass this; + + this := @this: target.exercise1.DemoClass; + x := @parameter0: int; + y := @parameter1: int; + + if y != 0 goto label1; + + $stack9 = new java.lang.RuntimeException; + specialinvoke $stack9.(java.lang.String)>("Divide by zero error"); + throw $stack9; + + label1: + $stack4 = ; + $stack3 = new java.lang.StringBuilder; + specialinvoke $stack3.()>(); + + $stack5 = virtualinvoke $stack3.("Divide result : "); + $stack6 = x / y; + $stack7 = virtualinvoke $stack5.($stack6); + $stack8 = virtualinvoke $stack7.(); + + virtualinvoke $stack4.($stack8); + return; + } + } + /* + "throw $stack9" is JThrowStmt. + */ + ``` + +=== "Java" + + ```java + package target.exercise1; + + public class DemoClass { + public void divideExample(int x, int y){ + if(y == 0){ + throw new RuntimeException("Divide by zero error"); + } + System.out.println("Divide result : " + x / y); + } + } + ``` + +=== "Bytecode" + + ``` + // class version 52.0 (52) + // access flags 0x21 + public class target/exercise1/DemoClass { + + // compiled from: DemoClass.java + + // access flags 0x1 + public ()V + L0 + LINENUMBER 3 L0 + ALOAD 0 + INVOKESPECIAL java/lang/Object. ()V + RETURN + L1 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 + MAXSTACK = 1 + MAXLOCALS = 1 + + // access flags 0x1 + public divideExample(II)V + L0 + LINENUMBER 5 L0 + ILOAD 2 + IFNE L1 + L2 + LINENUMBER 6 L2 + NEW java/lang/RuntimeException + DUP + LDC "Divide by zero error" + INVOKESPECIAL java/lang/RuntimeException. + (Ljava/lang/String;)V + ATHROW + L1 + LINENUMBER 8 L1 + FRAME SAME + GETSTATIC java/lang/System.out : Ljava/io/PrintStream; + NEW java/lang/StringBuilder + DUP + INVOKESPECIAL java/lang/StringBuilder. ()V + LDC "Divide result : " + INVOKEVIRTUAL java/lang/StringBuilder.append + (Ljava/lang/String;)Ljava/lang/StringBuilder; + ILOAD 1 + ILOAD 2 + IDIV + INVOKEVIRTUAL java/lang/StringBuilder.append + (I)Ljava/lang/StringBuilder; + INVOKEVIRTUAL java/lang/StringBuilder.toString + ()Ljava/lang/String; + INVOKEVIRTUAL java/io/PrintStream.println + (Ljava/lang/String;)V + L3 + LINENUMBER 9 L3 + RETURN + L4 + LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0 + LOCALVARIABLE x I L0 L4 1 + LOCALVARIABLE y I L0 L4 2 + MAXSTACK = 4 + MAXLOCALS = 3 + } + ``` diff --git a/docs/jimple.md b/docs/jimple.md index a0ffe406f2e..9e90f7c7dad 100644 --- a/docs/jimple.md +++ b/docs/jimple.md @@ -10,7 +10,7 @@ For this purpose Jimple was designed as a representation of JVM bytecode which i To learn more about jimple, refer to the [thesis](https://courses.cs.washington.edu/courses/cse501/01wi/project/sable-thesis.pdf) by Raja Vallee-Rai. -It might help to visualize how the Jimple version of a Java code looks like. Have a look at the following example on the `HelloWorld` class. +Lets have a look at the following Jimple code representing Java code of a `HelloWorld` class. === "Jimple" @@ -95,6 +95,12 @@ It might help to visualize how the Jimple version of a Java code looks like. Hav } ``` +The Java Sourcecode is the easiest representation - So why all the fuzz and just use that? +Sometimes we have no access to the sourcecode but have a binary with the bytecode. +For most People reading bytecode is not that intuitive. So SootUp generates Jimple from the bytecode. +Jimple is very verbose, but makes everything explicit, that the JVM does implicitly and transforms the stack-machine strategy by a register-machine strategy i.e. Variable (`Local`) handling . + + ## Jimple Grammar Structure Jimple mimics the JVMs class file structure. Therefore it is object oriented. diff --git a/docs/tool_ux.md b/docs/tool_ux.md index 8528055cd3d..730979ba32e 100644 --- a/docs/tool_ux.md +++ b/docs/tool_ux.md @@ -25,12 +25,12 @@ Dependencies: ### Java Code -```java - -class SootUpConfiguration{ - // TODO incorporate -} - -``` + ```java + + class SootUpConfiguration{ + // TODO incorporate + } + + ``` We are happy if you steal the following code to create a tool where the setup is just simple. diff --git a/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java b/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java index d2e1fcc36a7..d62b7a2f0fa 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java +++ b/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java @@ -34,8 +34,8 @@ import sootup.core.util.printer.StmtPrinter; /** - * Represents the deprecated JVM ret statement - which is used in JSR Context - which - * is deprecated as well + * Represents the deprecated JVM ret statement (< java 1.6) - which is used in JSR Context - which + * is deprecated as well. */ public final class JRetStmt extends AbstractStmt implements FallsThroughStmt { From ad06e076f90325e4130a7bf7cd6694e5ba3ae77e Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 09:41:16 +0200 Subject: [PATCH 11/23] more doc --- docs/analysisinputlocations.md | 14 ++-- docs/css/customizetheme.css | 13 ++- docs/jimple-body.md | 12 +-- docs/jimple-stmts.md | 60 +++++++------- docs/jimple-types.md | 46 ++++++----- docs/jimple-values.md | 21 +++-- docs/jimple.md | 147 ++------------------------------- 7 files changed, 99 insertions(+), 214 deletions(-) diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md index 520dc5d3890..f64da9983af 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinputlocations.md @@ -2,23 +2,23 @@ An AnalysisInputLocation tells SootUp what code input it should analyze. ### Java Runtime -- Java <9: DefaultRTJaAnalysisInputLocation current rt.jar (or point to any rt.jar as its just a usual .jar file) -- Java >8: JRTFilesystemAnalysisInputLocation +- Java <9: `DefaultRTJaAnalysisInputLocation` current rt.jar (or point to any rt.jar as its just a usual .jar file) +- Java >8: `JRTFilesystemAnalysisInputLocation` If you have errors like Java.lang.String, Java.lang.Object, ... you are most likely missing this AnalysisInput. ### Java Bytecode .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). +- `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 -- OTFCompileAnalysisInputLocation - you can point directly to .java files or pass a String with Java sourcecode -- JavaSourcePathInputLocation - points to a directory that is the root source directory (containing the package directory structure) +- `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 -- JimpleAnalysisInputLocation - needs a Path to a .jimple file or a directory. +- `JimpleAnalysisInputLocation` - needs a Path to a .jimple file or a directory. ### Android Bytecode .dex -- ApkAnalysisInputLocation - currenlty uses dex2jar internally - SootUp solution is WIP! +- `ApkAnalysisInputLocation` - currenlty uses dex2jar internally - SootUp solution is WIP! ### Java cli arguments to configure SootUp diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index 2ecd037a9a7..ac31584dcce 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -37,7 +37,7 @@ } .md-typeset .admonition, .md-typeset .admonition.info, .md-typeset .admonition.example, .md-typeset .admonition{ - border-color: rgba(255,140,0, 0.2); + border-color: rgba(255,140,0, 0.1); margin-bottom: 3em; } @@ -46,7 +46,8 @@ } .md-typeset .admonition>.admonition-title, .md-typeset .admonition>.admonition-title{ - background: rgba(255,140,0, 0.2); + background: rgba(255,140,0, 0.1); + color: rgba(255,140,0, 1); } .md-typeset .admonition, .md-typeset details { border-color: rgba(255,140,0, 1); @@ -82,6 +83,14 @@ padding-left: 2em; } +.md-sidebar.md-sidebar--secondary .md-nav__item a { + padding: 0; +} + +.md-sidebar.md-sidebar--secondary .md-nav__item .md-nav{ + padding-bottom: 1em; +} + .md-search__form{ background: #EEE; } diff --git a/docs/jimple-body.md b/docs/jimple-body.md index 10ae286516d..39ed9a06dd3 100644 --- a/docs/jimple-body.md +++ b/docs/jimple-body.md @@ -1,6 +1,6 @@ -# Jimple MethodBody -A Methodbody consists of the Modifiers and its StmtGraph - SootUps Control Flow Graph Structure. -The StmtGraph organizes the flow of [Stmts](jimple-stmts.md). +# Jimple Body +A SootMethod `Body` consists of the `Modifiers` and its `StmtGraph` - SootUps Control Flow Graph Structure. +The StmtGraph models the flow of [Stmts](jimple-stmts.md). ### Control Flow Graph - unexceptional flow -> like FallsThroughStmts and BranchingStmts for if,goto etc. @@ -11,10 +11,12 @@ Learn more about the types of [Stmts](jimple-stmts.md). ### Traps A Trap is a mechanism to model exceptional flow. +A Trap represents the try-catch (finally) construct and therefore defines the type of the caught exception, the try-catch range (from-to) and the actual code that handles the exception (handler). +In serialized(!) Jimple Labels are used to denote from,to and handler Stmts. === "Jimple" - ```jimple + ```jimple hl_lines="39" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -57,7 +59,7 @@ A Trap is a mechanism to model exceptional flow. } } /* - By calling getTraps() method, we can get the Trap. + By calling getTraps() method, we can get the Traip chain. For the above jimple code, we have the below trap: Trap : begin : $stack5 = diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index 6066ae39f60..2a5f8a8cf22 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1,5 +1,7 @@ # Jimple Stmt ("Statements") [Stmts]{formerly known as Units} represent instructions of the JVM. +Jimple is a 3-address form code so there are max 3 operands used in a ("manipulating") Stmt - i.e. this does not apply to invokes as this is just operand/parameter passing. + Stmts can be roughly grouped by the amount of successors (in the `StmtGraph` of a `Body` of a `Method`). - A `FallsThroughStmt` has always one successor - it basically represents `program counter++`. @@ -9,12 +11,12 @@ Stmts can be roughly grouped by the amount of successors (in the `StmtGraph` of ## Branching Stmts A BranchingStmt's job is to model the jumps or conditional branching flow between Stmts. -##### JGotoStmt +### JGotoStmt represents unconditional jumps to another Stmt. === "Jimple" - ```jimple + ```jimple hl_lines="18 22" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -121,14 +123,14 @@ represents unconditional jumps to another Stmt. } ``` -##### JIfStmt +### JIfStmt For conditional jumps depending on the result of the conditional expression `AbstractConditionExpr` which needs to have boolean result. If the conditional expression is false, the next Stmt is the successor as the JIFStmt is also a `FallsthroughStmt`. Therefore, the JIfStmt has two successor Stmt's. === "Jimple" - ```jimple + ```jimple hl_lines="19" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -239,12 +241,12 @@ Therefore, the JIfStmt has two successor Stmt's. } ``` -##### JSwitchStmt +### JSwitchStmt for conditional flow that behaves like a switch-case. It has #numberOfCaseLabels+1 (for default) successor Stmt's. === "Jimple" - ```jimple + ```jimple hl_lines="20-25" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -408,12 +410,12 @@ for conditional flow that behaves like a switch-case. It has #numberOfCaseLabels ## FallsThrough Stmts The execution of a FallsthroughStmt goes on with the following Stmt (if no exception was thrown). -##### JInvokeStmt +### JInvokeStmt transfers the control flow to another method until the called method returns. === "Jimple" - ```jimple + ```jimple hl_lines="7 20 22 24 26" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -433,17 +435,13 @@ transfers the control flow to another method until the called method returns. this := @this: target.exercise1.DemoClass; x := @parameter0: int; - a = virtualinvoke this.(x); + a = virtualinvoke this.(x); $stack4 = ; - virtualinvoke $stack4.(a); + virtualinvoke $stack4.(a); - a = virtualinvoke this.(a); + a = virtualinvoke this.(a); $stack6 = ; - virtualinvoke $stack6.(a); + virtualinvoke $stack6.(a); return; } @@ -558,14 +556,14 @@ transfers the control flow to another method until the called method returns. ``` -##### JAssignStmt +### JAssignStmt assigns a Value from the right hand-side to the left hand-side. Left hand-side of an assignment can be a Local referencing a variable (i.e. a Local) or a FieldRef referencing a Field. Right hand-side of an assignment can be an expression (Expr), a Local, a FieldRef or a Constant. === "Jimple" - ```jimple + ```jimple hl_lines="8 19-22" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -668,12 +666,16 @@ Right hand-side of an assignment can be an expression (Expr), a Local, a FieldRe ``` -##### JIdentityStmt -is semantically like the JAssignStmt and handles assignments of IdentityRef's to make implicit assignments explicit into the StmtGraph. +### JIdentityStmt +is similar to the `JAssignStmt` and but handles assignments of `IdentityRef`s to make implicit assignments explicit into the `StmtGraph`. + +- Assigns parameters to a `Local` via `JParameterRef` like `@parameter0: int` refering to the first argument of the method (which is of Type int in this case). +- Assigns exceptions to a `Local` via `JCaughtExceptionRef` like `@caughtexception: java.lang.NullpointerException` +- Assigns the `this` Variable to a `Local` via a `JThisRef` === "Jimple" - ```jimple + ```jimple hl_lines="16 17" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -757,12 +759,12 @@ is semantically like the JAssignStmt and handles assignments of IdentityRef's to ``` -#####JEnterMonitorStmt & JExitMonitorStmt +###JEnterMonitorStmt & JExitMonitorStmt marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt. === "Jimple" - ```jimple + ```jimple hl_lines="20 27 35" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -907,20 +909,20 @@ marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt. } ``` -##### JRetStmt +### JRetStmt // TODO: [java 1.6 spec](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.ret) -##### JBreakpointStmt +### JBreakpointStmt models a Breakpoint set by a Debugger. Therefore, not really relevant for static analyses but useful for code generation. ## Other Stmts -##### JReturnStmt & JReturnVoidStmt +### JReturnStmt & JReturnVoidStmt They end the execution/flow inside the current method and return (a value) to its caller. === "Jimple" - ```jimple + ```jimple hl_lines="20 32" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -1029,13 +1031,13 @@ They end the execution/flow inside the current method and return (a value) to it ``` -##### JThrowStmt +### JThrowStmt Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler. === "Jimple" - ```jimple + ```jimple hl_lines="29" public class target.exercise1.DemoClass extends java.lang.Object { public void () diff --git a/docs/jimple-types.md b/docs/jimple-types.md index fc073396599..1cfcff8f327 100644 --- a/docs/jimple-types.md +++ b/docs/jimple-types.md @@ -1,18 +1,20 @@ -#Jimple Types - -#### PrimaryType -- BooleanType -- ByteType -- CharType -- ShortType -- IntType -- LongType -- DoubleType -- FloatType +# Jimple Types +represents primary types i.e. non-reference types and non-void + +### PrimaryType + +- `BooleanType` +- `ByteType` +- `CharType` +- `ShortType` +- `IntType` +- `LongType` +- `DoubleType` +- `FloatType` === "Jimple" - ```jimple + ```jimple hl_lines="14-21" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -257,14 +259,14 @@ ``` -#### ReferenceType -- ClassType -- ArrayType -- NullType +### ReferenceType +- `(Java)ClassType` - represents the type of a Class. +- `ArrayType` - represents an array. +- `NullType` - assignable to one of the other ReferenceTypes. === "Jimple" - ```jimple + ```jimple hl_lines="21 24 26" public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -323,8 +325,8 @@ } } /* - The JimpleLocal b is of ArrayType, - and JimpleLocal r0 is of NullType. + The Local b is of ArrayType, + and Local r0 is of NullType. */ ``` @@ -454,12 +456,12 @@ ``` -#### VoidType -Only used as a possible return type of a method. +### VoidType +Used as a possible return type of a method. === "Jimple" - ```jimple + ```jimple hl_lines="11" public class target.exercise1.DemoClass extends java.lang.Object { public void () diff --git a/docs/jimple-values.md b/docs/jimple-values.md index fa49fd97c8f..ef45d4ecec2 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -130,10 +130,9 @@ Values can be assigned to Locals via JIdentityStmt or JAssignStmt. #### Constant -represents a value itself. don't confuse it with a variable/Local which has a immutable (i.e. final) attribute. - -There exists a constant entity for every Type - that way all value types can have a representation. - +represents an actual value itself like `42` or `"This is a String"`. +Constants are usually assigned to `Local`s or `Ref`s. +There exists a constant entity for every [Primitive Type](jimple-types.md). ### Expr An expression is a language construct that returns a value. E.g. a binary operation such as addition. @@ -146,13 +145,13 @@ $arr[1] ``` referencing a position inside an array. -#### JFieldRef (JStaticFieldRef & JInstanceFieldRef) -```jimple - -// or -r1. -``` -referencing a Field via its FieldSignature and if necessary (i.e. with JInstanceFieldRef) the corresponding Local instance that points to the object instance. +#### JFieldRef +`JFieldRef`s are referencing a `SootField` via its FieldSignature + +- `JStaticFieldRef` like `#!jimple ` +- `JInstanceFieldRef` like `#!jimple r1.` + You can see the JInstanceFieldRef has the corresponding Local instance that points to the instance of the object which is holding the field. + #### IdentityRef The IdentityRef makes those implicit special value assignments explicit. diff --git a/docs/jimple.md b/docs/jimple.md index 9e90f7c7dad..8b86014413f 100644 --- a/docs/jimple.md +++ b/docs/jimple.md @@ -247,9 +247,9 @@ Sidenote: Locals, do not have a signature, since they are referenced within meth } ``` -### Class (or Interface) -A class consists of Fields and Methods. -It is referenced by its ClassType. +### SootClass +A `SootClass` consists of SootFields and SootMethods. +It is referenced by its global identifier the `ClassType` like `java.lang.String`. === "Jimple" @@ -298,9 +298,9 @@ It is referenced by its ClassType. ``` -### Field -A Field is a piece of memory which can store a value that is accessible according to its visibility modifier. -It is referenced by its FieldSignature. +### SootField +A SootField is a piece of memory which can store a value that is accessible according to its visibility modifier. +It is referenced by its FieldSignature like `#!jimple `. === "Jimple" @@ -363,9 +363,9 @@ It is referenced by its FieldSignature. ``` -### Method and its Body +### SootMethod and its Body The interesting part is a method. A method is a "piece of code" that can be executed. -It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control flow graph} that models the sequence of single instructions/statements (Stmts). +It is referenced by its MethodSignature like `#!jimple `. === "Jimple" @@ -461,133 +461,4 @@ It is referenced by its MethodSignature and contains a [**StmtGraph**]{a control } ``` - -### Traps -A Trap is a mechanism to model exceptional flow. - -=== "Jimple" - - ```jimple - public class target.exercise1.DemoClass extends java.lang.Object - { - public void () - { - target.exercise1.DemoClass this; - this := @this: target.exercise1.DemoClass; - specialinvoke this.()>(); - return; - } - - public void divideExample(int, int) - { - int x, y, $stack4; - java.io.PrintStream $stack5, $stack7; - java.lang.Exception $stack6; - target.exercise1.DemoClass this; - - this := @this: target.exercise1.DemoClass; - x := @parameter0: int; - y := @parameter1: int; - - label1: - $stack5 = ; - $stack4 = x / y; - virtualinvoke $stack5.($stack4); - - label2: - goto label4; - - label3: - $stack6 := @caughtexception; - $stack7 = ; - virtualinvoke $stack7.("Exception caught"); - - label4: - return; - - catch java.lang.Exception from label1 to label2 with label3; - } - } - /* - By calling getTraps() method, we can get the Traip chain. - For the above jimple code, we have the below trap: - Trap : - begin : $stack5 = - end : goto [?= return] - handler: $stack6 := @caughtexception - */ - ``` - -=== "Java" - - ```java - package target.exercise1; - - public class DemoClass { - public void divideExample(int x, int y){ - try { - System.out.println(x / y); - }catch (Exception e){ - System.out.println("Exception caught"); - } - } - } - ``` - -=== "Bytecode" - - ``` - // class version 52.0 (52) - // access flags 0x21 - public class target/exercise1/DemoClass { - - // compiled from: DemoClass.java - - // access flags 0x1 - public ()V - L0 - LINENUMBER 3 L0 - ALOAD 0 - INVOKESPECIAL java/lang/Object. ()V - RETURN - L1 - LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0 - MAXSTACK = 1 - MAXLOCALS = 1 - - // access flags 0x1 - public divideExample(II)V - TRYCATCHBLOCK L0 L1 L2 java/lang/Exception - L0 - LINENUMBER 6 L0 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - ILOAD 1 - ILOAD 2 - IDIV - INVOKEVIRTUAL java/io/PrintStream.println (I)V - L1 - LINENUMBER 9 L1 - GOTO L3 - L2 - LINENUMBER 7 L2 - FRAME SAME1 java/lang/Exception - ASTORE 3 - L4 - LINENUMBER 8 L4 - GETSTATIC java/lang/System.out : Ljava/io/PrintStream; - LDC "Exception caught" - INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V - L3 - LINENUMBER 10 L3 - FRAME SAME - RETURN - L5 - LOCALVARIABLE e Ljava/lang/Exception; L4 L3 3 - LOCALVARIABLE this Land Ttarget/exercise1/DemoClass; L0 L5 0 - LOCALVARIABLE x I L0 L5 1 - LOCALVARIABLE y I L0 L5 2 - MAXSTACK = 3 - MAXLOCALS = 4 - } - ``` +More about the [Body](jimple-body.md) of the SootMethod. \ No newline at end of file From cc958adeaa2ac4d4462cd407d84def44ed1ef277 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 09:59:27 +0200 Subject: [PATCH 12/23] improve callgraph examples --- docs/call-graph-construction.md | 44 +++++++++++++++++++-------------- docs/jimple-stmts.md | 2 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/docs/call-graph-construction.md b/docs/call-graph-construction.md index 79d87e55622..e589b5736c9 100644 --- a/docs/call-graph-construction.md +++ b/docs/call-graph-construction.md @@ -43,23 +43,31 @@ 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: -=== "SootUp" +=== "SootUp (performant)" ```java - JavaClassType classTypeA = view.getIdentifierFactory().getClassType("A"); + JavaClassType classTypeA = view.getIdentifierFactory().getClassType("packageNameA.A"); MethodSignature entryMethodSignature = view.getIdentifierFactory() .getMethodSignature( classTypeA, - JavaIdentifierFactory.getInstance() - .getMethodSubSignature( - "calc", VoidType.getInstance(), Collections.singletonList(classTypeA))); + "calc", + VoidType.getInstance(), + Collections.singletonList(classTypeA) + ); ``` - + +=== "SootUp (alternative)" + + ```java + MethodSignature entryMethodSignature = view.getIdentifierFactory().parseMethodSignature(" System.out.println(entryMethodSignature + " may call " + tgt); ``` === "Soot" @@ -90,7 +97,7 @@ You can construct a call graph with CHA as follows: while (targets.hasNext()) { SootMethod tgt = (SootMethod)targets.next(); System.out.println(src + " may call " + tgt); - } + } ``` ## Rapid Type Analysis @@ -100,13 +107,12 @@ You can construct a call graph with RTA as follows: === "SootUp" ```java - CallGraphAlgorithm rta = - new RapidTypeAnalysisAlgorithm(view); + CallGraphAlgorithm rta = new RapidTypeAnalysisAlgorithm(view); - CallGraph cg = - rta.initialize(Collections.singletonList(entryMethodSignature)); + CallGraph cg = rta.initialize(Collections.singletonList(entryMethodSignature)); - System.out.println(cg); + cg.callsFrom(entryMethodSignature).stream() + .forEach(tgt -> System.out.println(entryMethodSignature + " may call " + tgt); ``` === "Soot" @@ -128,6 +134,8 @@ You can construct a call graph with RTA as follows: ``` ## Variable Type Analysis +(**WIP!**) + Variable Type Analysis (VTA) algorithm further refines the call graph that the RTA constructs. It refines RTA by considering only the assigned instantiations of the implementers of an interface, when resolving a method call on an interface. When considering assignments, we usually need to consider **pointer** (points-to) relationship. diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index 2a5f8a8cf22..d739eeb01da 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1,4 +1,4 @@ -# Jimple Stmt ("Statements") +# Jimple Stmt ("Statement") [Stmts]{formerly known as Units} represent instructions of the JVM. Jimple is a 3-address form code so there are max 3 operands used in a ("manipulating") Stmt - i.e. this does not apply to invokes as this is just operand/parameter passing. From 065d77eade513a7b93deeb6d443a70b6a73bf2b2 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 11:16:29 +0200 Subject: [PATCH 13/23] docs --- docs/analysisinputlocations.md | 2 +- docs/jimple-values.md | 5 +++-- docs/{advanced-topics.md => shipped-analyses.md} | 0 docs/{tool_ux.md => tool_setup.md} | 2 +- docs/write_analyses.md | 6 +++++- mkdocs.yml | 4 ++-- .../java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java | 4 ++-- 7 files changed, 14 insertions(+), 9 deletions(-) rename docs/{advanced-topics.md => shipped-analyses.md} (100%) rename docs/{tool_ux.md => tool_setup.md} (95%) diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md index f64da9983af..9c9cb70a1c6 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinputlocations.md @@ -22,4 +22,4 @@ If you have errors like Java.lang.String, Java.lang.Object, ... you are most lik ### Java cli arguments to configure SootUp -We created a [Utility](tool_ux.md) that parses a String of java command line arguments and configures SootUp respectively. \ No newline at end of file +We created a [Utility](tool_setup) that parses a String of java command line arguments and configures SootUp respectively. \ No newline at end of file diff --git a/docs/jimple-values.md b/docs/jimple-values.md index ef45d4ecec2..3da17f8a88f 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -135,8 +135,9 @@ Constants are usually assigned to `Local`s or `Ref`s. There exists a constant entity for every [Primitive Type](jimple-types.md). ### Expr -An expression is a language construct that returns a value. E.g. a binary operation such as addition. - +An expression is a language construct that calculates an operation and returns a value. +E.g. a binary operation `AbstracBinopExpr` such as an addition `a + b`, an `AbstractInvokeExpr` such as `virtualinvoke $stack2.(1);` or an `UnaryExpr` such as `!valid`. +And a bunch more! ### Ref #### JArrayRef diff --git a/docs/advanced-topics.md b/docs/shipped-analyses.md similarity index 100% rename from docs/advanced-topics.md rename to docs/shipped-analyses.md diff --git a/docs/tool_ux.md b/docs/tool_setup.md similarity index 95% rename from docs/tool_ux.md rename to docs/tool_setup.md index 730979ba32e..c4d0f4d96cf 100644 --- a/docs/tool_ux.md +++ b/docs/tool_setup.md @@ -1,4 +1,4 @@ -# From Prototype to user friendly tool +# From Prototype to a user friendly tool `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.. diff --git a/docs/write_analyses.md b/docs/write_analyses.md index 914b008d803..5604ea1e47c 100644 --- a/docs/write_analyses.md +++ b/docs/write_analyses.md @@ -25,6 +25,10 @@ Taint Analysis, TypeState Analysis, Linear Constant Propagation, ... ``` // TODO incorporate & guide through examples + +In the meantime please have a look into the test cases of the +analysis submodule to see example implementations of interprocedural +data-flow analysis via the IFDS or IDE Framework. + ``` -If you wish to implement an interprocedural data-flow analysis via the IFDS or IDE Framework please have a look at the test cases in the sootup.analysis submodule. diff --git a/mkdocs.yml b/mkdocs.yml index 8045d12d043..261fac16d31 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,7 +21,7 @@ nav: - BodyInterceptors: bodyinterceptors.md - Callgraph Construction: call-graph-construction.md - - Shipped Analyses: advanced-topics.md + - Shipped Analyses: shipped-analyses.md - How to..: - Write a Dataflow analysis: write_analyses.md @@ -30,7 +30,7 @@ nav: # - Modify a View: mutable_view.md # - Implement a BodyInterceptor: body_interceptor.md # - Implement an AnalysisTool: write_analysis_tool.md - - From Prototype to Tool: tool_ux.md + # - From Prototype to Tool: tool_setup.md - Misc: - Announcements: announce.md diff --git a/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java b/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java index d62b7a2f0fa..3a70f99745c 100644 --- a/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java +++ b/sootup.core/src/main/java/sootup/core/jimple/javabytecode/stmt/JRetStmt.java @@ -34,8 +34,8 @@ import sootup.core.util.printer.StmtPrinter; /** - * Represents the deprecated JVM ret statement (< java 1.6) - which is used in JSR Context - which - * is deprecated as well. + * Represents the deprecated JVM ret statement (< java 1.6) - which is used in JSR + * Context - which is deprecated as well. */ public final class JRetStmt extends AbstractStmt implements FallsThroughStmt { From 6b1ac22ba52ddbd53795580d884b5e8346a19111 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 11:53:56 +0200 Subject: [PATCH 14/23] add StmtVisitor doc --- docs/analysisinputlocations.md | 4 ++-- docs/jimple-stmts.md | 42 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md index 9c9cb70a1c6..450b55139c2 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinputlocations.md @@ -2,8 +2,8 @@ An AnalysisInputLocation tells SootUp what code input it should analyze. ### Java Runtime -- Java <9: `DefaultRTJaAnalysisInputLocation` current rt.jar (or point to any rt.jar as its just a usual .jar file) -- Java >8: `JRTFilesystemAnalysisInputLocation` +- Java <=8: `DefaultRTJaAnalysisInputLocation` current rt.jar (or point to any rt.jar as its just a usual .jar file) +- Java >=9: `JRTFilesystemAnalysisInputLocation` If you have errors like Java.lang.String, Java.lang.Object, ... you are most likely missing this AnalysisInput. diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index d739eeb01da..25b53cca1c6 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1171,3 +1171,45 @@ Ends the execution inside the current Method if the thrown exception is not caug MAXLOCALS = 3 } ``` + +## Good to know +A lot of the SootUp APIs return the `Stmt` Interface. To determine and handle its subtypes you can make use of instanceof. +=== "Stmt If-Else forest" + ```java + + List stmts = ... ; + for( Stmt stms : stmts ){ + if(stmt instanceof JAssignStmt){ + // found a JAssignStmt + Value rhsOp = ((JAssignStmt) stmt).getRightOp(); + ... + }else if(stmt instanceof JInvokeStmt){ + // found a JInvokeStmt + JInvokeStmt ivkStmt = ((JInvokeStmt) stmt); + MethodSignature rhsOp = ivkStmt.getInvokeExpr().getMethodSignature(); + ... + } + } + + ``` + +But this could escalate to a huge if-else-tree - almost a forest. To mitigate such scenario you can implement a subclass of `AbstractStmtVisitor`. +Just subclass the methods to the respective Stmts you need to handle. +=== "StmtVisitor" + ```java + + List stmts = ...; + AbstractStmtVisitor visitor = new AbstractStmtVisitor() { + private int countAssignStmts = 0; + @Override + public void caseIfStmt(@Nonnull JAssignStmt stmt) { + countAssignStmts++; + } + }; + + for( Stmt stms : stmts ){ + stmt.accept(visitor); + } + + int amountOfAssignStmts = visitor.getResult(); + ``` \ No newline at end of file From 31d52bf208b53e131aa43049b89fbebc0d752756 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 15:17:41 +0200 Subject: [PATCH 15/23] add StmtGraph doc --- docs/{announce.md => announcement.md} | 15 ++-- ...hipped-analyses.md => builtin-analyses.md} | 0 ...ll-graph-construction.md => callgraphs.md} | 0 docs/css/customizetheme.css | 5 ++ docs/getting-started.md | 78 ++++++++++++++----- mkdocs.yml | 13 ++-- 6 files changed, 77 insertions(+), 34 deletions(-) rename docs/{announce.md => announcement.md} (81%) rename docs/{shipped-analyses.md => builtin-analyses.md} (100%) rename docs/{call-graph-construction.md => callgraphs.md} (100%) diff --git a/docs/announce.md b/docs/announcement.md similarity index 81% rename from docs/announce.md rename to docs/announcement.md index 76ecf8b2fe8..98c0ccaa89f 100644 --- a/docs/announce.md +++ b/docs/announcement.md @@ -12,17 +12,18 @@ SootUp is a library that can easily be included in other projects, leaving those Below is an overview of what’s new. -* Library by default, framework as an option -* Modular Architecture, no more singletons -* New source code frontend -* Immutable Jimple IR -* Greatly increased testability and test coverage +- Library by default, framework as an option +- Modular Architecture, no more singletons +- New source code frontend +- Immutable Jimple IR +- Greatly increased testability and test coverage ![Coverage](https://camo.githubusercontent.com/adc4ab244f7c0c2b2f3fec0a6e5d778421ddc0be7f89a608c16533c9a964766f/68747470733a2f2f636f6465636f762e696f2f67682f736f6f742d6f73732f536f6f7455702f6272616e63682f646576656c6f702f67726170682f62616467652e7376673f746f6b656e3d454c4137553749415744) SootUp is not a drop-in replacement for Soot! Due to its completely new architecture and API it is essentially an almost complete rewrite. For a while, Soot and SootUp will coexist, as many existing tools depend on Soot, yet our maintenance efforts will henceforth be focused on SootUp, not Soot, and on extending SootUp with those capabilities that people still find missing. For now, we recommend using SootUp for greenfield projects. For more details, check out -* The SootUp home page: https://soot-oss.github.io/SootUp/, and -* The SootUp repository: https://github.com/soot-oss/SootUp/ +- +- The SootUp home page: [This Page](https://soot-oss.github.io/SootUp/), and +- The SootUp repository: [https://github.com/soot-oss/SootUp/](https://soot-oss.github.io/SootUp/) We are very much looking forward to your feedback and feature requests. To this end, best create appropriate issues in the repository. diff --git a/docs/shipped-analyses.md b/docs/builtin-analyses.md similarity index 100% rename from docs/shipped-analyses.md rename to docs/builtin-analyses.md diff --git a/docs/call-graph-construction.md b/docs/callgraphs.md similarity index 100% rename from docs/call-graph-construction.md rename to docs/callgraphs.md diff --git a/docs/css/customizetheme.css b/docs/css/customizetheme.css index ac31584dcce..53d080d46d5 100644 --- a/docs/css/customizetheme.css +++ b/docs/css/customizetheme.css @@ -11,6 +11,11 @@ --md-accent-fg-color: rgba(255,140,0, 1); } +.md-main__inner { + margin-top: 0; + margin-bottom: 5em; +} + .md-typeset{ font-size: 12pt; } diff --git a/docs/getting-started.md b/docs/getting-started.md index 8dd6b44160b..6ca98dbe806 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,19 +2,16 @@ Before you get started with the SootUp library, it helps to learn about the following core data structures: - [`AnalysisInputLocation`]{It corresponds to the `cp` option, which specifies the classpath for Soot to find classes to be analyzed.} - : points to the target code to be analyzed. + : points to the target code that shall be loaded into the `View`. -- [`View`]{Corresponds to the `Scene` class, but it is not a singleton. So it is possible to instantiate multiple views simultaneously.}: presents the code/classes under analysis. +- [`View`]{Corresponds to the `Scene` class, but it is not a singleton. So it is possible to instantiate multiple views simultaneously.}: +handles the representation of the code you configured it to analyze. -- `SootClass`: represents a class loaded into the `View`. - -- `SootMethod`: represents a method of a class. - -- `SootField`: represents a field of a class. - -- `Body`: represents a method body in Jimple. - -- `StmtGraph`: represents the control flow graph of a method body in Jimple statements. +- `SootClass`: represents a class. Can be loaded from the View via a `ClassType` identifier. +- `SootMethod`: represents a method of a class - loaded from the View via a `MethodSignature` identifier. +- `SootField`: represents a field of a class - loaded from the View via a `FieldSignature` identifier. +- `Body`: represents a method body of a `SootMethod`. +- `StmtGraph`: represents the control flow graph of a `Body`. `Stmt`'s represent actual Instructions. ## Creating a View @@ -31,11 +28,10 @@ You can use bytecode analysis typically when you do not have access to the sourc If you have access to the source code, it is also possible to create a view for analyzing source code. Following example shows how to create view for analyzing Java source code. -!!! info "Experimental" - - The source code frontend is experimental and should only be used for testing purposes. You should compile the code for analysis first and use the bytecode frontend instead. +!!! info "Experimental! - Create a view to analyze Java source code" -!!! example "Create a view to analyze Java source code" + The source code frontend is experimental and should only be used for testing purposes. + Usually you should compile the code for analysis first and use the bytecode frontend instead (see above). ~~~java AnalysisInputLocation inputLocation = @@ -65,10 +61,10 @@ If you have a [Jimple](../jimple) file, you can create a view for analyzing jimp By default, whenever a class is retrieved, it will be permanently stored in a cache. If you do not want retrieved classes to be stored indefinetly, you can instead provide a different `CacheProvider` to the created view. -To for example use an `LRUCache` instead, which stores at most 50 classes, and always replaces the least recently used class by a newly retrieved one, use the following call: +To for example use an `LRUCache` instead, which stores at most e.g. 50 classes, and always replaces the least recently used class by a newly retrieved one, use the following call: ```java -JavaView view = new JavaView(Collections.singletonList(inputLocation), new LRUCacheProvider(50)); +JavaView view = new JavaView(inputLocations, new LRUCacheProvider(50)); ``` @@ -149,9 +145,11 @@ Once we have a `MethodSignature` that identifies the `main` method of the `Hello ```java Optional opt = view.getMethod(methodSignature); - if(opt.isPresent()){ - SootMethod method = opt.get(); + if(!opt.isPresent()){ + return; } + SootMethod method = opt.get(); + System.out.println(method.getModifiers()); ``` Alternatively, we can also retrieve a `SootMethod` from `SootClass` that contains it. @@ -173,7 +171,47 @@ Each `SootMethod` contains a Control-Flow Graph (CFG) which is represented via t !!! example "Retrieving the CFG of a SootMethod" ```java - sootMethod.getBody().getStmtGraph(); + StmtGraph graph = sootMethod.getBody().getStmtGraph(); + ``` + + +## Using the StmtGraph + +=== "StmtGraph Stmts" + ```java + for( Stmt stmt : graph.nodes()){ + // pseudo topological order as Stmts would be serialized to a Jimple file. + } + + for( Stmt stmt : graph.nodes()){ + // Stmts are unordered! + } + ``` +=== "StmtGraph Blocks" + ```java + List> blocks = graph.getBlocks(); + for( BasicBlock block : blocks){ + // e.g. check if its a merge point + if(block.getPredecessors().size() > 1){ + ... + } + + // e.g. check if its a branching point + if(block.getSuccessors().size() > 1){ + // or use block.getTail() instanceof BranchingStmt + ... + } + + // e.g. check if thrown exceptions would be caught in this method + if(!block.getExceptionalSuccessors().isEmpty()){ + ... + } + } + ``` +=== "StmtGraph DotExport" + ```java + String urlToWebeditor = DotExporter.createUrlToWebeditor(this); + System.out.println(urlToWebeditor); ``` diff --git a/mkdocs.yml b/mkdocs.yml index 261fac16d31..c2cf7395a97 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,27 +1,26 @@ -site_name: SootUp +site_name: "" site_url: https://soot-oss.github.io/SootUp/ repo_url: https://github.com/soot-oss/SootUp/ edit_uri: edit/develop/docs/ nav: - - Home: index.md - - Getting Started: - Installation: installation.md - First Steps: getting-started.md - Examples: examples.md - Configure your Inputs: analysisinputlocations.md - - Basics: + - Basics I: - Jimple IR: jimple.md - Jimple Body: jimple-body.md - Jimple Statements: jimple-stmts.md - Jimple Types: jimple-types.md - Jimple Values: jimple-values.md + - Basics II: - BodyInterceptors: bodyinterceptors.md - - Callgraph Construction: call-graph-construction.md - - Shipped Analyses: shipped-analyses.md + - Callgraphs: callgraphs.md + - BuiltIn Analyses: builtin-analyses.md - How to..: - Write a Dataflow analysis: write_analyses.md @@ -33,7 +32,7 @@ nav: # - From Prototype to Tool: tool_setup.md - Misc: - - Announcements: announce.md + - Announcements: announcement.md - Design Decisions: whatsnew.md - Migration Help: migrating.md From 9f67b3426f0713c74fbdc2417cd109f843066449 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 15:55:12 +0200 Subject: [PATCH 16/23] progress --- docs/bodyinterceptors.md | 9 ++++----- docs/builtin-analyses.md | 7 ++++--- docs/callgraphs.md | 11 +++++++---- docs/examples.md | 25 ++++++++++++++++--------- docs/faq.md | 6 ++++-- docs/jimple.md | 3 +-- mkdocs.yml | 14 ++++++-------- 7 files changed, 42 insertions(+), 33 deletions(-) diff --git a/docs/bodyinterceptors.md b/docs/bodyinterceptors.md index 4f98e8e1fac..4039ee4508e 100644 --- a/docs/bodyinterceptors.md +++ b/docs/bodyinterceptors.md @@ -9,7 +9,8 @@ The "raw" generated Jimple from the Bytecodefrontend needs a lot improvements - - The Locals we get from the Java bytecode are typically untyped. Therefore we have to augment the Local types which is done by the TypeAssigner. - t.b.c. -Method scoped optimisations: +Optimizations (method scope) + - ConditionalBranchFolder: removes tautologic ifs that are always true/false - if we can determine it in the scope of the method. - EmptySwitchEliminator: removes switches that are not really switching - ConstantPropagatorAndFolder: calculates constant values before runtime @@ -17,16 +18,14 @@ Method scoped optimisations: - UnreachableCodeEliminator: speaks for itself. - TrapTightener -Make Local names standardized: +Standardize Jimple appearance + - LocalNameStandardizer: numbers Locals with the scheme: type-initial + number of type occurence !!! info "Soot Equivalent" - [BodyTransformer](https://github.com/soot-oss/soot/blob/develop/src/main/java/soot/BodyTransformer.java) -Below, we show how these BodyInterceptors work for the users who are interested in their internal workings. - ### LocalSplitter LocalSplitter is aBodyInterceptorthat attempts to identify and separate uses of a local variable (as definition) that are independent of each other by renaming local variables. diff --git a/docs/builtin-analyses.md b/docs/builtin-analyses.md index 273912b3b93..6878e646810 100644 --- a/docs/builtin-analyses.md +++ b/docs/builtin-analyses.md @@ -1,6 +1,7 @@ -# Functionalities and Utilities +# BuiltIn Analyses +More to come! -#### LocalLivenessAnalyser +### LocalLivenessAnalyser LocalLivenessAnalyser is used for querying for the list of live local variables before and after a given Stmt. @@ -10,7 +11,7 @@ Example: The live local variables before and after each Stmt will be calculated after generating an instance of LocalLivenessAnalyser as shown the example above. They can be queried by using the methods getLiveLocalsBeforeStmt and getLiveLocalsAfterStmt. -#### DominanceFinder +### DominanceFinder DomianceFinder is used for querying for the immediate dominator and dominance frontiers for a given basic block. diff --git a/docs/callgraphs.md b/docs/callgraphs.md index e589b5736c9..dbfb503481d 100644 --- a/docs/callgraphs.md +++ b/docs/callgraphs.md @@ -10,8 +10,9 @@ Below, we show how to create a type hierarchy: === "SootUp" ```java + String cpString = "src/test/resources/Callgraph/binary"; List inputLocations = new ArrayList(); - inputLocations.add(new JavaClassPathAnalysisInputLocation("src/test/resources/Callgraph/binary")); + inputLocations.add(new JavaClassPathAnalysisInputLocation(cpStr)); inputLocations.add(new DefaultRTJarAnalysisInputLocation()); JavaView view = new JavaView(inputLocations); @@ -61,7 +62,9 @@ All the call graph construction algorithms require an entry method to start with === "SootUp (alternative)" ```java - MethodSignature entryMethodSignature = view.getIdentifierFactory().parseMethodSignature(" \ No newline at end of file diff --git a/docs/faq.md b/docs/faq.md index f9c75c88b54..e7f2efa5e51 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -42,12 +42,14 @@ or create a convenient link with the exported stmtgraph as HTTP GET Parameter DotExporter.createUrlToWebeditor( stmtgraph ); ``` +### The Sourcecodefrontend... +is in a experimental state! If you wish to use it, please consider to contribute. ### Is there a way to use code exploration and syntax highlighting features in my IDE for .jimple files? -Try [JimpeLsp](https://github.com/swissiety/JimpleLsp). +Try [JimpeLsp](https://github.com/swissiety/JimpleLsp) or the [vscode plugin](https://marketplace.visualstudio.com/items?itemName=swissiety.jimplelsp) ### Is there a way to use syntax highlighting of .jimple in my paper, thesis, ...? -Have a look at [LspLexer4Pygments](https://github.com/swissiety/LspLexer4Pygments). +Have a look at [LspLexer4Pygments](https://github.com/swissiety/LspLexer4Pygments). Its the same syntax highlighting you see here in the documentation. You can export it to LaTex as well. ### How to ... add an entry in this list? i.e. Your question is not answered here? Feel free to start a [Discussion](https://github.com/soot-oss/SootUp/discussions). diff --git a/docs/jimple.md b/docs/jimple.md index 8b86014413f..74ad683fdec 100644 --- a/docs/jimple.md +++ b/docs/jimple.md @@ -6,8 +6,7 @@ Therefore, Jimple aims to bring the best of both worlds, a non-stack-based and f For this purpose Jimple was designed as a representation of JVM bytecode which is human readable. !!! info - - To learn more about jimple, refer to the [thesis](https://courses.cs.washington.edu/courses/cse501/01wi/project/sable-thesis.pdf) by Raja Vallee-Rai. + To learn more about jimple, refer to the [thesis](https://courses.cs.washington.edu/courses/cse501/01wi/project/sable-thesis.pdf) by Raja Vallee-Rai. Lets have a look at the following Jimple code representing Java code of a `HelloWorld` class. diff --git a/mkdocs.yml b/mkdocs.yml index c2cf7395a97..0ed35eb015f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,14 +10,14 @@ nav: - Examples: examples.md - Configure your Inputs: analysisinputlocations.md - - Basics I: + - Basics: - Jimple IR: jimple.md - Jimple Body: jimple-body.md - Jimple Statements: jimple-stmts.md - Jimple Types: jimple-types.md - Jimple Values: jimple-values.md - - Basics II: + - Advanced Topics: - BodyInterceptors: bodyinterceptors.md - Callgraphs: callgraphs.md - BuiltIn Analyses: builtin-analyses.md @@ -31,12 +31,10 @@ nav: # - Implement an AnalysisTool: write_analysis_tool.md # - From Prototype to Tool: tool_setup.md - - Misc: - - Announcements: announcement.md - - Design Decisions: whatsnew.md - - Migration Help: migrating.md - - - More information: + - Misc & More information: + - Announcements: announcement.md + - Design Decisions: whatsnew.md + - Migration Help: migrating.md - Latest Javadoc: /SootUp/apidocs - Troubleshooting & FAQ: faq.md # - Based on SootUp: tools.md From c881926bc3675fcbb12ad817a3ea4c1bc769bb36 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 16:00:36 +0200 Subject: [PATCH 17/23] more progress --- docs/analysisinputlocations.md | 2 +- docs/announcement.md | 5 ++--- docs/migrating.md | 6 +++--- docs/tool_setup.md | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md index 450b55139c2..77c04c71a65 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinputlocations.md @@ -22,4 +22,4 @@ If you have errors like Java.lang.String, Java.lang.Object, ... you are most lik ### Java cli arguments to configure SootUp -We created a [Utility](tool_setup) that parses a String of java command line arguments and configures SootUp respectively. \ No newline at end of file +We created a [Utility](tool_setup.md) that parses a String of java command line arguments and configures SootUp respectively. \ No newline at end of file diff --git a/docs/announcement.md b/docs/announcement.md index 98c0ccaa89f..78941b91c18 100644 --- a/docs/announcement.md +++ b/docs/announcement.md @@ -21,9 +21,8 @@ Below is an overview of what’s new. SootUp is not a drop-in replacement for Soot! Due to its completely new architecture and API it is essentially an almost complete rewrite. For a while, Soot and SootUp will coexist, as many existing tools depend on Soot, yet our maintenance efforts will henceforth be focused on SootUp, not Soot, and on extending SootUp with those capabilities that people still find missing. For now, we recommend using SootUp for greenfield projects. For more details, check out -- -- The SootUp home page: [This Page](https://soot-oss.github.io/SootUp/), and -- The SootUp repository: [https://github.com/soot-oss/SootUp/](https://soot-oss.github.io/SootUp/) + +[This Page ;-)](https://soot-oss.github.io/SootUp/) and The SootUp repository: [https://github.com/soot-oss/SootUp/](https://soot-oss.github.io/SootUp/) We are very much looking forward to your feedback and feature requests. To this end, best create appropriate issues in the repository. diff --git a/docs/migrating.md b/docs/migrating.md index c7302e738a0..dc2eca2059c 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -2,8 +2,7 @@ ### Version 1.3.0 - The Typehierarchy API is now returning `Stream` instead of `Collection`. The simplest fix to have the same behaviour as before would be to collect the Stream on your own ( e.g. via `.collect(Collectors.toList())` ). -- Default Bodyinterceptors are added to improve Jimple. To mitigate that adapt the List of BodyInterceptors to your needs. -- +- Default BytecodeBodyinterceptors are enabled to improve Jimple. To mitigate that adapt the List of BodyInterceptors to your needs. ### Version 1.2.0 - The (Java)Project structure was removed. You can configure the (Java)View directly. @@ -36,7 +35,8 @@ Below we show a comparison of the code so far with the same functionality in soo JavaSootClass sootClass = view.getClass(classType).get(); - JavaSootMethod sootMethod = sootClass.getMethod(methodSignature.getSubSignature()).get(); + MethodSubSignature mss = methodSignature.getSubSignature(); + JavaSootMethod sootMethod = sootClass.getMethod(mss).get(); sootMethod.getBody().getStmts(); ``` diff --git a/docs/tool_setup.md b/docs/tool_setup.md index c4d0f4d96cf..ee4445427f8 100644 --- a/docs/tool_setup.md +++ b/docs/tool_setup.md @@ -1,4 +1,4 @@ -# From Prototype to a user friendly tool +# From Prototype to an intuitive Tool `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.. From bba530951e74779bc12462fb02edcb5fa8d52818 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 16:07:27 +0200 Subject: [PATCH 18/23] more more progress --- docs/analysisinputlocations.md | 7 ++++--- mkdocs.yml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/analysisinputlocations.md b/docs/analysisinputlocations.md index 77c04c71a65..3c2773364b4 100644 --- a/docs/analysisinputlocations.md +++ b/docs/analysisinputlocations.md @@ -1,5 +1,6 @@ -# AnalysisInputLocations -An AnalysisInputLocation tells SootUp what code input it should analyze. +# Analysis Input +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. ### Java Runtime - Java <=8: `DefaultRTJaAnalysisInputLocation` current rt.jar (or point to any rt.jar as its just a usual .jar file) @@ -18,7 +19,7 @@ If you have errors like Java.lang.String, Java.lang.Object, ... you are most lik - `JimpleAnalysisInputLocation` - needs a Path to a .jimple file or a directory. ### Android Bytecode .dex -- `ApkAnalysisInputLocation` - currenlty uses dex2jar internally - SootUp solution is WIP! +- `ApkAnalysisInputLocation` - currenlty uses dex2jar internally - A SootUp solution to directly generate Jimple is WIP! ### Java cli arguments to configure SootUp diff --git a/mkdocs.yml b/mkdocs.yml index 0ed35eb015f..1ad408272cc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -7,8 +7,8 @@ nav: - Getting Started: - Installation: installation.md - First Steps: getting-started.md + - Possible Analysis Input: analysisinputlocations.md - Examples: examples.md - - Configure your Inputs: analysisinputlocations.md - Basics: - Jimple IR: jimple.md From 5d7f716814aed50f5693f46016ff89464815e528 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 17:12:12 +0200 Subject: [PATCH 19/23] try fixing code block --- docs/jimple-values.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/jimple-values.md b/docs/jimple-values.md index 3da17f8a88f..dadaafe5153 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -1,18 +1,19 @@ # Jimple Values -### Immediate -An Immediate has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). +### Immediates +An `Immediate` has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). #### Local ```jimple i0 ``` + A Local is a variable and its scope is inside its method i.e. no referencing from outside a method. Values can be assigned to Locals via JIdentityStmt or JAssignStmt. -=== "Jimple" +=== "Jimple" - ```jimple + ``` public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -40,14 +41,14 @@ Values can be assigned to Locals via JIdentityStmt or JAssignStmt. } } /* - $stack2, this, $stack3, local#2 are all JimpleLocal. + $stack2, this, $stack3, local#2 are all Locals. - "this := @this: target.exercise1.DemoClass" is JIdentityStmt + "this := @this: target.exercise1.DemoClass" is a JIdentityStmt assigning to a Local. "$stack2 = ", "local#2 = this.", "$stack3 = " - are JAssignStmt + are JAssignStmts assigning to a Local. */ ``` @@ -142,9 +143,10 @@ And a bunch more! ### Ref #### JArrayRef ```jimple -$arr[1] +$arr[1] = 42; +$anotherLocal = arr[99]; ``` -referencing a position inside an array. +referencing an array position. #### JFieldRef `JFieldRef`s are referencing a `SootField` via its FieldSignature From 4d58c4bff79f73d8d1ffae08aad50310713cbdd0 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 17:19:43 +0200 Subject: [PATCH 20/23] try fixing code block --- docs/jimple-stmts.md | 13 +++++++------ docs/jimple-values.md | 18 +++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index 25b53cca1c6..c3ae5f0d6b4 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1174,7 +1174,7 @@ Ends the execution inside the current Method if the thrown exception is not caug ## Good to know A lot of the SootUp APIs return the `Stmt` Interface. To determine and handle its subtypes you can make use of instanceof. -=== "Stmt If-Else forest" +=== "instanceOf & If-Else" ```java List stmts = ... ; @@ -1188,7 +1188,7 @@ A lot of the SootUp APIs return the `Stmt` Interface. To determine and handle it JInvokeStmt ivkStmt = ((JInvokeStmt) stmt); MethodSignature rhsOp = ivkStmt.getInvokeExpr().getMethodSignature(); ... - } + }else ... } ``` @@ -1200,10 +1200,11 @@ Just subclass the methods to the respective Stmts you need to handle. List stmts = ...; AbstractStmtVisitor visitor = new AbstractStmtVisitor() { - private int countAssignStmts = 0; + private int ifStmtsCounter = 0; @Override - public void caseIfStmt(@Nonnull JAssignStmt stmt) { - countAssignStmts++; + public void caseIfStmt(@Nonnull JIfStmt stmt) { + ifStmtsCounter++; + setResult(ifStmtCounter); } }; @@ -1211,5 +1212,5 @@ Just subclass the methods to the respective Stmts you need to handle. stmt.accept(visitor); } - int amountOfAssignStmts = visitor.getResult(); + int amountOfIfStmts = visitor.getResult(); ``` \ No newline at end of file diff --git a/docs/jimple-values.md b/docs/jimple-values.md index dadaafe5153..0c7a4b84ba0 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -13,7 +13,7 @@ Values can be assigned to Locals via JIdentityStmt or JAssignStmt. === "Jimple" - ``` + ```jimple public class target.exercise1.DemoClass extends java.lang.Object { public void () @@ -23,30 +23,30 @@ Values can be assigned to Locals via JIdentityStmt or JAssignStmt. specialinvoke this.()>(); return; } - + public void compute() { java.io.PrintStream $stack2, $stack3; target.exercise1.DemoClass this; - int local#2; - + int local2; + this := @this: target.exercise1.DemoClass; $stack2 = ; virtualinvoke $stack2.(1); - - local#2 = this.; + + local2 = this.; $stack3 = ; - virtualinvoke $stack3.(local#2); + virtualinvoke $stack3.(local2); return; } } /* - $stack2, this, $stack3, local#2 are all Locals. + $stack2, this, $stack3, local2 are all Locals. "this := @this: target.exercise1.DemoClass" is a JIdentityStmt assigning to a Local. "$stack2 = ", - "local#2 = this.", + "local2 = this.", "$stack3 = " are JAssignStmts assigning to a Local. From 6194af7a106ed3d83ba42a50ae3415cc92af78fc Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 18:10:40 +0200 Subject: [PATCH 21/23] dont print language tag of code block if the styling fails --- docs/jimple-values.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/jimple-values.md b/docs/jimple-values.md index 0c7a4b84ba0..017712b8574 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -4,7 +4,7 @@ An `Immediate` has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). #### Local -```jimple +``` i0 ``` @@ -142,7 +142,7 @@ And a bunch more! ### Ref #### JArrayRef -```jimple +``` $arr[1] = 42; $anotherLocal = arr[99]; ``` @@ -160,19 +160,19 @@ referencing an array position. The IdentityRef makes those implicit special value assignments explicit. ##### JThisRef -```jimple +``` @this: package.fruit.Banana ``` represents the this pointer of the current class. ##### JCaughtExceptionRef -```jimple +``` @caughtexception ``` represents the value of the thrown exception (caught by this exceptionhandler). ##### JParameterRef -```jimple +``` i0 := @parameter0 i1 := @parameter1 ``` From 069143091f58930995783e2eec77712e3d703a5c Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Tue, 18 Jun 2024 18:11:57 +0200 Subject: [PATCH 22/23] dont print language tag of code block if the styling fails --- docs/jimple-values.md | 4 ++-- docs/jimple.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/jimple-values.md b/docs/jimple-values.md index 017712b8574..4b98e5d31c4 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -151,8 +151,8 @@ referencing an array position. #### JFieldRef `JFieldRef`s are referencing a `SootField` via its FieldSignature -- `JStaticFieldRef` like `#!jimple ` -- `JInstanceFieldRef` like `#!jimple r1.` +- `JStaticFieldRef` like ` ` +- `JInstanceFieldRef` like ` r1.` You can see the JInstanceFieldRef has the corresponding Local instance that points to the instance of the object which is holding the field. diff --git a/docs/jimple.md b/docs/jimple.md index 74ad683fdec..7370de698ae 100644 --- a/docs/jimple.md +++ b/docs/jimple.md @@ -6,7 +6,7 @@ Therefore, Jimple aims to bring the best of both worlds, a non-stack-based and f For this purpose Jimple was designed as a representation of JVM bytecode which is human readable. !!! info - To learn more about jimple, refer to the [thesis](https://courses.cs.washington.edu/courses/cse501/01wi/project/sable-thesis.pdf) by Raja Vallee-Rai. + To learn more about jimple, refer to the [thesis](https://courses.cs.washington.edu/courses/cse501/01wi/project/sable-thesis.pdf) by Raja Vallee-Rai. Lets have a look at the following Jimple code representing Java code of a `HelloWorld` class. @@ -246,7 +246,7 @@ Sidenote: Locals, do not have a signature, since they are referenced within meth } ``` -### SootClass +### SootClass A `SootClass` consists of SootFields and SootMethods. It is referenced by its global identifier the `ClassType` like `java.lang.String`. @@ -299,7 +299,7 @@ It is referenced by its global identifier the `ClassType` like `java.lang.String ### SootField A SootField is a piece of memory which can store a value that is accessible according to its visibility modifier. -It is referenced by its FieldSignature like `#!jimple `. +It is referenced by its FieldSignature like ` `. === "Jimple" @@ -364,7 +364,7 @@ It is referenced by its FieldSignature like `#!jimple `. +It is referenced by its MethodSignature like ` `. === "Jimple" From fbe539be32bab492374e6b3f54685aacce522d52 Mon Sep 17 00:00:00 2001 From: "M.Schmidt" Date: Wed, 19 Jun 2024 11:07:10 +0200 Subject: [PATCH 23/23] add more visitor examples --- docs/jimple-stmts.md | 6 ++++-- docs/jimple-values.md | 41 +++++++++++++++++++++++++++++++++++++++-- mkdocs.yml | 39 +++++++++++++++++++-------------------- 3 files changed, 62 insertions(+), 24 deletions(-) diff --git a/docs/jimple-stmts.md b/docs/jimple-stmts.md index c3ae5f0d6b4..06bc1c8a233 100644 --- a/docs/jimple-stmts.md +++ b/docs/jimple-stmts.md @@ -1194,7 +1194,7 @@ A lot of the SootUp APIs return the `Stmt` Interface. To determine and handle it ``` But this could escalate to a huge if-else-tree - almost a forest. To mitigate such scenario you can implement a subclass of `AbstractStmtVisitor`. -Just subclass the methods to the respective Stmts you need to handle. +Just subclass the methods to the respective Stmts you need to handle. This is visitor acts like a switch-case, implemented via two dynamic calls. === "StmtVisitor" ```java @@ -1213,4 +1213,6 @@ Just subclass the methods to the respective Stmts you need to handle. } int amountOfIfStmts = visitor.getResult(); - ``` \ No newline at end of file + ``` + + Sidenote: Of course its possible can create a subclass instead of an anonymous class. \ No newline at end of file diff --git a/docs/jimple-values.md b/docs/jimple-values.md index 4b98e5d31c4..cdcb1cc35b8 100644 --- a/docs/jimple-values.md +++ b/docs/jimple-values.md @@ -1,6 +1,6 @@ # Jimple Values -### Immediates +### Immediate An `Immediate` has a [**given**]{as in constant or immutable} Type and consists of a Local ("a Variable", "Something that contains a Value") or a Constant ("Something that is a Value"). #### Local @@ -11,7 +11,7 @@ i0 A Local is a variable and its scope is inside its method i.e. no referencing from outside a method. Values can be assigned to Locals via JIdentityStmt or JAssignStmt. -=== "Jimple" +=== "Jimple" ```jimple public class target.exercise1.DemoClass extends java.lang.Object @@ -178,3 +178,40 @@ i1 := @parameter1 ``` represents a parameter of a method, identified by its index. +## Good to know +A lot of the SootUp APIs return the `Value` Interface. To determine and handle its subtypes you can make use of instanceof. +=== "instanceOf & If-Else" + ```java + + Value op = assignStmt.getRightOp(); + if(op instanceof Local){ + // found a Local + ... + }else if(stmt instanceof Constant){ + // found a Constant + ... + }else ... + + ``` + +But this could escalate to a huge if-else-tree - almost a forest. To mitigate such scenario you can implement a subclass of `AbstractValueVisitor`. +Just subclass the methods to the respective `Value`s you need to handle. This is visitor acts like a switch-case, implemented via two dynamic calls. +=== "StmtVisitor" + ```java + + Value op = assignStmt.getRightOp() ; + AbstractValueVisitor visitor = new AbstractValueVisitor() { + private int intConstantCounter = 0; + @Override + public void caseConstant(@Nonnull Constant c) { + intConstantCounter++; + setResult(intConstantCounter); + } + }; + + op.accept(visitor); + int amountOfIfStmts = visitor.getResult(); + ``` + + If you only need a visitor for a subset of Value, you can consider ImmediateVisitor, ConstantVisitor, ExprVisitor, RefVisitor. + Sidenote: Of course its possible can create a subclass instead of an anonymous class. diff --git a/mkdocs.yml b/mkdocs.yml index 1ad408272cc..87633845ac6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -4,52 +4,55 @@ repo_url: https://github.com/soot-oss/SootUp/ edit_uri: edit/develop/docs/ nav: - - Getting Started: - - Installation: installation.md - - First Steps: getting-started.md - - Possible Analysis Input: analysisinputlocations.md - - Examples: examples.md + - Getting Started: + - Installation: installation.md + - First Steps: getting-started.md + - Analysis Input: analysisinputlocations.md + - Examples: examples.md - - Basics: + - Basics: - Jimple IR: jimple.md - Jimple Body: jimple-body.md - Jimple Statements: jimple-stmts.md - Jimple Types: jimple-types.md - Jimple Values: jimple-values.md - - Advanced Topics: + - Advanced Topics: - BodyInterceptors: bodyinterceptors.md - Callgraphs: callgraphs.md - BuiltIn Analyses: builtin-analyses.md - - How to..: + - How to..: - Write a Dataflow analysis: write_analyses.md - Incorporate Pointer Analysis: qilin.md - # - Modify a StmtGraph: mutable_stmtgraph.md - # - Modify a View: mutable_view.md - # - Implement a BodyInterceptor: body_interceptor.md - # - Implement an AnalysisTool: write_analysis_tool.md - # - From Prototype to Tool: tool_setup.md + # - Modify a StmtGraph: mutable_stmtgraph.md + # - Modify a View: mutable_view.md + # - Implement a BodyInterceptor: body_interceptor.md + # - Implement an AnalysisTool: write_analysis_tool.md + # - From Prototype to Tool: tool_setup.md - - Misc & More information: + - Misc & More information: - Announcements: announcement.md - Design Decisions: whatsnew.md - Migration Help: migrating.md - Latest Javadoc: /SootUp/apidocs - Troubleshooting & FAQ: faq.md - # - Based on SootUp: tools.md + # - Based on SootUp: tools.md theme: + name: material logo: ./img/SootUpLogo.svg favicon: ./img/icon.svg palette: primary: custom custom_dir: ./docs/overrides - name: material features: - navigation.sections +extra_css: + - css/customizetheme.css + - css/hint.min.css plugins: - tooltips @@ -57,10 +60,6 @@ plugins: - include: src_path: 'sootup.examples/src/test/java/sootup/examples' -extra_css: - - css/customizetheme.css - - css/hint.min.css - markdown_extensions: - pymdownx.highlight: linenums: true