Skip to content

Commit

Permalink
Merge pull request #16 from CodeShield-Security/develop
Browse files Browse the repository at this point in the history
Custom Flow Functions + DemandDrivenGuidedAnalysis
  • Loading branch information
johspaeth authored Dec 4, 2020
2 parents 298d673 + 4f27aac commit b350f03
Show file tree
Hide file tree
Showing 60 changed files with 2,150 additions and 721 deletions.
Binary file added Test.jar
Binary file not shown.
11 changes: 7 additions & 4 deletions boomerangPDS/src/main/java/boomerang/BoomerangOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@

import boomerang.callgraph.BoomerangResolver;
import boomerang.callgraph.ICallerCalleeResolutionStrategy.Factory;
import boomerang.callgraph.ObservableICFG;
import boomerang.flowfunction.IBackwardFlowFunction;
import boomerang.flowfunction.IForwardFlowFunction;
import boomerang.scene.AllocVal;
import boomerang.scene.Method;
import boomerang.scene.Statement;
Expand All @@ -33,6 +34,8 @@ default Factory getResolutionStrategy() {

boolean handleMaps();

IForwardFlowFunction getForwardFlowFunctions();

enum StaticFieldStrategy {
FLOW_SENSITIVE,
SINGLETON,
Expand Down Expand Up @@ -61,9 +64,7 @@ enum ArrayStrategy {

int analysisTimeoutMS();

// TODO remove icfg here.
Optional<AllocVal> getAllocationVal(
Method m, Statement stmt, Val fact, ObservableICFG<Statement, Method> icfg);
Optional<AllocVal> getAllocationVal(Method m, Statement stmt, Val fact);

IBoomerangStats statsFactory();

Expand Down Expand Up @@ -102,4 +103,6 @@ Optional<AllocVal> getAllocationVal(
boolean trackDataFlowPath();

boolean allowMultipleQueries();

IBackwardFlowFunction getBackwardFlowFunction();
}
18 changes: 15 additions & 3 deletions boomerangPDS/src/main/java/boomerang/DefaultBoomerangOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
*/
package boomerang;

import boomerang.callgraph.ObservableICFG;
import boomerang.flowfunction.DefaultBackwardFlowFunction;
import boomerang.flowfunction.DefaultForwardFlowFunction;
import boomerang.flowfunction.IBackwardFlowFunction;
import boomerang.flowfunction.IForwardFlowFunction;
import boomerang.scene.AllocVal;
import boomerang.scene.Method;
import boomerang.scene.Statement;
Expand Down Expand Up @@ -99,8 +102,7 @@ public boolean trackNullAssignments() {
}

@Override
public Optional<AllocVal> getAllocationVal(
Method m, Statement stmt, Val fact, ObservableICFG<Statement, Method> icfg) {
public Optional<AllocVal> getAllocationVal(Method m, Statement stmt, Val fact) {
if (!stmt.isAssign()) {
return Optional.empty();
}
Expand Down Expand Up @@ -225,4 +227,14 @@ public void checkValid() {
public boolean handleMaps() {
return true;
}

@Override
public IForwardFlowFunction getForwardFlowFunctions() {
return new DefaultForwardFlowFunction(this);
}

@Override
public IBackwardFlowFunction getBackwardFlowFunction() {
return new DefaultBackwardFlowFunction(this);
}
}
16 changes: 12 additions & 4 deletions boomerangPDS/src/main/java/boomerang/QueryGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ private AbstractBoomerangSolver<W> getSolver(Query query) {
}

public void unregisterAllListeners() {
this.roots.clear();
this.edgeAddListener.clear();
this.sourceToQueryEdgeLookUp.clear();
this.targetToQueryEdgeLookUp.clear();
}

public Set<Query> getNodes() {
Set<Query> nodes = Sets.newHashSet(sourceToQueryEdgeLookUp.keySet());
nodes.addAll(targetToQueryEdgeLookUp.keySet());
return nodes;
}

private class SourceListener extends WPAStateListener<Edge, INode<Val>, W> {
Expand All @@ -94,7 +97,12 @@ public void onOutTransitionAdded(
WeightedPAutomaton<Edge, INode<Val>, W> weightedPAutomaton) {
if (t.getStart() instanceof GeneratedState && callee != null) {
Edge callSiteLabel = t.getLabel();
getSolver(child).allowUnbalanced(callee, callSiteLabel);
getSolver(child)
.allowUnbalanced(
callee,
(parent instanceof BackwardQuery
? callSiteLabel.getTarget()
: callSiteLabel.getStart()));
}
if (t.getTarget() instanceof GeneratedState) {
getSolver(parent)
Expand Down
113 changes: 86 additions & 27 deletions boomerangPDS/src/main/java/boomerang/WeightedBoomerang.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
import boomerang.controlflowgraph.PredecessorListener;
import boomerang.controlflowgraph.StaticCFG;
import boomerang.controlflowgraph.SuccessorListener;
import boomerang.customize.BackwardEmptyCalleeFlow;
import boomerang.customize.EmptyCalleeFlow;
import boomerang.customize.ForwardEmptyCalleeFlow;
import boomerang.debugger.Debugger;
import boomerang.poi.AbstractPOI;
import boomerang.poi.CopyAccessPathChain;
Expand All @@ -46,7 +43,6 @@
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ControlFlowEdgeBasedFieldTransitionListener;
import boomerang.solver.ForwardBoomerangSolver;
import boomerang.solver.Strategies;
import boomerang.stats.IBoomerangStats;
import boomerang.util.DefaultValueMap;
import com.google.common.base.Stopwatch;
Expand Down Expand Up @@ -81,7 +77,6 @@
import wpds.impl.Transition;
import wpds.impl.Weight;
import wpds.impl.WeightedPAutomaton;
import wpds.interfaces.State;
import wpds.interfaces.WPAStateListener;

public abstract class WeightedBoomerang<W extends Weight> {
Expand Down Expand Up @@ -133,16 +128,9 @@ protected BackwardBoomerangSolver<W> createItem(BackwardQuery key) {
createCallSummaries(null, backwardCallSummaries),
createFieldSummaries(null, backwardFieldSummaries),
WeightedBoomerang.this.dataFlowscope,
strategies,
options.getBackwardFlowFunction(),
null) {

@Override
protected Collection<? extends State> getEmptyCalleeFlow(
Method caller, Edge callSiteEdge, Val value) {
return backwardEmptyCalleeFlow.getEmptyCalleeFlow(
caller, callSiteEdge.getStart(), value, callSiteEdge.getTarget());
}

@Override
public WeightFunctions<ControlFlowGraph.Edge, Val, Field, W> getFieldWeights() {
return WeightedBoomerang.this.getBackwardFieldWeights();
Expand Down Expand Up @@ -351,9 +339,6 @@ public void checkTimeout() {
}

private ObservableICFG<Statement, Method> bwicfg;
private EmptyCalleeFlow forwardEmptyCalleeFlow = new ForwardEmptyCalleeFlow();
private EmptyCalleeFlow backwardEmptyCalleeFlow = new BackwardEmptyCalleeFlow();

private NestedWeightedPAutomatons<Edge, INode<Val>, W> backwardCallSummaries =
new SummaryNestedWeightedPAutomatons<>();
private NestedWeightedPAutomatons<Field, INode<Node<Edge, Val>>, W> backwardFieldSummaries =
Expand All @@ -373,7 +358,6 @@ protected FieldWritePOI createItem(FieldWritePOI key) {
protected final BoomerangOptions options;
private Stopwatch analysisWatch = Stopwatch.createUnstarted();
private final DataFlowScope dataFlowscope;
private Strategies<W> strategies;
private CallGraph callGraph;
private INode<Val> rootQuery;

Expand All @@ -395,7 +379,6 @@ public WeightedBoomerang(CallGraph cg, DataFlowScope scope, BoomerangOptions opt
icfg = new ObservableStaticICFG(cg);
}
this.callGraph = cg;
this.strategies = new Strategies<>(options, this);
this.queryGraph = new QueryGraph<>(this);
}

Expand All @@ -410,7 +393,7 @@ protected void addVisitedMethod(Method method) {
}

protected Optional<AllocVal> isAllocationNode(ControlFlowGraph.Edge s, Val fact) {
return options.getAllocationVal(s.getStart().getMethod(), s.getStart(), fact, icfg());
return options.getAllocationVal(s.getStart().getMethod(), s.getStart(), fact);
}

protected ForwardBoomerangSolver<W> createForwardSolver(final ForwardQuery sourceQuery) {
Expand All @@ -424,16 +407,9 @@ protected ForwardBoomerangSolver<W> createForwardSolver(final ForwardQuery sourc
createCallSummaries(sourceQuery, forwardCallSummaries),
createFieldSummaries(sourceQuery, forwardFieldSummaries),
dataFlowscope,
strategies,
options.getForwardFlowFunctions(),
sourceQuery.getType()) {

@Override
protected Collection<? extends State> getEmptyCalleeFlow(
Method caller, Edge callSiteEdge, Val value) {
return forwardEmptyCalleeFlow.getEmptyCalleeFlow(
caller, callSiteEdge.getStart(), value, callSiteEdge.getTarget());
}

@Override
public WeightFunctions<ControlFlowGraph.Edge, Val, ControlFlowGraph.Edge, W>
getCallWeights() {
Expand Down Expand Up @@ -623,6 +599,10 @@ public DefaultValueMap<BackwardQuery, BackwardBoomerangSolver<W>> getBackwardSol
return queryToBackwardSolvers;
}

public QueryGraph<W> getQueryGraph() {
return queryGraph;
}

private final class EmptyFieldListener
extends WPAStateListener<Field, INode<Node<ControlFlowGraph.Edge, Val>>, W> {

Expand Down Expand Up @@ -967,6 +947,85 @@ public BackwardBoomerangResults<W> solve(BackwardQuery query, boolean timing) {
query, timedout, this.queryToSolvers, backwardSolverIns, getStats(), analysisWatch);
}

public BackwardBoomerangResults<W> solveUnderScope(
BackwardQuery query, Node<Edge, Val> triggeringNode, Query parentQuery) {
if (!options.allowMultipleQueries() && solving) {
throw new RuntimeException(
"One cannot re-use the same Boomerang solver for more than one query, unless option allowMultipleQueries is enabled. If allowMultipleQueries is enabled, ensure to call unregisterAllListeners() on this instance upon termination of all queries.");
}
solving = true;
if (!analysisWatch.isRunning()) {
analysisWatch.start();
}
boolean timedout = false;
try {

LOGGER.trace("Starting backward analysis of: {}", query);
backwardSolve(query);
queryGraph.addEdge(parentQuery, triggeringNode, query);
this.debugOutput();
} catch (BoomerangTimeoutException e) {
timedout = true;
LOGGER.info("Timeout ({}) of query: {} ", analysisWatch, query);
}
if (analysisWatch.isRunning()) {
analysisWatch.stop();
}
return new BackwardBoomerangResults<W>(
query, timedout, this.queryToSolvers, backwardSolverIns, getStats(), analysisWatch);
}

public ForwardBoomerangResults<W> solveUnderScope(
ForwardQuery query, Node<Edge, Val> triggeringNode, Query parentQuery) {
if (!options.allowMultipleQueries() && solving) {
throw new RuntimeException(
"One cannot re-use the same Boomerang solver for more than one query, unless option allowMultipleQueries is enabled. If allowMultipleQueries is enabled, ensure to call unregisterAllListeners() on this instance upon termination of all queries.");
}
solving = true;
if (!analysisWatch.isRunning()) {
analysisWatch.start();
}
boolean timedout = false;
try {
LOGGER.trace("Starting forward analysis of: {}", query);
forwardSolve(query);
LOGGER.trace(
"Query terminated in {} ({}), visited methods {}",
analysisWatch,
query,
visitedMethods.size());
queryGraph.addEdge(parentQuery, triggeringNode, query);
} catch (BoomerangTimeoutException e) {
timedout = true;
LOGGER.trace(
"Timeout ({}) of query: {}, visited methods {}",
analysisWatch,
query,
visitedMethods.size());
} catch (Throwable e) {
LOGGER.error("Solving query crashed in {}", e);
}
if (!options.allowMultipleQueries()) {
unregisterAllListeners();
}

if (analysisWatch.isRunning()) {
analysisWatch.stop();
}
return new ForwardBoomerangResults<W>(
query,
icfg(),
cfg(),
timedout,
this.queryToSolvers,
getStats(),
analysisWatch,
visitedMethods,
options.trackDataFlowPath(),
options.prunePathConditions(),
options.trackImplicitFlows());
}

public void debugOutput() {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Query Graph \n{}", queryGraph.toDotString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,12 @@
import boomerang.scene.ControlFlowGraph.Edge;
import boomerang.scene.Pair;
import boomerang.scene.Val;
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import java.util.Set;
import wpds.impl.Weight;
import wpds.interfaces.State;

public interface ArrayHandlingStrategy<W extends Weight> {
void handleForward(
Edge arrayStoreStmt,
Pair<Val, Integer> arrayBase,
Set<State> out,
ForwardBoomerangSolver<W> solver);
void handleForward(Edge arrayStoreStmt, Pair<Val, Integer> arrayBase, Set<State> out);

void handleBackward(
Edge arrayStoreStmt,
Pair<Val, Integer> arrayBase,
Set<State> out,
BackwardBoomerangSolver<W> solver);
void handleBackward(Edge arrayStoreStmt, Pair<Val, Integer> arrayBase, Set<State> out);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import boomerang.scene.Field;
import boomerang.scene.Pair;
import boomerang.scene.Val;
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import java.util.Set;
import sync.pds.solver.SyncPDSSolver.PDSSystem;
import sync.pds.solver.nodes.PushNode;
Expand All @@ -26,14 +24,12 @@
public class ArrayIndexInsensitiveStrategy<W extends Weight> implements ArrayHandlingStrategy<W> {

@Override
public void handleForward(
Edge curr, Pair<Val, Integer> arrayBase, Set<State> out, ForwardBoomerangSolver<W> solver) {
public void handleForward(Edge curr, Pair<Val, Integer> arrayBase, Set<State> out) {
out.add(new PushNode<>(curr, arrayBase.getX(), Field.array(-1), PDSSystem.FIELDS));
}

@Override
public void handleBackward(
Edge curr, Pair<Val, Integer> arrayBase, Set<State> out, BackwardBoomerangSolver<W> solver) {
public void handleBackward(Edge curr, Pair<Val, Integer> arrayBase, Set<State> out) {
out.add(new PushNode<>(curr, arrayBase.getX(), Field.array(-1), PDSSystem.FIELDS));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
import boomerang.scene.Field;
import boomerang.scene.Pair;
import boomerang.scene.Val;
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import java.util.Set;
import sync.pds.solver.SyncPDSSolver.PDSSystem;
import sync.pds.solver.nodes.PushNode;
Expand All @@ -26,15 +24,13 @@
public class ArrayIndexSensitiveStrategy<W extends Weight> implements ArrayHandlingStrategy<W> {

@Override
public void handleForward(
Edge curr, Pair<Val, Integer> arrayBase, Set<State> out, ForwardBoomerangSolver<W> solver) {
public void handleForward(Edge curr, Pair<Val, Integer> arrayBase, Set<State> out) {
out.add(
new PushNode<>(curr, arrayBase.getX(), Field.array(arrayBase.getY()), PDSSystem.FIELDS));
}

@Override
public void handleBackward(
Edge curr, Pair<Val, Integer> arrayBase, Set<State> out, BackwardBoomerangSolver<W> solver) {
public void handleBackward(Edge curr, Pair<Val, Integer> arrayBase, Set<State> out) {
out.add(
new PushNode<>(curr, arrayBase.getX(), Field.array(arrayBase.getY()), PDSSystem.FIELDS));
}
Expand Down
Loading

0 comments on commit b350f03

Please sign in to comment.