Boomerang Scope
Boomerang defines its own scope that is not related to any static analysis framework. The scope consists of a set of interfaces and classes that specify relevant information required by Boomerang to perform its analyses. Currently, we provide a scope implementations for the static analysis frameworks Soot, SootUp and Opal (see the FrameworkScopes). The scopes contain implementations for all relevant interfaces and objects s.t. Boomerang can be used with those frameworks without the need of additional implementation.
Dealing with Framework Objects
The Boomerang scope is designed to be as similar as possible to the analysis frameworks.
That is, for most Boomerang scope object there is a corresponding object in the analysis framework that is used to implement the required interface methods.
For example, the Boomerang scope has an abstract class Method
that expects implementations to override certain methods:
1 2 3 4 |
|
The concrete scope implementations extend this class by delegating the corresponding objects and using them to override the required methods.
For example, for the class Method
, we have the following (shortened) implementations:
1 2 3 4 5 6 7 8 9 |
|
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 |
|
With this setup, one can easily instantiate scope objects from the analysis framework objects and access delegated objects. The objects from each framework scope can be identified by their name:
- The scope objects for Soot are denoted with the prefix Jimple (e.g.
JimpleMethod
,JimpleStatement
etc.) - The scope objects for SootUp are denoted with the prefix JimpleUp (e.g.
JimpleUpMethod
,JimpleUpStatement
etc.) - The scope objects for Opal are denoted with the prefix Opal (e.g.
OpalMethod
,OpalStatement
etc.)
To simplify the process, we provide a ScopeConverter
for each framework scope.
These utility classes have basic methods to construct scope objects and extract delegated objects.
This concept may be relevant when working with Boomerang's results because Boomerang returns the general Boomerang scope object.
For example, we can work with a Method
and a Statement
as follows:
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 |
|
1 2 3 4 5 6 7 8 9 10 |
|
CallGraph
The Boomerang scope contains its own call graph representation that is used to compute data-flows during the analysis. Each framework scope provides a parser that transforms a generated call graph into the corresponding Boomerang scope representation that is applied when instantiating a FrameworkScope. The corresponding call graphs are accessible from the scope instances as follows:
1 2 3 |
|
1 2 3 |
|
1 2 3 |
|
DataFlowScope
The data-flow scope determines the program's scope that is analyzed. By default, Boomerang computes data-flows along the complete reachable program. However, in many scenarios, only a subset of the target program is from interest during the analysis. For example, we are only interested in data-flow paths that belong to the application. To this end, the data-flow scope allows the exclusion of methods to reduce the data-flows.
A DataFlowScope
defines two methods isExcluded(...)
that evaluate whether a method should be excluded from the analysis.
Boomerang calls these methods at each call site and when entering a new method.
If the methods evaluate to true
, Boomerang skips the methods and steps over corresponding call site.
For example, we can define a DataFlowScope
that excludes non-application classes and methods with the name callSite
as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
// TODO Example
Important
You should always make sure that potential allocation sites are considered when excluding call sites.
In the example above, we exclude the call to System.getProperty
because the class java.lang.System
is not an application class.
At this point, the data-flow stops because Boomerang cannot compute the returned value.
To deal with such cases, we provide a solution when defining the AllocationSite
Queries
AnalysisScope
Boomerang provides an AnalysisScope
to compute initial queries along the complete reachable program.
It traverses the call graph starting at the entry points that are defined in the FrameworkScopes while respecting their DataFlowScopes
.
The AnalysisScope
calls a method generateSeed
on each reachable control-flow graph edge where we can decide whether a query should be generated.
For example, we may be interested in the backward analysis of the first parameter of calls to a method sink
.
Then, we can implement an AnalysisScope
as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
We can use this implementation to compute relevant queries across the complete program as follows (see FrameworkScopes on how to initialize a framework scope):
1 2 3 |
|
The collection queries
contains all queries for a statement sink(v, ...)
that can be solved with the Boomerang Solver.