diff --git a/doc_keep_install_up2date/installation/index.html b/doc_keep_install_up2date/installation/index.html index 099fd6dec5e..9b7b76719f9 100644 --- a/doc_keep_install_up2date/installation/index.html +++ b/doc_keep_install_up2date/installation/index.html @@ -735,37 +735,37 @@
compile "org.soot-oss:sootup.core:"
-compile "org.soot-oss:sootup.java.core"
-compile "org.soot-oss:sootup.java.sourcecode"
-compile "org.soot-oss:sootup.java.bytecode"
-compile "org.soot-oss:sootup.jimple.parser"
-compile "org.soot-oss:sootup.callgraph"
-compile "org.soot-oss:sootup.analysis"
+7
compile "org.soot-oss:sootup.core:1.1.2"
+compile "org.soot-oss:sootup.java.core1.1.2"
+compile "org.soot-oss:sootup.java.sourcecode1.1.2"
+compile "org.soot-oss:sootup.java.bytecode1.1.2"
+compile "org.soot-oss:sootup.jimple.parser1.1.2"
+compile "org.soot-oss:sootup.callgraph1.1.2"
+compile "org.soot-oss:sootup.analysis1.1.2"
Build from source if you'd like to get the most recent changes. diff --git a/doc_keep_install_up2date/search/search_index.json b/doc_keep_install_up2date/search/search_index.json index a5ccd6968ad..39a04d7f1bd 100644 --- a/doc_keep_install_up2date/search/search_index.json +++ b/doc_keep_install_up2date/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"What's SootUp?","text":"
SootUp is a complete overhaul of the good, old static analysis framework Soot.
Important
SootUp is not a version update to Soot, it is instead a completely new implementation written from scratch that aims to be a leaner, more extensible equivalent of soot.
"},{"location":"#why-sootup","title":"Why SootUp?","text":""},{"location":"#click-here-to-read-our-announcement-on-the-first-release-of-sootup","title":"Click here to read our announcement on the first release of SootUp","text":"Over the 20+ years, SootUps predecessor Soot has evolved into a powerful framework, which is one of the most widely used tools in the static analysis community. This evolution was guided by the needs of the community and carried out with ad-hoc improvements. As a result, Soot has become a tool that can do a multitude of things, but it is heavy and hard to maintain and comprehend. So there was the need to clean up the codebase e.g. improve the software architecture, remove legacy datastructures that weren't in the Java Runtime at the time of Soots creation, enforce validation to have a sane state, removing the necessity of arcane knowledge, document it more and more - to make Soot future prove. So we introduced Design changes in SootUp, which aim to address Soot's shortcomings. The goal is a lighter library that can easily be understood and maintained to be included in other projects.
"},{"location":"#is-this-a-drop-in-replacement-for-soot","title":"Is this a drop-in replacement for Soot?","text":"Not really. SootUp has a completely new architecture and API, so it is not trivial to update existing projects that build on soot. We recommend using SootUp for greenfield projects.
"},{"location":"#supporters","title":"Supporters","text":"The development of SootUp is financed by generous support from the German Research Foundation (DFG) and the Heinz Nixdorf Institute (HNI).
Become a sponsor!
"},{"location":"advanced-topics/","title":"Advanced Topics","text":"As a user of the SootUp framework, you can omit these topics which mostly explain how some of the concepts work internally.
"},{"location":"advanced-topics/#body-interceptors","title":"Body Interceptors","text":"Soot Equivalent
BodyTransformer
Almost in all use-cases you can simply ignore body interceptors. They are applied to each Body
by default to create their rather normalized or leaner versions, e.g. by eliminating unreachable code (UnreachableCodeEliminator
), standardizing names of locals (LocalNameStandardizer
), or removing empty switch statements (EmptySwitchEliminator
) etc.
Below, we show how these body interceptors work for the users who are interested in their internal workings.
"},{"location":"advanced-topics/#localsplitter","title":"LocalSplitter","text":"LocalSplitter is aBodyInterceptor
that attempts to identify and separate uses of a local variable (as definition) that are independent of each other by renaming local variables.
Example 1:
As shown in the example above, the local variablel1
is 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.
Look for foldable navigation and tabs for showing old vs new
Example 2:
In the second example, the local variablel2
is 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.
LocalPacker is aBodyInterceptor
that attempts to minimize the number of local variables which are used in body by reusing them, when it is possible. It corresponds to the inverse body transformation of LocalSplitter. Note: Every local variable's type should be assigned before running LocalPacker.
Example:
In the given example above, the local variablesl1
,l3
are summarized to be one local variablel1
, because they have the same type without interference with each other. Likewise, the local variablesl2
,l4
andl5
are summarized to be another local variablel2
. Although the local variablel0
doesn't interfere any other local variables, it cannot be summed up with other local variables because of its distinctive type.
TrapTightener is aBodyInterceptor
that shrinks the protected area covered by each Trap in a Body.
Example:
We assume in the example above that only theStmt
:l2 := 2
might throw an exception caught by theTrap
which 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 theStmt
that might throw an exception, namely theStmt
:l2 := 2
.
EmptySwitchEliminator is aBodyInterceptor
that removes empty switch statements which contain only the default case.
Example:
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 aGotoStmt
to the default case.
UnreachableCodeEliminator is aBodyInterceptor
that removes all unreachable statements.
Example:
Obviously, the code segmentl2 = 2; l3 = 3;
is unreachable. It will be removed after running the UreachableCodeEliminator.
CopyPropagator is aBodyInterceptor
that supports the global copy propagation and constant propagation.
Example for global copy propagation:
Consider a code segment in the following form:
a = b;\n...\nc = use(a); // a, b, c are local variables\n
According to the copy propagation's definition, the statementc = use(a)
can be replaced withc = use(b)
iff both conditions are met:
a
is defined only one time on all the paths froma = b
toc = use(a)
.b
on any path froma = b
toc = use(a)
.In the example for global copy propagation, the first usedl1
is replaced withl0
, but the second usedl1
cannot be replaced withl3
, because the second condition is not satisfied.
Example for constant propagation:
Constant propagation is similar to copy propagation. Consider a code segment in the following form:
a = const;\n...\nb = use(a); // a, b are local variables, const is a constant\n
After perfoming the constant propagation, the statementb = use(a)
can be replaced withb = use(const)
iffa
is not redefined on any of the paths froma = const
tob = use(a)
.
Therefore, the first usedl1
in the second example can be replaced with the constant1
, but the second usedl1
cannot be replaced with the constant2
, becausel1
is redefined on the path froml1 = 2
tol4 = use(l1)
. However, it can be replaced with local variablel2
, because the both conditions of copy propagation are met.
LocalNameStandardizer is aBodyInterceptor
that assigns a generic name to each local variable. Firstly, it will sort the local variables' order alphabetically by the string representation of their type. If there are two local variables with the same type, then the LocalNameStandardizer will use the sequence of their occurrence in jimple body to determine their order. Each assigned name consists of two parts:
The following table shows the letter corresponding to each type:
Type of Local Variable Letter boolean z byte b short s int i long l float f double d char c null n unknown e reference r"},{"location":"advanced-topics/#staticsingleassignmentformer","title":"StaticSingleAssignmentFormer","text":"StaticSingleAssignmentFormer is aBodyInterceptor
that transforms jimple body into SSA form, so that each local variable is assigned exactly once and defined before its first use.
Example:
In the given example, the StaticSingleAssignmentFormer assigns eachIdentityStmt
andAssignStmt
to 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 aPhiStmt
in the front of the join block to merge all most recently defined local variables and assign them a new local variable.
LocalLivenessAnalyser is used for querying for the list of live local variables before and after a given Stmt
.
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
.
DomianceFinder is used for querying for the immediate dominator and dominance frontiers for a given basic block.
Example:
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 methodsgetImmediateDominator
andgetDominanceFrontiers
.
We would like to announce Soot\u2019s successor, SootUp.
Over more than 20 years, Soot has become one of the world\u2019s most popular academic tool for Java and Android analysis and instrumentation. We thank all of you who have used and contributed to it over the years! It was your feedback and your contributions that helped it grow into such a versatile tool!
However, over the years, the requirements for Soot have changed a lot, and given its original architecture, it was no longer quite up to the task. Soot was originally developed for ahead-of-time code transformation, particularly optimization, which has become very uncommon in Java. Current use cases center much more around powerful program analyses and program-understanding tasks.
Today we are officially releasing SootUp, a new version of Soot with a completely overhauled architecture. With SootUp, we aim to keep the best things about Soot, yet overcome a lot of its drawbacks. We very much restructured Soot, particularly abolishing the heavy use of singletons. Soot now has a concept of views; each view corresponds to some version or variant of an analyzed program, and multiple views can be kept in memory at the same time. This sets the foundation, for instance, for differential or incremental program analyses.
SootUp is a library that can easily be included in other projects, leaving those projects in control. For those who intend to use it as a framework, with inversion of control, SootUp provides additional templates that help you and novices to get started more easily. The Jimple IR has been slightly simplified, and has been made immutable by default such that internally SootUp can make use of caching where desired. Where required, Jimple transformations are still allowed, but in a systematic manner, for instance assuring that analyses depending on the transformed code are notified about its changes.
Below is an overview of what\u2019s 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: https://soot-oss.github.io/SootUp/, and * The SootUp repository: https://github.com/soot-oss/SootUp/
We are very much looking forward to your feedback and feature requests. To this end, best create appropriate issues in the repository.
This major upgrade of Soot was made possible by generous competitive funding by the DFG, within the project \u201cFuture-proofing the Soot Framework for Program Analysis and Transformation (FutureSoot)\u201d. It was funded in the DFG\u2019s program on Research Software Sustainability.
"},{"location":"call-graph-construction/","title":"Call Graph Construction","text":"A call graph shows the method calling relationship of a program. It is a directed graph, whose nodes represent different methods, and edges represent caller -> callee relationship.
SootUp contains several call graph construction algorithms. Below, we show how you can use each of these.
"},{"location":"call-graph-construction/#creating-the-type-hierarchy","title":"Creating the Type Hierarchy","text":"All the call graph construction algorithms require the view to access the type hierarchy for resolving method calls based of sub typing relationship. Below, we show how to create a type hierarchy:
SootUpSootAnalysisInputLocation<JavaSootClass> inputLocation =\n new JavaClassPathAnalysisInputLocation(\n \"src/test/resources/Callgraph/binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nJavaProject project =\n JavaProject.builder(language)\n .addInputLocation(inputLocation)\n .addInputLocation(\n new JavaClassPathAnalysisInputLocation(\n System.getProperty(\"java.home\") + \"/lib/rt.jar\"))\n .build();\n\nJavaView view = project.createView();\n
String targetTestClassName = target.exercise1.Hierarchy.class.getName();\nG.reset();\nString userdir = System.getProperty(\"user.dir\");\nString sootCp = userdir + File.separator + \"target\" + File.separator + \"test-classes\"+ File.pathSeparator + \"lib\"+File.separator+\"rt.jar\";\nOptions.v().set_whole_program(true);\nOptions.v().set_soot_classpath(sootCp);\nOptions.v().set_no_bodies_for_excluded(true);\nOptions.v().process_dir();\nOptions.v().set_allow_phantom_refs(true);\nOptions.v().setPhaseOption(\"jb\", \"use-original-names:true\");\nOptions.v().set_prepend_classpath(false);\nSootClass c = Scene.v().forceResolve(targetTestClassName, SootClass.BODIES);\nif (c != null)\n c.setApplicationClass();\nScene.v().loadNecessaryClasses();\n\nHierarchy hierarchy = new Hierarchy();\n
"},{"location":"call-graph-construction/#defining-an-entry-method","title":"Defining an Entry Method","text":"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:
SootUpSootClassType classTypeA = project.getIdentifierFactory().getClassType(\"A\");\n\nMethodSignature entryMethodSignature =\n JavaIdentifierFactory.getInstance()\n .getMethodSignature(\n classTypeA,\n JavaIdentifierFactory.getInstance()\n .getMethodSubSignature(\n \"calc\", VoidType.getInstance(), Collections.singletonList(classTypeA))); \n
SootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\"); \n
"},{"location":"call-graph-construction/#class-hierarchy-analysis","title":"Class Hierarchy Analysis","text":"Class Hierarchy Analysis (CHA) algorithm is the most sound call graph construction algorithm available in SootUp. It soundly includes all implementers of an interface, when resolving a method call on an interface. You can construct a call graph with CHA as follows:
SootUpSootCallGraphAlgorithm cha = \n new ClassHierarchyAnalysisAlgorithm(view);\n\nCallGraph cg = \n cha.initialize(Collections.singletonList(entryMethodSignature));\n\nSystem.out.println(cg);\n
CHATransformer.v().transform();\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n }\n
"},{"location":"call-graph-construction/#rapid-type-analysis","title":"Rapid Type Analysis","text":"Rapid Type Analysis (RTA) algorithm constructs a rather precise version of the call graph that the CHA constructs. It refines CHA by considering only the instantiated implementers of an interface, when resolving a method call on an interface. You can construct a call graph with RTA as follows:
SootUpSootCallGraphAlgorithm rta = \n new RapidTypeAnalysisAlgorithm(view);\n\nCallGraph cg = \n rta.initialize(Collections.singletonList(entryMethodSignature));\n\nSystem.out.println(cg);\n
Transform sparkConfig = new Transform(\"cg.spark\", null);\nPhaseOptions.v().setPhaseOption(sparkConfig, \"enabled:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"rta:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"on-fly-cg:false\");\nMap phaseOptions = PhaseOptions.v().getPhaseOptions(sparkConfig);\nSparkTransformer.v().transform(sparkConfig.getPhaseName(), phaseOptions);\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n} \n
"},{"location":"call-graph-construction/#variable-type-analysis","title":"Variable Type Analysis","text":"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.
Info
VTA algorithm was implemented using the Spark pointer analysis framework. A reimplementation of Spark in SootUp is currently under development.
Spark requires an initial call graph to begin with. You can use one of the call graphs that we have constructed above. You can construct a call graph with VTA as follows:
SootUpSootSpark spark = new Spark.Builder(view, callGraph).vta(true).build();\nspark.analyze();\nCallGraph vtaCAllGraph = spark.getCallGraph();\n
Transform sparkConfig = new Transform(\"cg.spark\", null);\nPhaseOptions.v().setPhaseOption(sparkConfig, \"enabled:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"vta:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"on-fly-cg:false\");\nMap phaseOptions = PhaseOptions.v().getPhaseOptions(sparkConfig);\nSparkTransformer.v().transform(sparkConfig.getPhaseName(), phaseOptions);\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n} \n
"},{"location":"docguide/","title":"Docguide","text":""},{"location":"docguide/#general","title":"General","text":""},{"location":"docguide/#mkdocsextensions","title":"MkDocsExtensions","text":""},{"location":"docguide/#tooltip","title":"Tooltip","text":"Hover me
"},{"location":"docguide/#example-file-inclusion","title":"Example File inclusion","text":"this enables that tutorial code can be tested and will fail if its not up to date anymore :)
package sootup.examples.basicSetup;\n\nimport static org.junit.Assert.assertTrue;\n\nimport categories.Java8Test;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport org.junit.Ignore;\nimport org.junit.Test;\nimport org.junit.experimental.categories.Category;\nimport sootup.core.Language;\nimport sootup.core.Project;\nimport sootup.core.inputlocation.AnalysisInputLocation;\nimport sootup.core.jimple.common.expr.JVirtualInvokeExpr;\nimport sootup.core.jimple.common.stmt.JInvokeStmt;\nimport sootup.core.model.SootClass;\nimport sootup.core.model.SootMethod;\nimport sootup.core.signatures.MethodSignature;\nimport sootup.core.types.ClassType;\nimport sootup.core.views.View;\nimport sootup.java.bytecode.inputlocation.PathBasedAnalysisInputLocation;\nimport sootup.java.core.JavaProject;\nimport sootup.java.core.JavaSootClass;\nimport sootup.java.core.JavaSootClassSource;\nimport sootup.java.core.language.JavaJimple;\nimport sootup.java.core.language.JavaLanguage;\nimport sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation;\nimport sootup.jimple.parser.JimpleAnalysisInputLocation;\nimport sootup.jimple.parser.JimpleProject;\n\n/** This example illustrates how to create and use a new Soot Project. */\n@Category(Java8Test.class)\npublic class BasicSetup {\n\n @Test\n public void createSourceCodeProject() {\n Path pathToSource = Paths.get(\"src/test/resources/BasicSetup/source\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n new JavaSourcePathAnalysisInputLocation(pathToSource.toString());\n Language language = new JavaLanguage(8);\n Project project =\n JavaProject.builder((JavaLanguage) language).addInputLocation(inputLocation).build();\n }\n\n @Ignore\n public void createJimpleProject() {\n Path pathToJimple = Paths.get(\"src/test/resources/BasicSetup/jimple\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n new JimpleAnalysisInputLocation(pathToJimple);\n Project project = new JimpleProject(inputLocation);\n }\n\n @Test\n public void createByteCodeProject() {\n // Create a AnalysisInputLocation, which points to a directory. All class files will be loaded\n // from the directory\n Path pathToBinary = Paths.get(\"src/test/resources/BasicSetup/binary\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n PathBasedAnalysisInputLocation.create(pathToBinary, null);\n\n // Specify the language of the JavaProject. This is especially relevant for Multi-release jars,\n // where classes are loaded depending on the language level of the analysis\n Language language = new JavaLanguage(8);\n\n // Create a new JavaProject based on the input location\n Project project =\n JavaProject.builder((JavaLanguage) language).addInputLocation(inputLocation).build();\n\n // Create a signature for the class we want to analyze\n ClassType classType = project.getIdentifierFactory().getClassType(\"HelloWorld\");\n\n // Create a signature for the method we want to analyze\n MethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n classType, \"main\", \"void\", Collections.singletonList(\"java.lang.String[]\"));\n\n // Create a view for project, which allows us to retrieve classes\n View view = project.createView();\n\n // Assert that class is present\n assertTrue(view.getClass(classType).isPresent());\n\n // Retrieve class\n SootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n\n // Retrieve method\n view.getMethod(methodSignature);\n\n // Alternatively:\n assertTrue(sootClass.getMethod(methodSignature.getSubSignature()).isPresent());\n SootMethod sootMethod = sootClass.getMethod(methodSignature.getSubSignature()).get();\n\n // Read jimple code of method\n System.out.println(sootMethod.getBody());\n\n // Assert that Hello world print is present\n assertTrue(\n sootMethod.getBody().getStmts().stream()\n .anyMatch(\n stmt ->\n stmt instanceof JInvokeStmt\n && stmt.getInvokeExpr() instanceof JVirtualInvokeExpr\n && stmt.getInvokeExpr()\n .getArg(0)\n .equivTo(JavaJimple.getInstance().newStringConstant(\"Hello World!\"))));\n }\n}\n
"},{"location":"faq/","title":"Frequently Asked Questions","text":""},{"location":"faq/#how-to-setup-the-soot-dependency-in-maven-gradle","title":"How to setup the soot dependency (in Maven, Gradle)?","text":"See Installation.
"},{"location":"faq/#how-to-retreive-a-sootclass-or-sootmethod","title":"How to retreive a SootClass or SootMethod?","text":"See Getting Started.
"},{"location":"faq/#is-there-a-github-template-to-quickstart-into-development-with-sootup","title":"Is there a github template to quickstart into development with SootUp?","text":"Not yet.
"},{"location":"faq/#error-while-using-the-sourcecodefrontend","title":"Error while using the Sourcecodefrontend","text":"Please make sure to use Java8 to execute.
"},{"location":"faq/#exception-provider-jrt-not-found","title":"Exception: Provider \"jrt\" not found","text":"java.lang.ExceptionInInitializerError\n at sootup.java.bytecode.inputlocation.JrtFileSystemAnalysisInputLocationTest.getClassSource(JrtFileSystemAnalysisInputLocationTest.java:28)\n ...\nCaused by: java.nio.file.ProviderNotFoundException: Provider \"jrt\" not found\n
To execute SootUp with JavaModules support please make sure you run the code at least the Java9 Runtime."},{"location":"faq/#how-to-solve-a-concurrentmodificationexception","title":"How to solve a ConcurrentModificationException?","text":"Copy the Iterator into an intermediate Collection.
final StmtGraph<?> stmtGraph = builder.getStmtGraph();\n for (Stmt stmt : Lists.newArrayList(stmtGraph)){\n ...\n }\n}\n
"},{"location":"faq/#how-can-i-visualize-a-stmtgraph","title":"How can I visualize a StmtGraph?","text":"There exists a tool, that converts a StmtGraph to the Graphviz Dot Language.
DotExporter.buildGraph( stmtgraph );\n
or create a convenient link with the exported stmtgraph as HTTP GET Parameter DotExporter.createUrlToWebeditor( stmtgraph );\n
"},{"location":"faq/#is-there-a-way-to-use-code-exploration-and-syntax-highlighting-features-in-my-ide-for-jimple-files","title":"Is there a way to use code exploration and syntax highlighting features in my IDE for .jimple files?","text":"Try JimpeLsp.
"},{"location":"faq/#is-there-a-way-to-use-syntax-highlighting-of-jimple-in-my-paper-thesis","title":"Is there a way to use syntax highlighting of .jimple in my paper, thesis, ...?","text":"Have a look at LspLexer4Pygments.
"},{"location":"faq/#how-to-add-an-entry-in-this-list-ie-your-question-is-not-answered-here","title":"How to ... add an entry in this list? i.e. Your question is not answered here?","text":"Feel free to start a Discussion.
"},{"location":"getting-started/","title":"General Usage of SootUp","text":"This page walks you through the core data structures, as well as shows how to get started with SootUp.
"},{"location":"getting-started/#the-core-datastructures","title":"The core datastructures","text":"Before you get started with the SootUp library, it helps to learn about the following core data structures:
Project
: defines the outlines of an analysis. SootUp users should first create a Project
instance. It is the starting point for all operations. You can define multiple instances of Project
at the same time and there are no information shared between them. All caches are always at the project level.
Language
: represents the programming language of the analyzed code.
AnalysisInputLocation
: points to the target code to be analyzed.
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.Soot Equivalent
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.
StmtGraph
: represents the control flow graph of a method body in Jimple statements.
You can use bytecode analysis typically when you do not have access to the source code of the target program. Following example shows how to create project for analyzing Java bytecode.
Create a project to analyze Java bytecode
AnalysisInputLocation<JavaSootClass> inputLocation = \n new JavaClassPathAnalysisInputLocation(\"path2Binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project = \n JavaProject.builder(language).addInputLocation(inputLocation).build();\n
If you have access to the source code, it is also possible to create a project for analyzing source code. Following example shows how to create project for analyzing Java source code.
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.
Create a project to analyze Java source code
AnalysisInputLocation<JavaSootClass> inputLocation = \n new JavaSourcePathAnalysisInputLocation(\"path2Source\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project = \n JavaProject.builder(language).addInputLocation(inputLocation).build();\n
If you have a Jimple file, you can create a project for analyzing jimple code directly. Following example shows how to create project for analyzing jimple code.
Create a project to analyze jimple code
Path pathToJimple = Paths.get(\"path2Jimple\");\n\nAnalysisInputLocation<JavaSootClass> inputLocation = \n new JimpleAnalysisInputLocation(pathToJimple);\n\nProject project = new JimpleProject(inputLocation);\n
"},{"location":"getting-started/#creating-a-view","title":"Creating a View","text":"To create an analysis view, you can call the createView()
method on the project
object:
JavaView view = project.createView();\n
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:
JavaView view = project.createView(new LRUCacheProvider(50));\n
"},{"location":"getting-started/#retrieving-a-class","title":"Retrieving a Class","text":"Each class is identified with a unique signature adhering to Java identifier rules, therefore you first need to specify the class signature (ClassType
) as shown below.
Let's say the following is the target program that we want to analyze:
Target Program
package example;\n\npublic class HelloWorld {\n\n public HelloWorld() {\n\n }\n\n public static void main(String[] args) {\n HelloWorld hw = new HelloWorld();\n hw.hello();\n }\n\n public void hello() {\n\n }\n\n}\n
Then, we could define the ClassType
of the HelloWorld
class as follows:
Defining a ClassType
ClassType classType = \n project.getIdentifierFactory().getClassType(\"example.HelloWorld\");\n
Once we have a ClassType
that identifies the HelloWorld
class, we can use it to retrieve the corresponding SootClass
object from the view
as shown below:
Retrieving a SootClass
SootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n
"},{"location":"getting-started/#retrieving-a-method","title":"Retrieving a Method","text":"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:
Defining a MethodSignature
MethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n \"main\", // method name\n classType,\n \"void\", // return type\n Collections.singletonList(\"java.lang.String[]\")); // args\n
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:
Retrieving a SootMethod from the View
Optional<SootMethod> opt = view.getMethod(methodSignature);\n\nif(opt.isPresent()){\n SootMethod method = opt.get();\n}\n
Alternatively, we can also retrieve a SootMethod
from SootClass
that contains it.
Retrieving a SootMethod from a SootClass
Optional<? extends SootMethod> opt = sootClass.getMethod(methodSignature.getSubSignature());\n\nif(opt.isPresent()){\n SootMethod method = opt.get();\n}\n
"},{"location":"getting-started/#retrieving-the-control-flow-graph-of-a-method","title":"Retrieving the Control-Flow Graph of a Method","text":"Each SootMethod
contains a Control-Flow Graph (CFG) which is represented via the StmtGraph
. This structure is usually used for program analysis. You can retrieve the CFG of a SootMethod
as follows:
Retrieving the CFG of a SootMethod
sootMethod.getBody().getStmts();\n
Access or Download all of the code used above
BasicSetup.java
"},{"location":"getting-started/#sootup-vs-soot","title":"SootUp vs Soot","text":"Below we show a comparison of the code so far with the same functionality in sootup.
SootUpSootAnalysisInputLocation<JavaSootClass> inputLocation =\nnew JavaClassPathAnalysisInputLocation(\"path2Binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project =\n JavaProject.builder(language)\n .addInputLocation(inputLocation).build();\n\nClassType classType = \n project.getIdentifierFactory().getClassType(\"HelloWorld\");\n\nMethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n \"main\", classType, \"void\",\n Collections.singletonList(\"java.lang.String[]\"));\n\nView view = project.createView();\n\nSootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n\nSootMethod sootMethod = \n sootClass.getMethod(methodSignature.getSubSignature()).get();\n\nsootMethod.getBody().getStmts();\n
G.reset();\nString userdir = System.getProperty(\"user.dir\");\nString sootCp = \n userdir \n + File.separator \n + \"target\" \n + File.separator \n + \"test-classes\"\n + File.pathSeparator + \"lib\"+File.separator+\"rt.jar\";\n\nOptions.v().set_soot_classpath(sootCp);\nOptions.v().set_whole_program(true);\nOptions.v().setPhaseOption(\"cg.cha\", \"on\");\nOptions.v().setPhaseOption(\"cg\", \"all-reachable:true\");\nOptions.v().set_no_bodies_for_excluded(true);\nOptions.v().set_allow_phantom_refs(true);\nOptions.v().setPhaseOption(\"jb\", \"use-original-names:true\");\nOptions.v().set_prepend_classpath(false);\n\nScene.v().addBasicClass(\"java.lang.StringBuilder\");\nSootClass c = \n Scene.v().forceResolve(targetTestClassName, SootClass.BODIES);\nif (c != null) {\n c.setApplicationClass();\n}\nScene.v().loadNecessaryClasses();\n\nSootMethod method;\nfor (SootClass c : Scene.v().getApplicationClasses()) {\n if(c.getName().equals(\"example.HelloWorld\")){\n for (SootMethod m : c.getMethods()) {\n if (!m.hasActiveBody()) {\n continue;\n }\n if (m.getName().equals(\"entryPoint\")) {\n method = m;\n break;\n }\n }\n }\n}\n\nmethod.getActiveBody().getUnits();\n
"},{"location":"installation/","title":"Installation","text":""},{"location":"installation/#using-the-release","title":"Using the release","text":"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 to learn more about which modules you might need.
"},{"location":"installation/#maven","title":"Maven","text":"Add the following dependency in the pom.xml
file of your project to include all SootUp modules into your project.
<dependencies>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.core</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.core</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.sourcecode</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.bytecode</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.jimple.parser</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.callgraph</artifactId>\n <version></version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.analysis</artifactId>\n <version></version>\n </dependency>\n</dependencies>\n
"},{"location":"installation/#gradle","title":"Gradle","text":"Add the following dependency in the build.gradle
file of your project to include all SootUp modules into your project.
compile \"org.soot-oss:sootup.core:\"\ncompile \"org.soot-oss:sootup.java.core\"\ncompile \"org.soot-oss:sootup.java.sourcecode\"\ncompile \"org.soot-oss:sootup.java.bytecode\"\ncompile \"org.soot-oss:sootup.jimple.parser\"\ncompile \"org.soot-oss:sootup.callgraph\"\ncompile \"org.soot-oss:sootup.analysis\"\n
"},{"location":"installation/#building-from-source","title":"Building from Source","text":"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:
git clone https://github.com/secure-software-engineering/SootUp.git\n
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\n
Or if you want to skip tests while building:
mvn -Dskiptests install\n
"},{"location":"jimple/","title":"Jimple","text":"What is Jimple? Jimple is the intermediate representation IR of Soot, and thus SootUp. Soot's intention is to provide a simplified way to analyze JVM bytecode. JVM bytecode is stack-based, which makes it difficult for program analysis. Java source code, on the other hand, is also not quite suitable for program analysis, due to its nested structures. Therefore, Jimple aims to bring the best of both worlds, a non-stack-based and flat (non-nested) representation. 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 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.
public class HelloWorld extends java.lang.Object\n{\n public void <init>()\n {\n HelloWorld r0;\n r0 := @this: HelloWorld;\n specialinvoke r0.<java.lang.Object: void <init>()>();\n return;\n }\n\n public static void main(java.lang.String[])\n {\n java.lang.String[] r0;\n java.io.PrintStream $r1;\n\n r0 := @parameter0: java.lang.String[];\n $r1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $r1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Hello world!\");\n return;\n }\n}\n
public class HelloWorld {\n\n public HelloWorld() {\n\n }\n\n public static void main(String[] var0) {\n System.out.println(\"Hello World!\");\n }\n\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class analysis/HelloWorld {\n\n// compiled from: HelloWorld.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 4 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 6 L1\n RETURN\n L2\n LOCALVARIABLE this Lanalysis/HelloWorld; L0 L2 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static main([Ljava/lang/String;)V\n L0\n LINENUMBER 9 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Hello World!\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 10 L1\n RETURN\n L2\n LOCALVARIABLE var0 [Ljava/lang/String; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jimple-grammar-structure","title":"Jimple Grammar Structure","text":"Jimple mimics the JVMs class file structure. Therefore it is object oriented. A Single Class (or Interface) per file. Three-Address-Code which means there are no nested expressions. (nested expressions can be modeled via Locals that store intermediate calculation results.)
"},{"location":"jimple/#class-or-interface","title":"Class (or Interface)","text":"A class consists of Fields and Methods. It is referenced by its ClassType.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n}\n
package target.exercise1;\n\npublic class DemoClass {}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#field","title":"Field","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: double pi> = 3.14;\n return;\n }\n}\n/*\n \"this.<target.exercise1.DemoClass: double pi>\" is JInstanceFieldRef\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private final double pi = 3.14;\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x12\nprivate final D pi = 3.14\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n LDC 3.14\n PUTFIELD target/exercise1/DemoClass.pi : D\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#method-and-the-body","title":"Method and the Body","text":"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 that models the sequence of single instructions/statements (Stmts).
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n virtualinvoke this.<target.exercise1.DemoClass: \n void demoMethod()>();\n return;\n }\n\n public void demoMethod()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Inside method.\");\n return;\n }\n}\n/*\n \"<target.exercise1.DemoClass: void demoMethod()>\" \n and \"<target.exercise1.DemoClass: void <init>()>\" \n are instances of SootMethod \n*/\n
package target.exercise1;\n\npublic class DemoClass {\n DemoClass(){\n demoMethod();\n }\n public void demoMethod(){\n System.out.println(\"Inside method.\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x0\n<init>()V\n L0\n LINENUMBER 5 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 6 L1\n ALOAD 0\n INVOKEVIRTUAL target/exercise1/DemoClass.demoMethod ()V\n L2\n LINENUMBER 7 L2\n RETURN\n L3\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L3 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic demoMethod()V\n L0\n LINENUMBER 10 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Inside method.\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 11 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#signatures","title":"Signatures","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: double pi> = 3.14;\n return;\n }\n\n public void demoMethod()\n {\n java.io.PrintStream $stack3, $stack5;\n java.lang.StringBuilder $stack4, $stack6, $stack7;\n java.lang.String $stack8;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"pi : 3.14\");\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n $stack4 = new java.lang.StringBuilder;\n\n specialinvoke $stack4.<java.lang.StringBuilder: void <init>()>();\n $stack6 = virtualinvoke $stack4.<java.lang.StringBuilder: \n java.lang.StringBuilder append(java.lang.String)>\n (\"pi : \");\n $stack7 = virtualinvoke $stack6.<java.lang.StringBuilder: \n java.lang.StringBuilder append(double)>(3.1415);\n $stack8 = virtualinvoke $stack7.<java.lang.StringBuilder: \n java.lang.String toString()>();\n\n virtualinvoke $stack5.<java.io.PrintStream: \n void println(java.lang.String)>($stack8);\n return;\n }\n}\n/*\n For JInstanceFieldRef \"this.<target.exercise1.DemoClass: double pi>\" \n signature is <target.exercise1.DemoClass: double pi>\n Similarly, we have other signatures like \n <java.lang.Object: void <init>()>, \n <java.io.PrintStream: void println(java.lang.String)> \n and so on. \n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private final double pi = 3.14;\n\n public void demoMethod(){\n double localPi = 3.1415;\n System.out.println(\"pi : \" + pi);\n System.out.println(\"pi : \" + localPi);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x12\nprivate final D pi = 3.14\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n LDC 3.14\n PUTFIELD target/exercise1/DemoClass.pi : D\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n\n// access flags 0x1\npublic demoMethod()V\n L0\n LINENUMBER 6 L0\n LDC 3.1415\n DSTORE 1\n L1\n LINENUMBER 7 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"pi : 3.14\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L2\n LINENUMBER 8 L2\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n NEW java/lang/StringBuilder\n DUP\n INVOKESPECIAL java/lang/StringBuilder.<init> ()V\n LDC \"pi : \"\n INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)\n Ljava/lang/StringBuilder;\n DLOAD 1\n INVOKEVIRTUAL java/lang/StringBuilder.append (D)Ljava/lang/StringBuilder;\n INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 9 L3\n RETURN\n L4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0\n LOCALVARIABLE localPi D L1 L4 1\n MAXSTACK = 4\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#trap","title":"Trap","text":"A Trap is a mechanism to model exceptional flow.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void divideExample(int, int)\n {\n int x, y, $stack4;\n java.io.PrintStream $stack5, $stack7;\n java.lang.Exception $stack6;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n y := @parameter1: int;\n\n label1:\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n $stack4 = x / y;\n virtualinvoke $stack5.<java.io.PrintStream: void println(int)>($stack4);\n\n label2:\n goto label4;\n\n label3:\n $stack6 := @caughtexception;\n $stack7 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack7.<java.io.PrintStream: \n void println(java.lang.String)>(\"Exception caught\");\n\n label4:\n return;\n\n catch java.lang.Exception from label1 to label2 with label3;\n }\n}\n/*\n By calling getTraps() method, we can get the Traip chain.\n For the above jimple code, we have the below trap:\n Trap :\n begin : $stack5 = <java.lang.System: java.io.PrintStream out>\n end : goto [?= return]\n handler: $stack6 := @caughtexception\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void divideExample(int x, int y){\n try {\n System.out.println(x / y);\n }catch (Exception e){\n System.out.println(\"Exception caught\");\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic divideExample(II)V\n TRYCATCHBLOCK L0 L1 L2 java/lang/Exception\n L0\n LINENUMBER 6 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n ILOAD 2\n IDIV\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L1\n LINENUMBER 9 L1\n GOTO L3\n L2\n LINENUMBER 7 L2\n FRAME SAME1 java/lang/Exception\n ASTORE 3\n L4\n LINENUMBER 8 L4\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Exception caught\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 10 L3\n FRAME SAME\n RETURN\n L5\n LOCALVARIABLE e Ljava/lang/Exception; L4 L3 3\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE x I L0 L5 1\n LOCALVARIABLE y I L0 L5 2\n MAXSTACK = 3\n MAXLOCALS = 4\n}\n
"},{"location":"jimple/#stmt","title":"Stmt","text":"The main piece of Jimple is a Statement (Stmt). Stmts represent that can be executed by the JVM.
"},{"location":"jimple/#branching-statements","title":"Branching Statements","text":"A BranchingStmt's job is to model the flow between Stmts.
"},{"location":"jimple/#jgotostmt","title":"JGotoStmt","text":"for unconditional flow.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n public static void sampleMethod()\n {\n int i;\n i = 0;\n\n label1:\n if i >= 5 goto label3;\n if i != 3 goto label2;\n goto label3;\n\n label2:\n i = i + 1;\n goto label1;\n\n label3:\n return;\n }\n}\n/*\n Here for statements \"goto label3;\" and \"goto label1;\", \n we have two instances of JGotoStmt : \n \"goto[?=return]\" and \"goto[?=(branch)]\".\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public static void sampleMethod(){\n label1:\n for (int i = 0; i < 5; i++){\n if(i == 3){\n break label1;\n }\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static sampleMethod()V\n L0\n LINENUMBER 6 L0\n ICONST_0\n ISTORE 0\n L1\n FRAME APPEND [I]\n ILOAD 0\n ICONST_5\n IF_ICMPGE L2\n L3\n LINENUMBER 7 L3\n ILOAD 0\n ICONST_3\n IF_ICMPNE L4\n L5\n LINENUMBER 8 L5\n GOTO L2\n L4\n LINENUMBER 6 L4\n FRAME SAME\n IINC 0 1\n GOTO L1\n L2\n LINENUMBER 11 L2\n FRAME CHOP 1\n RETURN\n LOCALVARIABLE i I L1 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jifstmt","title":"JIfStmt","text":"for conditional flow depending on boolean Expression (AbstractConditionExpr) so they have two successor Stmt's.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public static void sampleMethod(int)\n {\n int x, $stack1;\n java.io.PrintStream $stack2, $stack3;\n\n x := @parameter0: int;\n\n $stack1 = x % 2;\n if $stack1 != 0 goto label1;\n\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"Even\");\n goto label2;\n\n label1:\n $stack2 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack2.<java.io.PrintStream: \n void println(java.lang.String)>(\"Odd\");\n\n label2:\n return;\n }\n}\n/*\n For statement \"if $stack1 != 0 goto label1;\", \n we have an instance of JIfStmt :\n \"if $stack1 != 0 goto $stack2 \n = <java.lang.System:java.io.PrintStream out>\".\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public static void sampleMethod(int x){\n if(x % 2 == 0){\n System.out.println(\"Even\");\n }else{\n System.out.println(\"Odd\");\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static sampleMethod(I)V\n L0\n LINENUMBER 5 L0\n ILOAD 0\n ICONST_2\n IREM\n IFNE L1\n L2\n LINENUMBER 6 L2\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Even\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n GOTO L3\n L1\n LINENUMBER 8 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Odd\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 10 L3\n FRAME SAME\n RETURN\n L4\n LOCALVARIABLE x I L0 L4 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jswitchstmt","title":"JSwitchStmt","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void switchExample(int)\n {\n int x;\n java.io.PrintStream $stack2, $stack3, $stack4;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n lookupswitch(x)\n {\n case 1: goto label1;\n case 2: goto label2;\n default: goto label3;\n };\n\n label1:\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input 1\");\n goto label4;\n\n label2:\n $stack2 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack2.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input 2\");\n goto label4;\n\n label3:\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input more than 2\");\n\n label4:\n return;\n }\n}\n/*\n Here for below statement:\n lookupswitch(x)\n {\n case 1: goto label1;\n case 2: goto label2;\n default: goto label3;\n };\n\n we have an instance of JLookupSwitchStmt :\n lookupswitch(x) \n { \n case 1: goto $stack3 \n = <java.lang.System: java.io.PrintStream out>; \n case 2: goto $stack2 \n = <java.lang.System: java.io.PrintStream out>; \n default: goto $stack4 \n = <java.lang.System: java.io.PrintStream out>; \n }\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void switchExample(int x){\n switch (x){\n case 1:\n System.out.println(\"Input 1\");\n break;\n\n case 2:\n System.out.println(\"Input 2\");\n break;\n\n default:\n System.out.println(\"Input more than 2\");\n break;\n\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic switchExample(I)V\n L0\n LINENUMBER 5 L0\n ILOAD 1\n LOOKUPSWITCH\n 1: L1\n 2: L2\n default: L3\n L1\n LINENUMBER 7 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input 1\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L4\n LINENUMBER 8 L4\n GOTO L5\n L2\n LINENUMBER 11 L2\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input 2\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L6\n LINENUMBER 12 L6\n GOTO L5\n L3\n LINENUMBER 15 L3\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input more than 2\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L5\n LINENUMBER 19 L5\n FRAME SAME\n RETURN\n L7\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L7 0\n LOCALVARIABLE x I L0 L7 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jreturnstmt-jreturnvoidstmt","title":"JReturnStmt & JReturnVoidStmt","text":"They end the execution/flow inside the current method and return (a value) to its caller.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public int increment(int)\n {\n int x, $stack2;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n $stack2 = x + 1;\n return $stack2;\n }\n\n public void print()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Inside method print\");\n return;\n }\n}\n/*\n \"return $stack2\" is JReturnStmt.\n \"return\" is JReturnVoidStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public int increment(int x){\n return x + 1;\n }\n public void print(){\n System.out.println(\"Inside method print\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic increment(I)I\n L0\n LINENUMBER 5 L0\n ILOAD 1\n ICONST_1\n IADD\n IRETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE x I L0 L1 1\n MAXSTACK = 2\n MAXLOCALS = 2\n\n// access flags 0x1\npublic print()V\n L0\n LINENUMBER 8 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Inside method print\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 9 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jthrowstmt","title":"JThrowStmt","text":"Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void divideExample(int, int)\n {\n int y, x, $stack6;\n java.lang.StringBuilder $stack3, $stack5, $stack7;\n java.io.PrintStream $stack4;\n java.lang.String $stack8;\n java.lang.RuntimeException $stack9;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n y := @parameter1: int;\n\n if y != 0 goto label1;\n\n $stack9 = new java.lang.RuntimeException;\n specialinvoke $stack9.<java.lang.RuntimeException: \n void <init>(java.lang.String)>(\"Divide by zero error\");\n throw $stack9;\n\n label1:\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n $stack3 = new java.lang.StringBuilder;\n specialinvoke $stack3.<java.lang.StringBuilder: void <init>()>();\n\n $stack5 = virtualinvoke $stack3.<java.lang.StringBuilder: \n java.lang.StringBuilder append(java.lang.String)>(\"Divide result : \");\n $stack6 = x / y;\n $stack7 = virtualinvoke $stack5.<java.lang.StringBuilder: \n java.lang.StringBuilder append(int)>($stack6);\n $stack8 = virtualinvoke $stack7.<java.lang.StringBuilder: \n java.lang.String toString()>();\n\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(java.lang.String)>($stack8);\n return;\n }\n}\n/*\n \"throw $stack9\" is JThrowStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void divideExample(int x, int y){\n if(y == 0){\n throw new RuntimeException(\"Divide by zero error\");\n }\n System.out.println(\"Divide result : \" + x / y);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic divideExample(II)V\n L0\n LINENUMBER 5 L0\n ILOAD 2\n IFNE L1\n L2\n LINENUMBER 6 L2\n NEW java/lang/RuntimeException\n DUP\n LDC \"Divide by zero error\"\n INVOKESPECIAL java/lang/RuntimeException.<init> \n (Ljava/lang/String;)V\n ATHROW\n L1\n LINENUMBER 8 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n NEW java/lang/StringBuilder\n DUP\n INVOKESPECIAL java/lang/StringBuilder.<init> ()V\n LDC \"Divide result : \"\n INVOKEVIRTUAL java/lang/StringBuilder.append \n (Ljava/lang/String;)Ljava/lang/StringBuilder;\n ILOAD 1\n ILOAD 2\n IDIV\n INVOKEVIRTUAL java/lang/StringBuilder.append \n (I)Ljava/lang/StringBuilder;\n INVOKEVIRTUAL java/lang/StringBuilder.toString \n ()Ljava/lang/String;\n INVOKEVIRTUAL java/io/PrintStream.println \n (Ljava/lang/String;)V\n L3\n LINENUMBER 9 L3\n RETURN\n L4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0\n LOCALVARIABLE x I L0 L4 1\n LOCALVARIABLE y I L0 L4 2\n MAXSTACK = 4\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#jinvokestmt","title":"JInvokeStmt","text":"transfers the control flow to another method until the called method returns.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void print(int)\n {\n target.exercise1.DemoClass this;\n int x, a;\n java.io.PrintStream $stack4, $stack6;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n a = virtualinvoke this.<target.exercise1.DemoClass: \n int increment(int)>(x);\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(int)>(a);\n\n a = virtualinvoke this.<target.exercise1.DemoClass: \n int increment(int)>(a);\n $stack6 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack6.<java.io.PrintStream: \n void println(int)>(a);\n\n return;\n }\n\n public int increment(int)\n {\n int x, $stack2;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n $stack2 = x + 1;\n return $stack2;\n }\n}\n/*\n \"specialinvoke this.<java.lang.Object: void <init>()>()\", \n \"virtualinvoke this.<target.exercise1.DemoClass: int increment(int)>(x)\", \n \"virtualinvoke this.<target.exercise1.DemoClass: int increment(int)>(a)\" \n are JInvokeStmts.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void print(int x){\n int a = increment(x);\n System.out.println(a);\n a = increment(a);\n System.out.println(a);\n }\n public int increment(int x){\n return x + 1;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic print(I)V\n L0\n LINENUMBER 5 L0\n ALOAD 0\n ILOAD 1\n INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I\n ISTORE 2\n L1\n LINENUMBER 6 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L2\n LINENUMBER 7 L2\n ALOAD 0\n ILOAD 2\n INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I\n ISTORE 2\n L3\n LINENUMBER 8 L3\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L4\n LINENUMBER 9 L4\n RETURN\n L5\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE x I L0 L5 1\n LOCALVARIABLE a I L1 L5 2\n MAXSTACK = 2\n MAXLOCALS = 3\n\n// access flags 0x1\npublic increment(I)I\n L0\n LINENUMBER 11 L0\n ILOAD 1\n ICONST_1\n IADD\n IRETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE x I L0 L1 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jassignstmt","title":"JAssignStmt","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: int counter> = 0;\n return;\n }\n\n public int updateCounter()\n {\n target.exercise1.DemoClass this;\n int $stack1, $stack2, $stack3;\n\n this := @this: target.exercise1.DemoClass;\n\n $stack1 = this.<target.exercise1.DemoClass: int counter>;\n $stack2 = $stack1 + 1;\n this.<target.exercise1.DemoClass: int counter> = $stack2;\n $stack3 = this.<target.exercise1.DemoClass: int counter>;\n\n return $stack3;\n }\n}\n/*\n \"this.<target.exercise1.DemoClass: int counter> = 0\", \n \"$stack1 = this.<target.exercise1.DemoClass: int counter>\",\n \"$stack2 = $stack1 + 1\"\n \"this.<target.exercise1.DemoClass: int counter> = $stack2\"\n \"$stack3 = this.<target.exercise1.DemoClass: int counter>\"\n are JAssignStmts.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter = 0;\n public int updateCounter(){\n counter = counter + 1;\n return counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n ICONST_0\n PUTFIELD target/exercise1/DemoClass.counter : I\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n\n// access flags 0x1\npublic updateCounter()I\n L0\n LINENUMBER 6 L0\n ALOAD 0\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n ICONST_1\n IADD\n PUTFIELD target/exercise1/DemoClass.counter : I\n L1\n LINENUMBER 7 L1\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n IRETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jidentitystmt","title":"JIdentityStmt","text":"is semantically like the JAssignStmt and handles assignments of IdentityRef's to make implicit assignments explicit into the StmtGraph.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void DemoClass(int)\n {\n target.exercise1.DemoClass this;\n int counter;\n\n this := @this: target.exercise1.DemoClass;\n counter := @parameter0: int;\n this.<target.exercise1.DemoClass: int counter> = counter;\n return;\n }\n}\n/*\n \"this := @this: target.exercise1.DemoClass\" and \n \"counter := @parameter0: int\" are JIdentityStmts\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter;\n public void DemoClass(int counter){\n this.counter = counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic DemoClass(I)V\n L0\n LINENUMBER 6 L0\n ALOAD 0\n ILOAD 1\n PUTFIELD target/exercise1/DemoClass.counter : I\n L1\n LINENUMBER 7 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n LOCALVARIABLE counter I L0 L2 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jentermonitorstmt-jexitmonitorstmt","title":"JEnterMonitorStmt & JExitMonitorStmt","text":"marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: int counter> = 0;\n return;\n }\n\n public int updateCounter()\n {\n target.exercise1.DemoClass this;\n int $stack4, $stack5, $stack7;\n java.lang.Throwable $stack8;\n\n this := @this: target.exercise1.DemoClass;\n\n entermonitor this;\n\n label1:\n $stack4 = this.<target.exercise1.DemoClass: int counter>;\n $stack5 = $stack4 + 1;\n this.<target.exercise1.DemoClass: int counter> = $stack5;\n\n exitmonitor this;\n\n label2:\n goto label5;\n\n label3:\n $stack8 := @caughtexception;\n\n exitmonitor this;\n\n label4:\n throw $stack8;\n\n label5:\n $stack7 = this.<target.exercise1.DemoClass: int counter>;\n return $stack7;\n\n catch java.lang.Throwable from label1 to label2 with label3;\n catch java.lang.Throwable from label3 to label4 with label3;\n }\n}\n/*\n \"entermonitor this\" is JEnterMonitorStmt.\n \"exitmonitor this\" is JExitMonitorStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter = 0;\n public int updateCounter(){\n synchronized (this) {\n counter = counter + 1;\n }\n return counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n ICONST_0\n PUTFIELD target/exercise1/DemoClass.counter : I\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n\n// access flags 0x1\npublic updateCounter()I\n TRYCATCHBLOCK L0 L1 L2 null\n TRYCATCHBLOCK L2 L3 L2 null\n L4\n LINENUMBER 6 L4\n ALOAD 0\n DUP\n ASTORE 1\n MONITORENTER\n L0\n LINENUMBER 7 L0\n ALOAD 0\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n ICONST_1\n IADD\n PUTFIELD target/exercise1/DemoClass.counter : I\n L5\n LINENUMBER 8 L5\n ALOAD 1\n MONITOREXIT\n L1\n GOTO L6\n L2\n FRAME FULL [target/exercise1/DemoClass java/lang/Object] \n [java/lang/Throwable]\n ASTORE 2\n ALOAD 1\n MONITOREXIT\n L3\n ALOAD 2\n ATHROW\n L6\n LINENUMBER 9 L6\n FRAME CHOP 1\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n IRETURN\n L7\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L4 L7 0\n MAXSTACK = 3\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#jretstmt","title":"JRetStmt","text":""},{"location":"jimple/#jbreakpointstmt","title":"JBreakpointStmt","text":"models a Breakpoint set by a Debugger (usually not relevant for static analyses)
"},{"location":"jimple/#immediate","title":"Immediate","text":"An Immediate has a given Type and consists of a Local (\"a Variable\", \"Something that contains a Value\") or a Constant (\"Something that is a Value\").
"},{"location":"jimple/#type","title":"Type","text":"VoidType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void voidMethod()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"In voidMethod().\");\n return;\n }\n}\n/*\n For the SootMethod - <target.exercise1.DemoClass: void voidMethod()>, \n returnType is instance of VoidType.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void voidMethod(){\n System.out.println(\"In voidMethod().\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic voidMethod()V\n L0\n LINENUMBER 5 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"In voidMethod().\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 6 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#primarytype","title":"PrimaryType","text":"BooleanType, ByteType, CharType, ShortType, IntType, LongType, DoubleType, FloatType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n\n public void display()\n {\n java.io.PrintStream $stack11, $stack13, $stack15, \n $stack17, $stack19, $stack21, $stack23, $stack25;\n int $stack12, $stack14, $stack16, $stack18;\n long $stack20;\n double $stack22;\n float $stack24;\n target.exercise1.DemoClass this;\n boolean $stack26;\n\n this := @this: target.exercise1.DemoClass;\n\n $stack11 = <java.lang.System: java.io.PrintStream out>;\n\n goto label1;\n\n label1:\n $stack26 = 0;\n virtualinvoke $stack11.<java.io.PrintStream: \n void println(boolean)>($stack26);\n\n $stack13 = <java.lang.System: java.io.PrintStream out>;\n $stack12 = 127 - 1;\n virtualinvoke $stack13.<java.io.PrintStream: \n void println(int)>($stack12);\n\n $stack15 = <java.lang.System: java.io.PrintStream out>;\n $stack14 = 97 + 1;\n virtualinvoke $stack15.<java.io.PrintStream: \n void println(int)>($stack14);\n\n $stack17 = <java.lang.System: java.io.PrintStream out>;\n $stack16 = 1123 + 1;\n virtualinvoke $stack17.<java.io.PrintStream: \n void println(int)>($stack16);\n\n $stack19 = <java.lang.System: java.io.PrintStream out>;\n $stack18 = 123456 + 1;\n virtualinvoke $stack19.<java.io.PrintStream: \n void println(int)>($stack18);\n\n $stack21 = <java.lang.System: java.io.PrintStream out>;\n $stack20 = 10L + 1L;\n virtualinvoke $stack21.<java.io.PrintStream: \n void println(long)>($stack20);\n\n $stack23 = <java.lang.System: java.io.PrintStream out>;\n $stack22 = 10.1 + 1.0;\n virtualinvoke $stack23.<java.io.PrintStream: \n void println(double)>($stack22);\n\n $stack25 = <java.lang.System: java.io.PrintStream out>;\n $stack24 = 10.1F + 1.0F;\n virtualinvoke $stack25.<java.io.PrintStream: \n void println(float)>($stack24);\n\n return;\n }\n}\n/*\n The JimpleLocal $stack12, $stack14, $stack16, $stack18 are of IntType. \n Similarly, $stack20 is of LongType, $stack22 is of DoubleType and so on.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void display(){\n boolean varBoolean = true;\n byte varByte = 127;\n char varChar = 'a';\n short varShort = 1123;\n int varInt = 123456;\n long varLong = 10L;\n double varDouble = 10.10;\n float varFloat = 10.10f;\n\n System.out.println(!varBoolean);\n System.out.println(varByte-1);\n System.out.println(varChar+1);\n System.out.println(varShort+1);\n System.out.println(varInt+1);\n System.out.println(varLong+1);\n System.out.println(varDouble+1);\n System.out.println(varFloat+1);\n\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic display()V\n L0\n LINENUMBER 5 L0\n ICONST_1\n ISTORE 1\n L1\n LINENUMBER 6 L1\n BIPUSH 127\n ISTORE 2\n L2\n LINENUMBER 7 L2\n BIPUSH 97\n ISTORE 3\n L3\n LINENUMBER 8 L3\n SIPUSH 1123\n ISTORE 4\n L4\n LINENUMBER 9 L4\n LDC 123456\n ISTORE 5\n L5\n LINENUMBER 10 L5\n LDC 10\n LSTORE 6\n L6\n LINENUMBER 11 L6\n LDC 10.1\n DSTORE 8\n L7\n LINENUMBER 12 L7\n LDC 10.1\n FSTORE 10\n L8\n LINENUMBER 14 L8\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n IFNE L9\n ICONST_1\n GOTO L10\n L9\n FRAME FULL [target/exercise1/DemoClass I I I I I J D F] \n [java/io/PrintStream]\n ICONST_0\n L10\n FRAME FULL [target/exercise1/DemoClass I I I I I J D F] \n [java/io/PrintStream I]\n INVOKEVIRTUAL java/io/PrintStream.println (Z)V\n L11\n LINENUMBER 15 L11\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n ICONST_1\n ISUB\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L12\n LINENUMBER 16 L12\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 3\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L13\n LINENUMBER 17 L13\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 4\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L14\n LINENUMBER 18 L14\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 5\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L15\n LINENUMBER 19 L15\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LLOAD 6\n LCONST_1\n LADD\n INVOKEVIRTUAL java/io/PrintStream.println (J)V\n L16\n LINENUMBER 20 L16\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n DLOAD 8\n DCONST_1\n DADD\n INVOKEVIRTUAL java/io/PrintStream.println (D)V\n L17\n LINENUMBER 21 L17\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n FLOAD 10\n FCONST_1\n FADD\n INVOKEVIRTUAL java/io/PrintStream.println (F)V\n L18\n LINENUMBER 23 L18\n RETURN\n L19\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L19 0\n LOCALVARIABLE varBoolean Z L1 L19 1\n LOCALVARIABLE varByte B L2 L19 2\n LOCALVARIABLE varChar C L3 L19 3\n LOCALVARIABLE varShort S L4 L19 4\n LOCALVARIABLE varInt I L5 L19 5\n LOCALVARIABLE varLong J L6 L19 6\n LOCALVARIABLE varDouble D L7 L19 8\n LOCALVARIABLE varFloat F L8 L19 10\n MAXSTACK = 5\n MAXLOCALS = 11\n}\n
"},{"location":"jimple/#referencetype","title":"ReferenceType","text":"ClassType, ArrayType NullType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\npublic void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public target.exercise1.DemoClass getObject(target.exercise1.DemoClass)\n {\n target.exercise1.DemoClass obj, this;\n this := @this: target.exercise1.DemoClass;\n obj := @parameter0: target.exercise1.DemoClass;\n return obj;\n }\n\n public void compute(boolean)\n {\n int[] b;\n java.io.PrintStream $stack5, $stack6;\n boolean check;\n target.exercise1.DemoClass this;\n int i;\n null_type $r0;\n java.lang.NullPointerException soot0;\n this := @this: target.exercise1.DemoClass;\n check := @parameter0: boolean;\n b = newarray (int)[5];\n i = 0;\n\n label1:\n if i >= 5 goto label3;\n if check == 0 goto label2;\n $r0 = (null_type) i;\n soot0 = new java.lang.NullPointerException;\n specialinvoke soot0.<java.lang.NullPointerException: \n void <init>(java.lang.String)>\n (\"This statement would have triggered an Exception: a[i#1] = $r0\");\n throw soot0;\n\n label2:\n b[i] = i;\n i = i + 1;\n goto label1;\n\n label3:\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack5.<java.io.PrintStream: \n void println(java.lang.Object)>(b);\n $stack6 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack6.<java.io.PrintStream: \n void println(java.lang.Object)>(null);\n return;\n }\n}\n/*\n The JimpleLocal b is of ArrayType,\n and JimpleLocal $r0 is of NullType.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n\n public DemoClass getObject(DemoClass obj){\n return obj;\n }\n\n public void compute(boolean check){\n int a[] = null;\n int b[] = new int[5];\n for (int i = 0; i < 5; i++) {\n if(check){\n a[i] = i;\n }\n b[i] = i;\n }\n System.out.println(b);\n System.out.println(a);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic getObject(Ltarget/exercise1/DemoClass;)Ltarget/exercise1/DemoClass;\n L0\n LINENUMBER 6 L0\n ALOAD 1\n ARETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE obj Ltarget/exercise1/DemoClass; L0 L1 1\n MAXSTACK = 1\n MAXLOCALS = 2\n\n// access flags 0x1\npublic compute(Z)V\n L0\n LINENUMBER 10 L0\n ACONST_NULL\n ASTORE 2\n L1\n LINENUMBER 11 L1\n ICONST_5\n NEWARRAY T_INT\n ASTORE 3\n L2\n LINENUMBER 12 L2\n ICONST_0\n ISTORE 4\n L3\n FRAME APPEND [[I [I I]\n ILOAD 4\n ICONST_5\n IF_ICMPGE L4\n L5\n LINENUMBER 13 L5\n ILOAD 1\n IFEQ L6\n L7\n LINENUMBER 14 L7\n ALOAD 2\n ILOAD 4\n ILOAD 4\n IASTORE\n L6\n LINENUMBER 16 L6\n FRAME SAME\n ALOAD 3\n ILOAD 4\n ILOAD 4\n IASTORE\n L8\n LINENUMBER 12 L8\n IINC 4 1\n GOTO L3\n L4\n LINENUMBER 18 L4\n FRAME CHOP 1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ALOAD 3\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V\n L9\n LINENUMBER 19 L9\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ALOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V\n L10\n LINENUMBER 20 L10\n RETURN\n L11\n LOCALVARIABLE i I L3 L4 4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L11 0\n LOCALVARIABLE check Z L0 L11 1\n LOCALVARIABLE a [I L1 L11 2\n LOCALVARIABLE b [I L2 L11 3\n MAXSTACK = 3\n MAXLOCALS = 5\n}\n
"},{"location":"jimple/#local","title":"Local","text":"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 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;\n$stack2 = <java.lang.System: java.io.PrintStream out>;\nvirtualinvoke $stack2.<java.io.PrintStream: void println(int)>(1);\n\nlocal#2 = this.<target.exercise1.DemoClass: int global>;\n$stack3 = <java.lang.System: java.io.PrintStream out>;\nvirtualinvoke $stack3.<java.io.PrintStream: void println(int)>(local#2);\nreturn;\n
} } /* $stack2, this, $stack3, local#2 are all JimpleLocal.
\"this := @this: target.exercise1.DemoClass\" is JIdentityStmt
\"$stack2 = \", \"local#2 = this.\", \"$stack3 = \" are JAssignStmt
*/ ```
package target.exercise1;\n\npublic class DemoClass {\n\n private int global;\n\n public void compute(){\n int local;\n local = 1;\n System.out.println(local);\n local = this.global;\n System.out.println(local);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I global\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic compute()V\n L0\n LINENUMBER 9 L0\n ICONST_1\n ISTORE 1\n L1\n LINENUMBER 10 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L2\n LINENUMBER 11 L2\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.global : I\n ISTORE 1\n L3\n LINENUMBER 12 L3\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L4\n LINENUMBER 14 L4\n RETURN\n L5\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE local I L1 L5 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#constant","title":"Constant","text":"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.
"},{"location":"jimple/#expr","title":"Expr","text":"An expression is a language construct that returns a value. E.g. a binary operation such as addition.
"},{"location":"jimple/#ref","title":"Ref","text":""},{"location":"jimple/#jarrayref","title":"JArrayRef","text":"jimple $arr[1]
referencing a position inside an array.
jimple <SomePackage.ExampleClass: fieldname> // or $r1.<SomePackage.ExampleClass: fieldname>
referencing a Field via its FieldSignature and if necessary (i.e. with JInstanceFieldRef) the corresponding Local instance that points to the object instance.
The IdentityRef makes those implicit special value assignments explicit.
"},{"location":"jimple/#jthisref","title":"JThisRef","text":"jimple @this: package.fruit.Banana
represents the this pointer of the current class.
jimple @caughtexception
represents the value of the thrown exception (caught by this exceptionhandler).
jimple $i0 := @parameter0 $i1 := @parameter1
represents a parameter of a method, identified by its index.
While Soot is a library and a stand-alone command-line application. SootUp, on the other hand, is designed to be a core library. It assumes that it is embedded in a client application that owns the thread of control. It can be extended with a command-line interface, included in other software projects as a library, or integrated into IDEs with JimpleLSP.
"},{"location":"whatsnew/#modular-architecture","title":"Modular Architecture","text":"SootUp has a modular architecture, which enables its clients to include only the necessary functionality to their applications.
Singletons offer a single view of a single program version, which makes it impossible to analyze multiple programs or multiple versions of the same program. SootUp does not make use of singletons such the Scene
class in the old Soot any more. It enables analyzing multple programs simultaneously.
Soot's JastAdd-based java frontend is not maintained anymore. In SootUp, we use WALA's well-maintained source code frontend, which will not only allow Soot to analyze Java source code, but also JavaScript and Python.
"},{"location":"whatsnew/#immutable-by-design","title":"Immutable by Design","text":"SootUp has been designed with the goal of immutability in mind. This makes sharing objects between several entities easier, because there is no need to worry about unintended changes to other entities.
"},{"location":"whatsnew/#withers-instead-of-setters","title":"Withers instead of Setters","text":"Due to the goal of immutability, many classes do not have setters anymore. For example, a Body
does not have a method setStmts(List<Stmt> stmts)
. Instead, a method called withStmts(List<Stmt> stmts)
has been added. This does not modify the original instance, but returns a copy of the Body but with the provided stmts
in its instance. This concept of so-called with
-ers can be found all throughout SootUp.
A simplified example
class Body {\n final List<Stmt> stmts;\n final List<Local> locals;\n\n Body(List<Stmt> stmts, List<Local> locals) {\n this.stmts = stmts;\n this.locals = locals;\n } \n\n Body withStmts(List<Stmt> stmts) { return new Body(stmts, this.locals); }\n Body withLocals(List<Local> locals) { return new Body(this.stmts, locals); }\n}\n
"},{"location":"whatsnew/#intermediate-representation","title":"Intermediate Representation","text":"Jimple is the only intermediate representation (IR) in SootUp. We modified it slightly to be able to accommodate different programming languages in the future.
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"What's SootUp?","text":"SootUp is a complete overhaul of the good, old static analysis framework Soot.
Important
SootUp is not a version update to Soot, it is instead a completely new implementation written from scratch that aims to be a leaner, more extensible equivalent of soot.
"},{"location":"#why-sootup","title":"Why SootUp?","text":""},{"location":"#click-here-to-read-our-announcement-on-the-first-release-of-sootup","title":"Click here to read our announcement on the first release of SootUp","text":"Over the 20+ years, SootUps predecessor Soot has evolved into a powerful framework, which is one of the most widely used tools in the static analysis community. This evolution was guided by the needs of the community and carried out with ad-hoc improvements. As a result, Soot has become a tool that can do a multitude of things, but it is heavy and hard to maintain and comprehend. So there was the need to clean up the codebase e.g. improve the software architecture, remove legacy datastructures that weren't in the Java Runtime at the time of Soots creation, enforce validation to have a sane state, removing the necessity of arcane knowledge, document it more and more - to make Soot future prove. So we introduced Design changes in SootUp, which aim to address Soot's shortcomings. The goal is a lighter library that can easily be understood and maintained to be included in other projects.
"},{"location":"#is-this-a-drop-in-replacement-for-soot","title":"Is this a drop-in replacement for Soot?","text":"Not really. SootUp has a completely new architecture and API, so it is not trivial to update existing projects that build on soot. We recommend using SootUp for greenfield projects.
"},{"location":"#supporters","title":"Supporters","text":"The development of SootUp is financed by generous support from the German Research Foundation (DFG) and the Heinz Nixdorf Institute (HNI).
Become a sponsor!
"},{"location":"advanced-topics/","title":"Advanced Topics","text":"As a user of the SootUp framework, you can omit these topics which mostly explain how some of the concepts work internally.
"},{"location":"advanced-topics/#body-interceptors","title":"Body Interceptors","text":"Soot Equivalent
BodyTransformer
Almost in all use-cases you can simply ignore body interceptors. They are applied to each Body
by default to create their rather normalized or leaner versions, e.g. by eliminating unreachable code (UnreachableCodeEliminator
), standardizing names of locals (LocalNameStandardizer
), or removing empty switch statements (EmptySwitchEliminator
) etc.
Below, we show how these body interceptors work for the users who are interested in their internal workings.
"},{"location":"advanced-topics/#localsplitter","title":"LocalSplitter","text":"LocalSplitter is aBodyInterceptor
that attempts to identify and separate uses of a local variable (as definition) that are independent of each other by renaming local variables.
Example 1:
As shown in the example above, the local variablel1
is 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.
Look for foldable navigation and tabs for showing old vs new
Example 2:
In the second example, the local variablel2
is 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.
LocalPacker is aBodyInterceptor
that attempts to minimize the number of local variables which are used in body by reusing them, when it is possible. It corresponds to the inverse body transformation of LocalSplitter. Note: Every local variable's type should be assigned before running LocalPacker.
Example:
In the given example above, the local variablesl1
,l3
are summarized to be one local variablel1
, because they have the same type without interference with each other. Likewise, the local variablesl2
,l4
andl5
are summarized to be another local variablel2
. Although the local variablel0
doesn't interfere any other local variables, it cannot be summed up with other local variables because of its distinctive type.
TrapTightener is aBodyInterceptor
that shrinks the protected area covered by each Trap in a Body.
Example:
We assume in the example above that only theStmt
:l2 := 2
might throw an exception caught by theTrap
which 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 theStmt
that might throw an exception, namely theStmt
:l2 := 2
.
EmptySwitchEliminator is aBodyInterceptor
that removes empty switch statements which contain only the default case.
Example:
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 aGotoStmt
to the default case.
UnreachableCodeEliminator is aBodyInterceptor
that removes all unreachable statements.
Example:
Obviously, the code segmentl2 = 2; l3 = 3;
is unreachable. It will be removed after running the UreachableCodeEliminator.
CopyPropagator is aBodyInterceptor
that supports the global copy propagation and constant propagation.
Example for global copy propagation:
Consider a code segment in the following form:
a = b;\n...\nc = use(a); // a, b, c are local variables\n
According to the copy propagation's definition, the statementc = use(a)
can be replaced withc = use(b)
iff both conditions are met:
a
is defined only one time on all the paths froma = b
toc = use(a)
.b
on any path froma = b
toc = use(a)
.In the example for global copy propagation, the first usedl1
is replaced withl0
, but the second usedl1
cannot be replaced withl3
, because the second condition is not satisfied.
Example for constant propagation:
Constant propagation is similar to copy propagation. Consider a code segment in the following form:
a = const;\n...\nb = use(a); // a, b are local variables, const is a constant\n
After perfoming the constant propagation, the statementb = use(a)
can be replaced withb = use(const)
iffa
is not redefined on any of the paths froma = const
tob = use(a)
.
Therefore, the first usedl1
in the second example can be replaced with the constant1
, but the second usedl1
cannot be replaced with the constant2
, becausel1
is redefined on the path froml1 = 2
tol4 = use(l1)
. However, it can be replaced with local variablel2
, because the both conditions of copy propagation are met.
LocalNameStandardizer is aBodyInterceptor
that assigns a generic name to each local variable. Firstly, it will sort the local variables' order alphabetically by the string representation of their type. If there are two local variables with the same type, then the LocalNameStandardizer will use the sequence of their occurrence in jimple body to determine their order. Each assigned name consists of two parts:
The following table shows the letter corresponding to each type:
Type of Local Variable Letter boolean z byte b short s int i long l float f double d char c null n unknown e reference r"},{"location":"advanced-topics/#staticsingleassignmentformer","title":"StaticSingleAssignmentFormer","text":"StaticSingleAssignmentFormer is aBodyInterceptor
that transforms jimple body into SSA form, so that each local variable is assigned exactly once and defined before its first use.
Example:
In the given example, the StaticSingleAssignmentFormer assigns eachIdentityStmt
andAssignStmt
to 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 aPhiStmt
in the front of the join block to merge all most recently defined local variables and assign them a new local variable.
LocalLivenessAnalyser is used for querying for the list of live local variables before and after a given Stmt
.
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
.
DomianceFinder is used for querying for the immediate dominator and dominance frontiers for a given basic block.
Example:
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 methodsgetImmediateDominator
andgetDominanceFrontiers
.
We would like to announce Soot\u2019s successor, SootUp.
Over more than 20 years, Soot has become one of the world\u2019s most popular academic tool for Java and Android analysis and instrumentation. We thank all of you who have used and contributed to it over the years! It was your feedback and your contributions that helped it grow into such a versatile tool!
However, over the years, the requirements for Soot have changed a lot, and given its original architecture, it was no longer quite up to the task. Soot was originally developed for ahead-of-time code transformation, particularly optimization, which has become very uncommon in Java. Current use cases center much more around powerful program analyses and program-understanding tasks.
Today we are officially releasing SootUp, a new version of Soot with a completely overhauled architecture. With SootUp, we aim to keep the best things about Soot, yet overcome a lot of its drawbacks. We very much restructured Soot, particularly abolishing the heavy use of singletons. Soot now has a concept of views; each view corresponds to some version or variant of an analyzed program, and multiple views can be kept in memory at the same time. This sets the foundation, for instance, for differential or incremental program analyses.
SootUp is a library that can easily be included in other projects, leaving those projects in control. For those who intend to use it as a framework, with inversion of control, SootUp provides additional templates that help you and novices to get started more easily. The Jimple IR has been slightly simplified, and has been made immutable by default such that internally SootUp can make use of caching where desired. Where required, Jimple transformations are still allowed, but in a systematic manner, for instance assuring that analyses depending on the transformed code are notified about its changes.
Below is an overview of what\u2019s 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: https://soot-oss.github.io/SootUp/, and * The SootUp repository: https://github.com/soot-oss/SootUp/
We are very much looking forward to your feedback and feature requests. To this end, best create appropriate issues in the repository.
This major upgrade of Soot was made possible by generous competitive funding by the DFG, within the project \u201cFuture-proofing the Soot Framework for Program Analysis and Transformation (FutureSoot)\u201d. It was funded in the DFG\u2019s program on Research Software Sustainability.
"},{"location":"call-graph-construction/","title":"Call Graph Construction","text":"A call graph shows the method calling relationship of a program. It is a directed graph, whose nodes represent different methods, and edges represent caller -> callee relationship.
SootUp contains several call graph construction algorithms. Below, we show how you can use each of these.
"},{"location":"call-graph-construction/#creating-the-type-hierarchy","title":"Creating the Type Hierarchy","text":"All the call graph construction algorithms require the view to access the type hierarchy for resolving method calls based of sub typing relationship. Below, we show how to create a type hierarchy:
SootUpSootAnalysisInputLocation<JavaSootClass> inputLocation =\n new JavaClassPathAnalysisInputLocation(\n \"src/test/resources/Callgraph/binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nJavaProject project =\n JavaProject.builder(language)\n .addInputLocation(inputLocation)\n .addInputLocation(\n new JavaClassPathAnalysisInputLocation(\n System.getProperty(\"java.home\") + \"/lib/rt.jar\"))\n .build();\n\nJavaView view = project.createView();\n
String targetTestClassName = target.exercise1.Hierarchy.class.getName();\nG.reset();\nString userdir = System.getProperty(\"user.dir\");\nString sootCp = userdir + File.separator + \"target\" + File.separator + \"test-classes\"+ File.pathSeparator + \"lib\"+File.separator+\"rt.jar\";\nOptions.v().set_whole_program(true);\nOptions.v().set_soot_classpath(sootCp);\nOptions.v().set_no_bodies_for_excluded(true);\nOptions.v().process_dir();\nOptions.v().set_allow_phantom_refs(true);\nOptions.v().setPhaseOption(\"jb\", \"use-original-names:true\");\nOptions.v().set_prepend_classpath(false);\nSootClass c = Scene.v().forceResolve(targetTestClassName, SootClass.BODIES);\nif (c != null)\n c.setApplicationClass();\nScene.v().loadNecessaryClasses();\n\nHierarchy hierarchy = new Hierarchy();\n
"},{"location":"call-graph-construction/#defining-an-entry-method","title":"Defining an Entry Method","text":"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:
SootUpSootClassType classTypeA = project.getIdentifierFactory().getClassType(\"A\");\n\nMethodSignature entryMethodSignature =\n JavaIdentifierFactory.getInstance()\n .getMethodSignature(\n classTypeA,\n JavaIdentifierFactory.getInstance()\n .getMethodSubSignature(\n \"calc\", VoidType.getInstance(), Collections.singletonList(classTypeA))); \n
SootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\"); \n
"},{"location":"call-graph-construction/#class-hierarchy-analysis","title":"Class Hierarchy Analysis","text":"Class Hierarchy Analysis (CHA) algorithm is the most sound call graph construction algorithm available in SootUp. It soundly includes all implementers of an interface, when resolving a method call on an interface. You can construct a call graph with CHA as follows:
SootUpSootCallGraphAlgorithm cha = \n new ClassHierarchyAnalysisAlgorithm(view);\n\nCallGraph cg = \n cha.initialize(Collections.singletonList(entryMethodSignature));\n\nSystem.out.println(cg);\n
CHATransformer.v().transform();\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n }\n
"},{"location":"call-graph-construction/#rapid-type-analysis","title":"Rapid Type Analysis","text":"Rapid Type Analysis (RTA) algorithm constructs a rather precise version of the call graph that the CHA constructs. It refines CHA by considering only the instantiated implementers of an interface, when resolving a method call on an interface. You can construct a call graph with RTA as follows:
SootUpSootCallGraphAlgorithm rta = \n new RapidTypeAnalysisAlgorithm(view);\n\nCallGraph cg = \n rta.initialize(Collections.singletonList(entryMethodSignature));\n\nSystem.out.println(cg);\n
Transform sparkConfig = new Transform(\"cg.spark\", null);\nPhaseOptions.v().setPhaseOption(sparkConfig, \"enabled:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"rta:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"on-fly-cg:false\");\nMap phaseOptions = PhaseOptions.v().getPhaseOptions(sparkConfig);\nSparkTransformer.v().transform(sparkConfig.getPhaseName(), phaseOptions);\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n} \n
"},{"location":"call-graph-construction/#variable-type-analysis","title":"Variable Type Analysis","text":"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.
Info
VTA algorithm was implemented using the Spark pointer analysis framework. A reimplementation of Spark in SootUp is currently under development.
Spark requires an initial call graph to begin with. You can use one of the call graphs that we have constructed above. You can construct a call graph with VTA as follows:
SootUpSootSpark spark = new Spark.Builder(view, callGraph).vta(true).build();\nspark.analyze();\nCallGraph vtaCAllGraph = spark.getCallGraph();\n
Transform sparkConfig = new Transform(\"cg.spark\", null);\nPhaseOptions.v().setPhaseOption(sparkConfig, \"enabled:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"vta:true\");\nPhaseOptions.v().setPhaseOption(sparkConfig, \"on-fly-cg:false\");\nMap phaseOptions = PhaseOptions.v().getPhaseOptions(sparkConfig);\nSparkTransformer.v().transform(sparkConfig.getPhaseName(), phaseOptions);\nSootMethod src = Scene.v().getSootClass(targetTestClassName).getMethodByName(\"doStuff\");\nCallGraph cg = Scene.v().getCallGraph();\nIterator<MethodOrMethodContext> targets = new Targets(cg.edgesOutOf(src));\nwhile (targets.hasNext()) {\n SootMethod tgt = (SootMethod)targets.next();\n System.out.println(src + \" may call \" + tgt);\n} \n
"},{"location":"docguide/","title":"Docguide","text":""},{"location":"docguide/#general","title":"General","text":""},{"location":"docguide/#mkdocsextensions","title":"MkDocsExtensions","text":""},{"location":"docguide/#tooltip","title":"Tooltip","text":"Hover me
"},{"location":"docguide/#example-file-inclusion","title":"Example File inclusion","text":"this enables that tutorial code can be tested and will fail if its not up to date anymore :)
package sootup.examples.basicSetup;\n\nimport static org.junit.Assert.assertTrue;\n\nimport categories.Java8Test;\nimport java.nio.file.Path;\nimport java.nio.file.Paths;\nimport java.util.Collections;\nimport org.junit.Ignore;\nimport org.junit.Test;\nimport org.junit.experimental.categories.Category;\nimport sootup.core.Language;\nimport sootup.core.Project;\nimport sootup.core.inputlocation.AnalysisInputLocation;\nimport sootup.core.jimple.common.expr.JVirtualInvokeExpr;\nimport sootup.core.jimple.common.stmt.JInvokeStmt;\nimport sootup.core.model.SootClass;\nimport sootup.core.model.SootMethod;\nimport sootup.core.signatures.MethodSignature;\nimport sootup.core.types.ClassType;\nimport sootup.core.views.View;\nimport sootup.java.bytecode.inputlocation.PathBasedAnalysisInputLocation;\nimport sootup.java.core.JavaProject;\nimport sootup.java.core.JavaSootClass;\nimport sootup.java.core.JavaSootClassSource;\nimport sootup.java.core.language.JavaJimple;\nimport sootup.java.core.language.JavaLanguage;\nimport sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation;\nimport sootup.jimple.parser.JimpleAnalysisInputLocation;\nimport sootup.jimple.parser.JimpleProject;\n\n/** This example illustrates how to create and use a new Soot Project. */\n@Category(Java8Test.class)\npublic class BasicSetup {\n\n @Test\n public void createSourceCodeProject() {\n Path pathToSource = Paths.get(\"src/test/resources/BasicSetup/source\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n new JavaSourcePathAnalysisInputLocation(pathToSource.toString());\n Language language = new JavaLanguage(8);\n Project project =\n JavaProject.builder((JavaLanguage) language).addInputLocation(inputLocation).build();\n }\n\n @Ignore\n public void createJimpleProject() {\n Path pathToJimple = Paths.get(\"src/test/resources/BasicSetup/jimple\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n new JimpleAnalysisInputLocation(pathToJimple);\n Project project = new JimpleProject(inputLocation);\n }\n\n @Test\n public void createByteCodeProject() {\n // Create a AnalysisInputLocation, which points to a directory. All class files will be loaded\n // from the directory\n Path pathToBinary = Paths.get(\"src/test/resources/BasicSetup/binary\");\n AnalysisInputLocation<JavaSootClass> inputLocation =\n PathBasedAnalysisInputLocation.create(pathToBinary, null);\n\n // Specify the language of the JavaProject. This is especially relevant for Multi-release jars,\n // where classes are loaded depending on the language level of the analysis\n Language language = new JavaLanguage(8);\n\n // Create a new JavaProject based on the input location\n Project project =\n JavaProject.builder((JavaLanguage) language).addInputLocation(inputLocation).build();\n\n // Create a signature for the class we want to analyze\n ClassType classType = project.getIdentifierFactory().getClassType(\"HelloWorld\");\n\n // Create a signature for the method we want to analyze\n MethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n classType, \"main\", \"void\", Collections.singletonList(\"java.lang.String[]\"));\n\n // Create a view for project, which allows us to retrieve classes\n View view = project.createView();\n\n // Assert that class is present\n assertTrue(view.getClass(classType).isPresent());\n\n // Retrieve class\n SootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n\n // Retrieve method\n view.getMethod(methodSignature);\n\n // Alternatively:\n assertTrue(sootClass.getMethod(methodSignature.getSubSignature()).isPresent());\n SootMethod sootMethod = sootClass.getMethod(methodSignature.getSubSignature()).get();\n\n // Read jimple code of method\n System.out.println(sootMethod.getBody());\n\n // Assert that Hello world print is present\n assertTrue(\n sootMethod.getBody().getStmts().stream()\n .anyMatch(\n stmt ->\n stmt instanceof JInvokeStmt\n && stmt.getInvokeExpr() instanceof JVirtualInvokeExpr\n && stmt.getInvokeExpr()\n .getArg(0)\n .equivTo(JavaJimple.getInstance().newStringConstant(\"Hello World!\"))));\n }\n}\n
"},{"location":"faq/","title":"Frequently Asked Questions","text":""},{"location":"faq/#how-to-setup-the-soot-dependency-in-maven-gradle","title":"How to setup the soot dependency (in Maven, Gradle)?","text":"See Installation.
"},{"location":"faq/#how-to-retreive-a-sootclass-or-sootmethod","title":"How to retreive a SootClass or SootMethod?","text":"See Getting Started.
"},{"location":"faq/#is-there-a-github-template-to-quickstart-into-development-with-sootup","title":"Is there a github template to quickstart into development with SootUp?","text":"Not yet.
"},{"location":"faq/#error-while-using-the-sourcecodefrontend","title":"Error while using the Sourcecodefrontend","text":"Please make sure to use Java8 to execute.
"},{"location":"faq/#exception-provider-jrt-not-found","title":"Exception: Provider \"jrt\" not found","text":"java.lang.ExceptionInInitializerError\n at sootup.java.bytecode.inputlocation.JrtFileSystemAnalysisInputLocationTest.getClassSource(JrtFileSystemAnalysisInputLocationTest.java:28)\n ...\nCaused by: java.nio.file.ProviderNotFoundException: Provider \"jrt\" not found\n
To execute SootUp with JavaModules support please make sure you run the code at least the Java9 Runtime."},{"location":"faq/#how-to-solve-a-concurrentmodificationexception","title":"How to solve a ConcurrentModificationException?","text":"Copy the Iterator into an intermediate Collection.
final StmtGraph<?> stmtGraph = builder.getStmtGraph();\n for (Stmt stmt : Lists.newArrayList(stmtGraph)){\n ...\n }\n}\n
"},{"location":"faq/#how-can-i-visualize-a-stmtgraph","title":"How can I visualize a StmtGraph?","text":"There exists a tool, that converts a StmtGraph to the Graphviz Dot Language.
DotExporter.buildGraph( stmtgraph );\n
or create a convenient link with the exported stmtgraph as HTTP GET Parameter DotExporter.createUrlToWebeditor( stmtgraph );\n
"},{"location":"faq/#is-there-a-way-to-use-code-exploration-and-syntax-highlighting-features-in-my-ide-for-jimple-files","title":"Is there a way to use code exploration and syntax highlighting features in my IDE for .jimple files?","text":"Try JimpeLsp.
"},{"location":"faq/#is-there-a-way-to-use-syntax-highlighting-of-jimple-in-my-paper-thesis","title":"Is there a way to use syntax highlighting of .jimple in my paper, thesis, ...?","text":"Have a look at LspLexer4Pygments.
"},{"location":"faq/#how-to-add-an-entry-in-this-list-ie-your-question-is-not-answered-here","title":"How to ... add an entry in this list? i.e. Your question is not answered here?","text":"Feel free to start a Discussion.
"},{"location":"getting-started/","title":"General Usage of SootUp","text":"This page walks you through the core data structures, as well as shows how to get started with SootUp.
"},{"location":"getting-started/#the-core-datastructures","title":"The core datastructures","text":"Before you get started with the SootUp library, it helps to learn about the following core data structures:
Project
: defines the outlines of an analysis. SootUp users should first create a Project
instance. It is the starting point for all operations. You can define multiple instances of Project
at the same time and there are no information shared between them. All caches are always at the project level.
Language
: represents the programming language of the analyzed code.
AnalysisInputLocation
: points to the target code to be analyzed.
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.Soot Equivalent
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.
StmtGraph
: represents the control flow graph of a method body in Jimple statements.
You can use bytecode analysis typically when you do not have access to the source code of the target program. Following example shows how to create project for analyzing Java bytecode.
Create a project to analyze Java bytecode
AnalysisInputLocation<JavaSootClass> inputLocation = \n new JavaClassPathAnalysisInputLocation(\"path2Binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project = \n JavaProject.builder(language).addInputLocation(inputLocation).build();\n
If you have access to the source code, it is also possible to create a project for analyzing source code. Following example shows how to create project for analyzing Java source code.
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.
Create a project to analyze Java source code
AnalysisInputLocation<JavaSootClass> inputLocation = \n new JavaSourcePathAnalysisInputLocation(\"path2Source\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project = \n JavaProject.builder(language).addInputLocation(inputLocation).build();\n
If you have a Jimple file, you can create a project for analyzing jimple code directly. Following example shows how to create project for analyzing jimple code.
Create a project to analyze jimple code
Path pathToJimple = Paths.get(\"path2Jimple\");\n\nAnalysisInputLocation<JavaSootClass> inputLocation = \n new JimpleAnalysisInputLocation(pathToJimple);\n\nProject project = new JimpleProject(inputLocation);\n
"},{"location":"getting-started/#creating-a-view","title":"Creating a View","text":"To create an analysis view, you can call the createView()
method on the project
object:
JavaView view = project.createView();\n
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:
JavaView view = project.createView(new LRUCacheProvider(50));\n
"},{"location":"getting-started/#retrieving-a-class","title":"Retrieving a Class","text":"Each class is identified with a unique signature adhering to Java identifier rules, therefore you first need to specify the class signature (ClassType
) as shown below.
Let's say the following is the target program that we want to analyze:
Target Program
package example;\n\npublic class HelloWorld {\n\n public HelloWorld() {\n\n }\n\n public static void main(String[] args) {\n HelloWorld hw = new HelloWorld();\n hw.hello();\n }\n\n public void hello() {\n\n }\n\n}\n
Then, we could define the ClassType
of the HelloWorld
class as follows:
Defining a ClassType
ClassType classType = \n project.getIdentifierFactory().getClassType(\"example.HelloWorld\");\n
Once we have a ClassType
that identifies the HelloWorld
class, we can use it to retrieve the corresponding SootClass
object from the view
as shown below:
Retrieving a SootClass
SootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n
"},{"location":"getting-started/#retrieving-a-method","title":"Retrieving a Method","text":"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:
Defining a MethodSignature
MethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n \"main\", // method name\n classType,\n \"void\", // return type\n Collections.singletonList(\"java.lang.String[]\")); // args\n
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:
Retrieving a SootMethod from the View
Optional<SootMethod> opt = view.getMethod(methodSignature);\n\nif(opt.isPresent()){\n SootMethod method = opt.get();\n}\n
Alternatively, we can also retrieve a SootMethod
from SootClass
that contains it.
Retrieving a SootMethod from a SootClass
Optional<? extends SootMethod> opt = sootClass.getMethod(methodSignature.getSubSignature());\n\nif(opt.isPresent()){\n SootMethod method = opt.get();\n}\n
"},{"location":"getting-started/#retrieving-the-control-flow-graph-of-a-method","title":"Retrieving the Control-Flow Graph of a Method","text":"Each SootMethod
contains a Control-Flow Graph (CFG) which is represented via the StmtGraph
. This structure is usually used for program analysis. You can retrieve the CFG of a SootMethod
as follows:
Retrieving the CFG of a SootMethod
sootMethod.getBody().getStmts();\n
Access or Download all of the code used above
BasicSetup.java
"},{"location":"getting-started/#sootup-vs-soot","title":"SootUp vs Soot","text":"Below we show a comparison of the code so far with the same functionality in sootup.
SootUpSootAnalysisInputLocation<JavaSootClass> inputLocation =\nnew JavaClassPathAnalysisInputLocation(\"path2Binary\");\n\nJavaLanguage language = new JavaLanguage(8);\n\nProject project =\n JavaProject.builder(language)\n .addInputLocation(inputLocation).build();\n\nClassType classType = \n project.getIdentifierFactory().getClassType(\"HelloWorld\");\n\nMethodSignature methodSignature =\n project\n .getIdentifierFactory()\n .getMethodSignature(\n \"main\", classType, \"void\",\n Collections.singletonList(\"java.lang.String[]\"));\n\nView view = project.createView();\n\nSootClass<JavaSootClassSource> sootClass =\n (SootClass<JavaSootClassSource>) view.getClass(classType).get();\n\nSootMethod sootMethod = \n sootClass.getMethod(methodSignature.getSubSignature()).get();\n\nsootMethod.getBody().getStmts();\n
G.reset();\nString userdir = System.getProperty(\"user.dir\");\nString sootCp = \n userdir \n + File.separator \n + \"target\" \n + File.separator \n + \"test-classes\"\n + File.pathSeparator + \"lib\"+File.separator+\"rt.jar\";\n\nOptions.v().set_soot_classpath(sootCp);\nOptions.v().set_whole_program(true);\nOptions.v().setPhaseOption(\"cg.cha\", \"on\");\nOptions.v().setPhaseOption(\"cg\", \"all-reachable:true\");\nOptions.v().set_no_bodies_for_excluded(true);\nOptions.v().set_allow_phantom_refs(true);\nOptions.v().setPhaseOption(\"jb\", \"use-original-names:true\");\nOptions.v().set_prepend_classpath(false);\n\nScene.v().addBasicClass(\"java.lang.StringBuilder\");\nSootClass c = \n Scene.v().forceResolve(targetTestClassName, SootClass.BODIES);\nif (c != null) {\n c.setApplicationClass();\n}\nScene.v().loadNecessaryClasses();\n\nSootMethod method;\nfor (SootClass c : Scene.v().getApplicationClasses()) {\n if(c.getName().equals(\"example.HelloWorld\")){\n for (SootMethod m : c.getMethods()) {\n if (!m.hasActiveBody()) {\n continue;\n }\n if (m.getName().equals(\"entryPoint\")) {\n method = m;\n break;\n }\n }\n }\n}\n\nmethod.getActiveBody().getUnits();\n
"},{"location":"installation/","title":"Installation","text":""},{"location":"installation/#using-the-release","title":"Using the release","text":"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 to learn more about which modules you might need.
"},{"location":"installation/#maven","title":"Maven","text":"Add the following dependency in the pom.xml
file of your project to include all SootUp modules into your project.
<dependencies>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.core</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.core</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.sourcecode</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.java.bytecode</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.jimple.parser</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.callgraph</artifactId>\n <version>1.1.2</version>\n </dependency>\n <dependency>\n <groupId>org.soot-oss</groupId>\n <artifactId>sootup.analysis</artifactId>\n <version>1.1.2</version>\n </dependency>\n</dependencies>\n
"},{"location":"installation/#gradle","title":"Gradle","text":"Add the following dependency in the build.gradle
file of your project to include all SootUp modules into your project.
compile \"org.soot-oss:sootup.core:1.1.2\"\ncompile \"org.soot-oss:sootup.java.core1.1.2\"\ncompile \"org.soot-oss:sootup.java.sourcecode1.1.2\"\ncompile \"org.soot-oss:sootup.java.bytecode1.1.2\"\ncompile \"org.soot-oss:sootup.jimple.parser1.1.2\"\ncompile \"org.soot-oss:sootup.callgraph1.1.2\"\ncompile \"org.soot-oss:sootup.analysis1.1.2\"\n
"},{"location":"installation/#building-from-source","title":"Building from Source","text":"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:
git clone https://github.com/secure-software-engineering/SootUp.git\n
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\n
Or if you want to skip tests while building:
mvn -Dskiptests install\n
"},{"location":"jimple/","title":"Jimple","text":"What is Jimple? Jimple is the intermediate representation IR of Soot, and thus SootUp. Soot's intention is to provide a simplified way to analyze JVM bytecode. JVM bytecode is stack-based, which makes it difficult for program analysis. Java source code, on the other hand, is also not quite suitable for program analysis, due to its nested structures. Therefore, Jimple aims to bring the best of both worlds, a non-stack-based and flat (non-nested) representation. 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 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.
public class HelloWorld extends java.lang.Object\n{\n public void <init>()\n {\n HelloWorld r0;\n r0 := @this: HelloWorld;\n specialinvoke r0.<java.lang.Object: void <init>()>();\n return;\n }\n\n public static void main(java.lang.String[])\n {\n java.lang.String[] r0;\n java.io.PrintStream $r1;\n\n r0 := @parameter0: java.lang.String[];\n $r1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $r1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Hello world!\");\n return;\n }\n}\n
public class HelloWorld {\n\n public HelloWorld() {\n\n }\n\n public static void main(String[] var0) {\n System.out.println(\"Hello World!\");\n }\n\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class analysis/HelloWorld {\n\n// compiled from: HelloWorld.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 4 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 6 L1\n RETURN\n L2\n LOCALVARIABLE this Lanalysis/HelloWorld; L0 L2 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static main([Ljava/lang/String;)V\n L0\n LINENUMBER 9 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Hello World!\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 10 L1\n RETURN\n L2\n LOCALVARIABLE var0 [Ljava/lang/String; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jimple-grammar-structure","title":"Jimple Grammar Structure","text":"Jimple mimics the JVMs class file structure. Therefore it is object oriented. A Single Class (or Interface) per file. Three-Address-Code which means there are no nested expressions. (nested expressions can be modeled via Locals that store intermediate calculation results.)
"},{"location":"jimple/#class-or-interface","title":"Class (or Interface)","text":"A class consists of Fields and Methods. It is referenced by its ClassType.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n}\n
package target.exercise1;\n\npublic class DemoClass {}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#field","title":"Field","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: double pi> = 3.14;\n return;\n }\n}\n/*\n \"this.<target.exercise1.DemoClass: double pi>\" is JInstanceFieldRef\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private final double pi = 3.14;\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x12\nprivate final D pi = 3.14\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n LDC 3.14\n PUTFIELD target/exercise1/DemoClass.pi : D\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#method-and-the-body","title":"Method and the Body","text":"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 that models the sequence of single instructions/statements (Stmts).
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n virtualinvoke this.<target.exercise1.DemoClass: \n void demoMethod()>();\n return;\n }\n\n public void demoMethod()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Inside method.\");\n return;\n }\n}\n/*\n \"<target.exercise1.DemoClass: void demoMethod()>\" \n and \"<target.exercise1.DemoClass: void <init>()>\" \n are instances of SootMethod \n*/\n
package target.exercise1;\n\npublic class DemoClass {\n DemoClass(){\n demoMethod();\n }\n public void demoMethod(){\n System.out.println(\"Inside method.\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x0\n<init>()V\n L0\n LINENUMBER 5 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 6 L1\n ALOAD 0\n INVOKEVIRTUAL target/exercise1/DemoClass.demoMethod ()V\n L2\n LINENUMBER 7 L2\n RETURN\n L3\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L3 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic demoMethod()V\n L0\n LINENUMBER 10 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Inside method.\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 11 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#signatures","title":"Signatures","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: double pi> = 3.14;\n return;\n }\n\n public void demoMethod()\n {\n java.io.PrintStream $stack3, $stack5;\n java.lang.StringBuilder $stack4, $stack6, $stack7;\n java.lang.String $stack8;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"pi : 3.14\");\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n $stack4 = new java.lang.StringBuilder;\n\n specialinvoke $stack4.<java.lang.StringBuilder: void <init>()>();\n $stack6 = virtualinvoke $stack4.<java.lang.StringBuilder: \n java.lang.StringBuilder append(java.lang.String)>\n (\"pi : \");\n $stack7 = virtualinvoke $stack6.<java.lang.StringBuilder: \n java.lang.StringBuilder append(double)>(3.1415);\n $stack8 = virtualinvoke $stack7.<java.lang.StringBuilder: \n java.lang.String toString()>();\n\n virtualinvoke $stack5.<java.io.PrintStream: \n void println(java.lang.String)>($stack8);\n return;\n }\n}\n/*\n For JInstanceFieldRef \"this.<target.exercise1.DemoClass: double pi>\" \n signature is <target.exercise1.DemoClass: double pi>\n Similarly, we have other signatures like \n <java.lang.Object: void <init>()>, \n <java.io.PrintStream: void println(java.lang.String)> \n and so on. \n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private final double pi = 3.14;\n\n public void demoMethod(){\n double localPi = 3.1415;\n System.out.println(\"pi : \" + pi);\n System.out.println(\"pi : \" + localPi);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x12\nprivate final D pi = 3.14\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n LDC 3.14\n PUTFIELD target/exercise1/DemoClass.pi : D\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n\n// access flags 0x1\npublic demoMethod()V\n L0\n LINENUMBER 6 L0\n LDC 3.1415\n DSTORE 1\n L1\n LINENUMBER 7 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"pi : 3.14\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L2\n LINENUMBER 8 L2\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n NEW java/lang/StringBuilder\n DUP\n INVOKESPECIAL java/lang/StringBuilder.<init> ()V\n LDC \"pi : \"\n INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)\n Ljava/lang/StringBuilder;\n DLOAD 1\n INVOKEVIRTUAL java/lang/StringBuilder.append (D)Ljava/lang/StringBuilder;\n INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 9 L3\n RETURN\n L4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0\n LOCALVARIABLE localPi D L1 L4 1\n MAXSTACK = 4\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#trap","title":"Trap","text":"A Trap is a mechanism to model exceptional flow.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void divideExample(int, int)\n {\n int x, y, $stack4;\n java.io.PrintStream $stack5, $stack7;\n java.lang.Exception $stack6;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n y := @parameter1: int;\n\n label1:\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n $stack4 = x / y;\n virtualinvoke $stack5.<java.io.PrintStream: void println(int)>($stack4);\n\n label2:\n goto label4;\n\n label3:\n $stack6 := @caughtexception;\n $stack7 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack7.<java.io.PrintStream: \n void println(java.lang.String)>(\"Exception caught\");\n\n label4:\n return;\n\n catch java.lang.Exception from label1 to label2 with label3;\n }\n}\n/*\n By calling getTraps() method, we can get the Traip chain.\n For the above jimple code, we have the below trap:\n Trap :\n begin : $stack5 = <java.lang.System: java.io.PrintStream out>\n end : goto [?= return]\n handler: $stack6 := @caughtexception\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void divideExample(int x, int y){\n try {\n System.out.println(x / y);\n }catch (Exception e){\n System.out.println(\"Exception caught\");\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic divideExample(II)V\n TRYCATCHBLOCK L0 L1 L2 java/lang/Exception\n L0\n LINENUMBER 6 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n ILOAD 2\n IDIV\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L1\n LINENUMBER 9 L1\n GOTO L3\n L2\n LINENUMBER 7 L2\n FRAME SAME1 java/lang/Exception\n ASTORE 3\n L4\n LINENUMBER 8 L4\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Exception caught\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 10 L3\n FRAME SAME\n RETURN\n L5\n LOCALVARIABLE e Ljava/lang/Exception; L4 L3 3\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE x I L0 L5 1\n LOCALVARIABLE y I L0 L5 2\n MAXSTACK = 3\n MAXLOCALS = 4\n}\n
"},{"location":"jimple/#stmt","title":"Stmt","text":"The main piece of Jimple is a Statement (Stmt). Stmts represent that can be executed by the JVM.
"},{"location":"jimple/#branching-statements","title":"Branching Statements","text":"A BranchingStmt's job is to model the flow between Stmts.
"},{"location":"jimple/#jgotostmt","title":"JGotoStmt","text":"for unconditional flow.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n public static void sampleMethod()\n {\n int i;\n i = 0;\n\n label1:\n if i >= 5 goto label3;\n if i != 3 goto label2;\n goto label3;\n\n label2:\n i = i + 1;\n goto label1;\n\n label3:\n return;\n }\n}\n/*\n Here for statements \"goto label3;\" and \"goto label1;\", \n we have two instances of JGotoStmt : \n \"goto[?=return]\" and \"goto[?=(branch)]\".\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public static void sampleMethod(){\n label1:\n for (int i = 0; i < 5; i++){\n if(i == 3){\n break label1;\n }\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static sampleMethod()V\n L0\n LINENUMBER 6 L0\n ICONST_0\n ISTORE 0\n L1\n FRAME APPEND [I]\n ILOAD 0\n ICONST_5\n IF_ICMPGE L2\n L3\n LINENUMBER 7 L3\n ILOAD 0\n ICONST_3\n IF_ICMPNE L4\n L5\n LINENUMBER 8 L5\n GOTO L2\n L4\n LINENUMBER 6 L4\n FRAME SAME\n IINC 0 1\n GOTO L1\n L2\n LINENUMBER 11 L2\n FRAME CHOP 1\n RETURN\n LOCALVARIABLE i I L1 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jifstmt","title":"JIfStmt","text":"for conditional flow depending on boolean Expression (AbstractConditionExpr) so they have two successor Stmt's.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public static void sampleMethod(int)\n {\n int x, $stack1;\n java.io.PrintStream $stack2, $stack3;\n\n x := @parameter0: int;\n\n $stack1 = x % 2;\n if $stack1 != 0 goto label1;\n\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"Even\");\n goto label2;\n\n label1:\n $stack2 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack2.<java.io.PrintStream: \n void println(java.lang.String)>(\"Odd\");\n\n label2:\n return;\n }\n}\n/*\n For statement \"if $stack1 != 0 goto label1;\", \n we have an instance of JIfStmt :\n \"if $stack1 != 0 goto $stack2 \n = <java.lang.System:java.io.PrintStream out>\".\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public static void sampleMethod(int x){\n if(x % 2 == 0){\n System.out.println(\"Even\");\n }else{\n System.out.println(\"Odd\");\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x9\npublic static sampleMethod(I)V\n L0\n LINENUMBER 5 L0\n ILOAD 0\n ICONST_2\n IREM\n IFNE L1\n L2\n LINENUMBER 6 L2\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Even\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n GOTO L3\n L1\n LINENUMBER 8 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Odd\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L3\n LINENUMBER 10 L3\n FRAME SAME\n RETURN\n L4\n LOCALVARIABLE x I L0 L4 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jswitchstmt","title":"JSwitchStmt","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void switchExample(int)\n {\n int x;\n java.io.PrintStream $stack2, $stack3, $stack4;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n lookupswitch(x)\n {\n case 1: goto label1;\n case 2: goto label2;\n default: goto label3;\n };\n\n label1:\n $stack3 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack3.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input 1\");\n goto label4;\n\n label2:\n $stack2 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack2.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input 2\");\n goto label4;\n\n label3:\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(java.lang.String)>(\"Input more than 2\");\n\n label4:\n return;\n }\n}\n/*\n Here for below statement:\n lookupswitch(x)\n {\n case 1: goto label1;\n case 2: goto label2;\n default: goto label3;\n };\n\n we have an instance of JLookupSwitchStmt :\n lookupswitch(x) \n { \n case 1: goto $stack3 \n = <java.lang.System: java.io.PrintStream out>; \n case 2: goto $stack2 \n = <java.lang.System: java.io.PrintStream out>; \n default: goto $stack4 \n = <java.lang.System: java.io.PrintStream out>; \n }\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void switchExample(int x){\n switch (x){\n case 1:\n System.out.println(\"Input 1\");\n break;\n\n case 2:\n System.out.println(\"Input 2\");\n break;\n\n default:\n System.out.println(\"Input more than 2\");\n break;\n\n }\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic switchExample(I)V\n L0\n LINENUMBER 5 L0\n ILOAD 1\n LOOKUPSWITCH\n 1: L1\n 2: L2\n default: L3\n L1\n LINENUMBER 7 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input 1\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L4\n LINENUMBER 8 L4\n GOTO L5\n L2\n LINENUMBER 11 L2\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input 2\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L6\n LINENUMBER 12 L6\n GOTO L5\n L3\n LINENUMBER 15 L3\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Input more than 2\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L5\n LINENUMBER 19 L5\n FRAME SAME\n RETURN\n L7\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L7 0\n LOCALVARIABLE x I L0 L7 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jreturnstmt-jreturnvoidstmt","title":"JReturnStmt & JReturnVoidStmt","text":"They end the execution/flow inside the current method and return (a value) to its caller.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public int increment(int)\n {\n int x, $stack2;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n $stack2 = x + 1;\n return $stack2;\n }\n\n public void print()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"Inside method print\");\n return;\n }\n}\n/*\n \"return $stack2\" is JReturnStmt.\n \"return\" is JReturnVoidStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public int increment(int x){\n return x + 1;\n }\n public void print(){\n System.out.println(\"Inside method print\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic increment(I)I\n L0\n LINENUMBER 5 L0\n ILOAD 1\n ICONST_1\n IADD\n IRETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE x I L0 L1 1\n MAXSTACK = 2\n MAXLOCALS = 2\n\n// access flags 0x1\npublic print()V\n L0\n LINENUMBER 8 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"Inside method print\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 9 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jthrowstmt","title":"JThrowStmt","text":"Ends the execution inside the current Method if the thrown exception is not caught by a Trap, which redirects the execution to an exceptionhandler.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void divideExample(int, int)\n {\n int y, x, $stack6;\n java.lang.StringBuilder $stack3, $stack5, $stack7;\n java.io.PrintStream $stack4;\n java.lang.String $stack8;\n java.lang.RuntimeException $stack9;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n y := @parameter1: int;\n\n if y != 0 goto label1;\n\n $stack9 = new java.lang.RuntimeException;\n specialinvoke $stack9.<java.lang.RuntimeException: \n void <init>(java.lang.String)>(\"Divide by zero error\");\n throw $stack9;\n\n label1:\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n $stack3 = new java.lang.StringBuilder;\n specialinvoke $stack3.<java.lang.StringBuilder: void <init>()>();\n\n $stack5 = virtualinvoke $stack3.<java.lang.StringBuilder: \n java.lang.StringBuilder append(java.lang.String)>(\"Divide result : \");\n $stack6 = x / y;\n $stack7 = virtualinvoke $stack5.<java.lang.StringBuilder: \n java.lang.StringBuilder append(int)>($stack6);\n $stack8 = virtualinvoke $stack7.<java.lang.StringBuilder: \n java.lang.String toString()>();\n\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(java.lang.String)>($stack8);\n return;\n }\n}\n/*\n \"throw $stack9\" is JThrowStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void divideExample(int x, int y){\n if(y == 0){\n throw new RuntimeException(\"Divide by zero error\");\n }\n System.out.println(\"Divide result : \" + x / y);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic divideExample(II)V\n L0\n LINENUMBER 5 L0\n ILOAD 2\n IFNE L1\n L2\n LINENUMBER 6 L2\n NEW java/lang/RuntimeException\n DUP\n LDC \"Divide by zero error\"\n INVOKESPECIAL java/lang/RuntimeException.<init> \n (Ljava/lang/String;)V\n ATHROW\n L1\n LINENUMBER 8 L1\n FRAME SAME\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n NEW java/lang/StringBuilder\n DUP\n INVOKESPECIAL java/lang/StringBuilder.<init> ()V\n LDC \"Divide result : \"\n INVOKEVIRTUAL java/lang/StringBuilder.append \n (Ljava/lang/String;)Ljava/lang/StringBuilder;\n ILOAD 1\n ILOAD 2\n IDIV\n INVOKEVIRTUAL java/lang/StringBuilder.append \n (I)Ljava/lang/StringBuilder;\n INVOKEVIRTUAL java/lang/StringBuilder.toString \n ()Ljava/lang/String;\n INVOKEVIRTUAL java/io/PrintStream.println \n (Ljava/lang/String;)V\n L3\n LINENUMBER 9 L3\n RETURN\n L4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L4 0\n LOCALVARIABLE x I L0 L4 1\n LOCALVARIABLE y I L0 L4 2\n MAXSTACK = 4\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#jinvokestmt","title":"JInvokeStmt","text":"transfers the control flow to another method until the called method returns.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void print(int)\n {\n target.exercise1.DemoClass this;\n int x, a;\n java.io.PrintStream $stack4, $stack6;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n a = virtualinvoke this.<target.exercise1.DemoClass: \n int increment(int)>(x);\n $stack4 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack4.<java.io.PrintStream: \n void println(int)>(a);\n\n a = virtualinvoke this.<target.exercise1.DemoClass: \n int increment(int)>(a);\n $stack6 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack6.<java.io.PrintStream: \n void println(int)>(a);\n\n return;\n }\n\n public int increment(int)\n {\n int x, $stack2;\n target.exercise1.DemoClass this;\n\n this := @this: target.exercise1.DemoClass;\n x := @parameter0: int;\n\n $stack2 = x + 1;\n return $stack2;\n }\n}\n/*\n \"specialinvoke this.<java.lang.Object: void <init>()>()\", \n \"virtualinvoke this.<target.exercise1.DemoClass: int increment(int)>(x)\", \n \"virtualinvoke this.<target.exercise1.DemoClass: int increment(int)>(a)\" \n are JInvokeStmts.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void print(int x){\n int a = increment(x);\n System.out.println(a);\n a = increment(a);\n System.out.println(a);\n }\n public int increment(int x){\n return x + 1;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic print(I)V\n L0\n LINENUMBER 5 L0\n ALOAD 0\n ILOAD 1\n INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I\n ISTORE 2\n L1\n LINENUMBER 6 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L2\n LINENUMBER 7 L2\n ALOAD 0\n ILOAD 2\n INVOKEVIRTUAL target/exercise1/DemoClass.increment (I)I\n ISTORE 2\n L3\n LINENUMBER 8 L3\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L4\n LINENUMBER 9 L4\n RETURN\n L5\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE x I L0 L5 1\n LOCALVARIABLE a I L1 L5 2\n MAXSTACK = 2\n MAXLOCALS = 3\n\n// access flags 0x1\npublic increment(I)I\n L0\n LINENUMBER 11 L0\n ILOAD 1\n ICONST_1\n IADD\n IRETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE x I L0 L1 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jassignstmt","title":"JAssignStmt","text":"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.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: int counter> = 0;\n return;\n }\n\n public int updateCounter()\n {\n target.exercise1.DemoClass this;\n int $stack1, $stack2, $stack3;\n\n this := @this: target.exercise1.DemoClass;\n\n $stack1 = this.<target.exercise1.DemoClass: int counter>;\n $stack2 = $stack1 + 1;\n this.<target.exercise1.DemoClass: int counter> = $stack2;\n $stack3 = this.<target.exercise1.DemoClass: int counter>;\n\n return $stack3;\n }\n}\n/*\n \"this.<target.exercise1.DemoClass: int counter> = 0\", \n \"$stack1 = this.<target.exercise1.DemoClass: int counter>\",\n \"$stack2 = $stack1 + 1\"\n \"this.<target.exercise1.DemoClass: int counter> = $stack2\"\n \"$stack3 = this.<target.exercise1.DemoClass: int counter>\"\n are JAssignStmts.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter = 0;\n public int updateCounter(){\n counter = counter + 1;\n return counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n ICONST_0\n PUTFIELD target/exercise1/DemoClass.counter : I\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n\n// access flags 0x1\npublic updateCounter()I\n L0\n LINENUMBER 6 L0\n ALOAD 0\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n ICONST_1\n IADD\n PUTFIELD target/exercise1/DemoClass.counter : I\n L1\n LINENUMBER 7 L1\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n IRETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 3\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#jidentitystmt","title":"JIdentityStmt","text":"is semantically like the JAssignStmt and handles assignments of IdentityRef's to make implicit assignments explicit into the StmtGraph.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void DemoClass(int)\n {\n target.exercise1.DemoClass this;\n int counter;\n\n this := @this: target.exercise1.DemoClass;\n counter := @parameter0: int;\n this.<target.exercise1.DemoClass: int counter> = counter;\n return;\n }\n}\n/*\n \"this := @this: target.exercise1.DemoClass\" and \n \"counter := @parameter0: int\" are JIdentityStmts\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter;\n public void DemoClass(int counter){\n this.counter = counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic DemoClass(I)V\n L0\n LINENUMBER 6 L0\n ALOAD 0\n ILOAD 1\n PUTFIELD target/exercise1/DemoClass.counter : I\n L1\n LINENUMBER 7 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n LOCALVARIABLE counter I L0 L2 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#jentermonitorstmt-jexitmonitorstmt","title":"JEnterMonitorStmt & JExitMonitorStmt","text":"marks synchronized blocks of code from JEnterMonitorStmt to JExitMonitorStmt.
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n this.<target.exercise1.DemoClass: int counter> = 0;\n return;\n }\n\n public int updateCounter()\n {\n target.exercise1.DemoClass this;\n int $stack4, $stack5, $stack7;\n java.lang.Throwable $stack8;\n\n this := @this: target.exercise1.DemoClass;\n\n entermonitor this;\n\n label1:\n $stack4 = this.<target.exercise1.DemoClass: int counter>;\n $stack5 = $stack4 + 1;\n this.<target.exercise1.DemoClass: int counter> = $stack5;\n\n exitmonitor this;\n\n label2:\n goto label5;\n\n label3:\n $stack8 := @caughtexception;\n\n exitmonitor this;\n\n label4:\n throw $stack8;\n\n label5:\n $stack7 = this.<target.exercise1.DemoClass: int counter>;\n return $stack7;\n\n catch java.lang.Throwable from label1 to label2 with label3;\n catch java.lang.Throwable from label3 to label4 with label3;\n }\n}\n/*\n \"entermonitor this\" is JEnterMonitorStmt.\n \"exitmonitor this\" is JExitMonitorStmt.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n private int counter = 0;\n public int updateCounter(){\n synchronized (this) {\n counter = counter + 1;\n }\n return counter;\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I counter\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n L1\n LINENUMBER 4 L1\n ALOAD 0\n ICONST_0\n PUTFIELD target/exercise1/DemoClass.counter : I\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n\n// access flags 0x1\npublic updateCounter()I\n TRYCATCHBLOCK L0 L1 L2 null\n TRYCATCHBLOCK L2 L3 L2 null\n L4\n LINENUMBER 6 L4\n ALOAD 0\n DUP\n ASTORE 1\n MONITORENTER\n L0\n LINENUMBER 7 L0\n ALOAD 0\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n ICONST_1\n IADD\n PUTFIELD target/exercise1/DemoClass.counter : I\n L5\n LINENUMBER 8 L5\n ALOAD 1\n MONITOREXIT\n L1\n GOTO L6\n L2\n FRAME FULL [target/exercise1/DemoClass java/lang/Object] \n [java/lang/Throwable]\n ASTORE 2\n ALOAD 1\n MONITOREXIT\n L3\n ALOAD 2\n ATHROW\n L6\n LINENUMBER 9 L6\n FRAME CHOP 1\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.counter : I\n IRETURN\n L7\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L4 L7 0\n MAXSTACK = 3\n MAXLOCALS = 3\n}\n
"},{"location":"jimple/#jretstmt","title":"JRetStmt","text":""},{"location":"jimple/#jbreakpointstmt","title":"JBreakpointStmt","text":"models a Breakpoint set by a Debugger (usually not relevant for static analyses)
"},{"location":"jimple/#immediate","title":"Immediate","text":"An Immediate has a given Type and consists of a Local (\"a Variable\", \"Something that contains a Value\") or a Constant (\"Something that is a Value\").
"},{"location":"jimple/#type","title":"Type","text":"VoidType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public void voidMethod()\n {\n java.io.PrintStream $stack1;\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n $stack1 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack1.<java.io.PrintStream: \n void println(java.lang.String)>(\"In voidMethod().\");\n return;\n }\n}\n/*\n For the SootMethod - <target.exercise1.DemoClass: void voidMethod()>, \n returnType is instance of VoidType.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void voidMethod(){\n System.out.println(\"In voidMethod().\");\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic voidMethod()V\n L0\n LINENUMBER 5 L0\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LDC \"In voidMethod().\"\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V\n L1\n LINENUMBER 6 L1\n RETURN\n L2\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L2 0\n MAXSTACK = 2\n MAXLOCALS = 1\n}\n
"},{"location":"jimple/#primarytype","title":"PrimaryType","text":"BooleanType, ByteType, CharType, ShortType, IntType, LongType, DoubleType, FloatType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\n public void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n\n public void display()\n {\n java.io.PrintStream $stack11, $stack13, $stack15, \n $stack17, $stack19, $stack21, $stack23, $stack25;\n int $stack12, $stack14, $stack16, $stack18;\n long $stack20;\n double $stack22;\n float $stack24;\n target.exercise1.DemoClass this;\n boolean $stack26;\n\n this := @this: target.exercise1.DemoClass;\n\n $stack11 = <java.lang.System: java.io.PrintStream out>;\n\n goto label1;\n\n label1:\n $stack26 = 0;\n virtualinvoke $stack11.<java.io.PrintStream: \n void println(boolean)>($stack26);\n\n $stack13 = <java.lang.System: java.io.PrintStream out>;\n $stack12 = 127 - 1;\n virtualinvoke $stack13.<java.io.PrintStream: \n void println(int)>($stack12);\n\n $stack15 = <java.lang.System: java.io.PrintStream out>;\n $stack14 = 97 + 1;\n virtualinvoke $stack15.<java.io.PrintStream: \n void println(int)>($stack14);\n\n $stack17 = <java.lang.System: java.io.PrintStream out>;\n $stack16 = 1123 + 1;\n virtualinvoke $stack17.<java.io.PrintStream: \n void println(int)>($stack16);\n\n $stack19 = <java.lang.System: java.io.PrintStream out>;\n $stack18 = 123456 + 1;\n virtualinvoke $stack19.<java.io.PrintStream: \n void println(int)>($stack18);\n\n $stack21 = <java.lang.System: java.io.PrintStream out>;\n $stack20 = 10L + 1L;\n virtualinvoke $stack21.<java.io.PrintStream: \n void println(long)>($stack20);\n\n $stack23 = <java.lang.System: java.io.PrintStream out>;\n $stack22 = 10.1 + 1.0;\n virtualinvoke $stack23.<java.io.PrintStream: \n void println(double)>($stack22);\n\n $stack25 = <java.lang.System: java.io.PrintStream out>;\n $stack24 = 10.1F + 1.0F;\n virtualinvoke $stack25.<java.io.PrintStream: \n void println(float)>($stack24);\n\n return;\n }\n}\n/*\n The JimpleLocal $stack12, $stack14, $stack16, $stack18 are of IntType. \n Similarly, $stack20 is of LongType, $stack22 is of DoubleType and so on.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n public void display(){\n boolean varBoolean = true;\n byte varByte = 127;\n char varChar = 'a';\n short varShort = 1123;\n int varInt = 123456;\n long varLong = 10L;\n double varDouble = 10.10;\n float varFloat = 10.10f;\n\n System.out.println(!varBoolean);\n System.out.println(varByte-1);\n System.out.println(varChar+1);\n System.out.println(varShort+1);\n System.out.println(varInt+1);\n System.out.println(varLong+1);\n System.out.println(varDouble+1);\n System.out.println(varFloat+1);\n\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic display()V\n L0\n LINENUMBER 5 L0\n ICONST_1\n ISTORE 1\n L1\n LINENUMBER 6 L1\n BIPUSH 127\n ISTORE 2\n L2\n LINENUMBER 7 L2\n BIPUSH 97\n ISTORE 3\n L3\n LINENUMBER 8 L3\n SIPUSH 1123\n ISTORE 4\n L4\n LINENUMBER 9 L4\n LDC 123456\n ISTORE 5\n L5\n LINENUMBER 10 L5\n LDC 10\n LSTORE 6\n L6\n LINENUMBER 11 L6\n LDC 10.1\n DSTORE 8\n L7\n LINENUMBER 12 L7\n LDC 10.1\n FSTORE 10\n L8\n LINENUMBER 14 L8\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n IFNE L9\n ICONST_1\n GOTO L10\n L9\n FRAME FULL [target/exercise1/DemoClass I I I I I J D F] \n [java/io/PrintStream]\n ICONST_0\n L10\n FRAME FULL [target/exercise1/DemoClass I I I I I J D F] \n [java/io/PrintStream I]\n INVOKEVIRTUAL java/io/PrintStream.println (Z)V\n L11\n LINENUMBER 15 L11\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 2\n ICONST_1\n ISUB\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L12\n LINENUMBER 16 L12\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 3\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L13\n LINENUMBER 17 L13\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 4\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L14\n LINENUMBER 18 L14\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 5\n ICONST_1\n IADD\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L15\n LINENUMBER 19 L15\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n LLOAD 6\n LCONST_1\n LADD\n INVOKEVIRTUAL java/io/PrintStream.println (J)V\n L16\n LINENUMBER 20 L16\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n DLOAD 8\n DCONST_1\n DADD\n INVOKEVIRTUAL java/io/PrintStream.println (D)V\n L17\n LINENUMBER 21 L17\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n FLOAD 10\n FCONST_1\n FADD\n INVOKEVIRTUAL java/io/PrintStream.println (F)V\n L18\n LINENUMBER 23 L18\n RETURN\n L19\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L19 0\n LOCALVARIABLE varBoolean Z L1 L19 1\n LOCALVARIABLE varByte B L2 L19 2\n LOCALVARIABLE varChar C L3 L19 3\n LOCALVARIABLE varShort S L4 L19 4\n LOCALVARIABLE varInt I L5 L19 5\n LOCALVARIABLE varLong J L6 L19 6\n LOCALVARIABLE varDouble D L7 L19 8\n LOCALVARIABLE varFloat F L8 L19 10\n MAXSTACK = 5\n MAXLOCALS = 11\n}\n
"},{"location":"jimple/#referencetype","title":"ReferenceType","text":"ClassType, ArrayType NullType
JimpleJavaByte Codepublic class target.exercise1.DemoClass extends java.lang.Object\n{\npublic void <init>()\n {\n target.exercise1.DemoClass this;\n this := @this: target.exercise1.DemoClass;\n specialinvoke this.<java.lang.Object: void <init>()>();\n return;\n }\n\n public target.exercise1.DemoClass getObject(target.exercise1.DemoClass)\n {\n target.exercise1.DemoClass obj, this;\n this := @this: target.exercise1.DemoClass;\n obj := @parameter0: target.exercise1.DemoClass;\n return obj;\n }\n\n public void compute(boolean)\n {\n int[] b;\n java.io.PrintStream $stack5, $stack6;\n boolean check;\n target.exercise1.DemoClass this;\n int i;\n null_type $r0;\n java.lang.NullPointerException soot0;\n this := @this: target.exercise1.DemoClass;\n check := @parameter0: boolean;\n b = newarray (int)[5];\n i = 0;\n\n label1:\n if i >= 5 goto label3;\n if check == 0 goto label2;\n $r0 = (null_type) i;\n soot0 = new java.lang.NullPointerException;\n specialinvoke soot0.<java.lang.NullPointerException: \n void <init>(java.lang.String)>\n (\"This statement would have triggered an Exception: a[i#1] = $r0\");\n throw soot0;\n\n label2:\n b[i] = i;\n i = i + 1;\n goto label1;\n\n label3:\n $stack5 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack5.<java.io.PrintStream: \n void println(java.lang.Object)>(b);\n $stack6 = <java.lang.System: java.io.PrintStream out>;\n virtualinvoke $stack6.<java.io.PrintStream: \n void println(java.lang.Object)>(null);\n return;\n }\n}\n/*\n The JimpleLocal b is of ArrayType,\n and JimpleLocal $r0 is of NullType.\n*/\n
package target.exercise1;\n\npublic class DemoClass {\n\n public DemoClass getObject(DemoClass obj){\n return obj;\n }\n\n public void compute(boolean check){\n int a[] = null;\n int b[] = new int[5];\n for (int i = 0; i < 5; i++) {\n if(check){\n a[i] = i;\n }\n b[i] = i;\n }\n System.out.println(b);\n System.out.println(a);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic getObject(Ltarget/exercise1/DemoClass;)Ltarget/exercise1/DemoClass;\n L0\n LINENUMBER 6 L0\n ALOAD 1\n ARETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n LOCALVARIABLE obj Ltarget/exercise1/DemoClass; L0 L1 1\n MAXSTACK = 1\n MAXLOCALS = 2\n\n// access flags 0x1\npublic compute(Z)V\n L0\n LINENUMBER 10 L0\n ACONST_NULL\n ASTORE 2\n L1\n LINENUMBER 11 L1\n ICONST_5\n NEWARRAY T_INT\n ASTORE 3\n L2\n LINENUMBER 12 L2\n ICONST_0\n ISTORE 4\n L3\n FRAME APPEND [[I [I I]\n ILOAD 4\n ICONST_5\n IF_ICMPGE L4\n L5\n LINENUMBER 13 L5\n ILOAD 1\n IFEQ L6\n L7\n LINENUMBER 14 L7\n ALOAD 2\n ILOAD 4\n ILOAD 4\n IASTORE\n L6\n LINENUMBER 16 L6\n FRAME SAME\n ALOAD 3\n ILOAD 4\n ILOAD 4\n IASTORE\n L8\n LINENUMBER 12 L8\n IINC 4 1\n GOTO L3\n L4\n LINENUMBER 18 L4\n FRAME CHOP 1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ALOAD 3\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V\n L9\n LINENUMBER 19 L9\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ALOAD 2\n INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V\n L10\n LINENUMBER 20 L10\n RETURN\n L11\n LOCALVARIABLE i I L3 L4 4\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L11 0\n LOCALVARIABLE check Z L0 L11 1\n LOCALVARIABLE a [I L1 L11 2\n LOCALVARIABLE b [I L2 L11 3\n MAXSTACK = 3\n MAXLOCALS = 5\n}\n
"},{"location":"jimple/#local","title":"Local","text":"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 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;\n$stack2 = <java.lang.System: java.io.PrintStream out>;\nvirtualinvoke $stack2.<java.io.PrintStream: void println(int)>(1);\n\nlocal#2 = this.<target.exercise1.DemoClass: int global>;\n$stack3 = <java.lang.System: java.io.PrintStream out>;\nvirtualinvoke $stack3.<java.io.PrintStream: void println(int)>(local#2);\nreturn;\n
} } /* $stack2, this, $stack3, local#2 are all JimpleLocal.
\"this := @this: target.exercise1.DemoClass\" is JIdentityStmt
\"$stack2 = \", \"local#2 = this.\", \"$stack3 = \" are JAssignStmt
*/ ```
package target.exercise1;\n\npublic class DemoClass {\n\n private int global;\n\n public void compute(){\n int local;\n local = 1;\n System.out.println(local);\n local = this.global;\n System.out.println(local);\n }\n}\n
// class version 52.0 (52)\n// access flags 0x21\npublic class target/exercise1/DemoClass {\n\n// compiled from: DemoClass.java\n\n// access flags 0x2\nprivate I global\n\n// access flags 0x1\npublic <init>()V\n L0\n LINENUMBER 3 L0\n ALOAD 0\n INVOKESPECIAL java/lang/Object.<init> ()V\n RETURN\n L1\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L1 0\n MAXSTACK = 1\n MAXLOCALS = 1\n\n// access flags 0x1\npublic compute()V\n L0\n LINENUMBER 9 L0\n ICONST_1\n ISTORE 1\n L1\n LINENUMBER 10 L1\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L2\n LINENUMBER 11 L2\n ALOAD 0\n GETFIELD target/exercise1/DemoClass.global : I\n ISTORE 1\n L3\n LINENUMBER 12 L3\n GETSTATIC java/lang/System.out : Ljava/io/PrintStream;\n ILOAD 1\n INVOKEVIRTUAL java/io/PrintStream.println (I)V\n L4\n LINENUMBER 14 L4\n RETURN\n L5\n LOCALVARIABLE this Ltarget/exercise1/DemoClass; L0 L5 0\n LOCALVARIABLE local I L1 L5 1\n MAXSTACK = 2\n MAXLOCALS = 2\n}\n
"},{"location":"jimple/#constant","title":"Constant","text":"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.
"},{"location":"jimple/#expr","title":"Expr","text":"An expression is a language construct that returns a value. E.g. a binary operation such as addition.
"},{"location":"jimple/#ref","title":"Ref","text":""},{"location":"jimple/#jarrayref","title":"JArrayRef","text":"jimple $arr[1]
referencing a position inside an array.
jimple <SomePackage.ExampleClass: fieldname> // or $r1.<SomePackage.ExampleClass: fieldname>
referencing a Field via its FieldSignature and if necessary (i.e. with JInstanceFieldRef) the corresponding Local instance that points to the object instance.
The IdentityRef makes those implicit special value assignments explicit.
"},{"location":"jimple/#jthisref","title":"JThisRef","text":"jimple @this: package.fruit.Banana
represents the this pointer of the current class.
jimple @caughtexception
represents the value of the thrown exception (caught by this exceptionhandler).
jimple $i0 := @parameter0 $i1 := @parameter1
represents a parameter of a method, identified by its index.
While Soot is a library and a stand-alone command-line application. SootUp, on the other hand, is designed to be a core library. It assumes that it is embedded in a client application that owns the thread of control. It can be extended with a command-line interface, included in other software projects as a library, or integrated into IDEs with JimpleLSP.
"},{"location":"whatsnew/#modular-architecture","title":"Modular Architecture","text":"SootUp has a modular architecture, which enables its clients to include only the necessary functionality to their applications.
Singletons offer a single view of a single program version, which makes it impossible to analyze multiple programs or multiple versions of the same program. SootUp does not make use of singletons such the Scene
class in the old Soot any more. It enables analyzing multple programs simultaneously.
Soot's JastAdd-based java frontend is not maintained anymore. In SootUp, we use WALA's well-maintained source code frontend, which will not only allow Soot to analyze Java source code, but also JavaScript and Python.
"},{"location":"whatsnew/#immutable-by-design","title":"Immutable by Design","text":"SootUp has been designed with the goal of immutability in mind. This makes sharing objects between several entities easier, because there is no need to worry about unintended changes to other entities.
"},{"location":"whatsnew/#withers-instead-of-setters","title":"Withers instead of Setters","text":"Due to the goal of immutability, many classes do not have setters anymore. For example, a Body
does not have a method setStmts(List<Stmt> stmts)
. Instead, a method called withStmts(List<Stmt> stmts)
has been added. This does not modify the original instance, but returns a copy of the Body but with the provided stmts
in its instance. This concept of so-called with
-ers can be found all throughout SootUp.
A simplified example
class Body {\n final List<Stmt> stmts;\n final List<Local> locals;\n\n Body(List<Stmt> stmts, List<Local> locals) {\n this.stmts = stmts;\n this.locals = locals;\n } \n\n Body withStmts(List<Stmt> stmts) { return new Body(stmts, this.locals); }\n Body withLocals(List<Local> locals) { return new Body(this.stmts, locals); }\n}\n
"},{"location":"whatsnew/#intermediate-representation","title":"Intermediate Representation","text":"Jimple is the only intermediate representation (IR) in SootUp. We modified it slightly to be able to accommodate different programming languages in the future.
"}]} \ No newline at end of file diff --git a/doc_keep_install_up2date/sitemap.xml.gz b/doc_keep_install_up2date/sitemap.xml.gz index 6d861a044ae..e616ee0d2d8 100644 Binary files a/doc_keep_install_up2date/sitemap.xml.gz and b/doc_keep_install_up2date/sitemap.xml.gz differ