Skip to content

Updating Static Analyser to TopDown and Stack Ordering - Method 2 #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
.idea/
stava.iml
.DS_Store

out
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Launch Current File",
"request": "launch",
"mainClass": "${file}"
},
{
"type": "java",
"name": "Launch Main",
"request": "launch",
"mainClass": "Main",
"projectName": "stava_862dc55b"
}
]
}
6 changes: 6 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"java.project.referencedLibraries": [
"lib/**/*.jar",
"soot/sootclasses-trunk-jar-with-dependencies.jar"
]
}
12 changes: 9 additions & 3 deletions scripts/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
# Sample script to be used to run the project on non-benchmark code.
# Set the paths according to your installation. All paths must be full paths.
# Instructions: ./run.sh ClassName

if [ -z "$1" ]; then
echo "No TestCase Number Provided";
exit
fi

# Installed path of Java 8 JDK
java_install_path="/usr/lib/jvm/java-8-oracle/"
java_install_path="/usr/lib/jvm/java-8-openjdk-amd64/"

# The soot jar to be used.
soot_path=`realpath ../soot/sootclasses-trunk-jar-with-dependencies.jar`
Expand All @@ -13,10 +19,10 @@ soot_path=`realpath ../soot/sootclasses-trunk-jar-with-dependencies.jar`
stava_path=`realpath ..`

# The directory to be analysed.
test_path=`realpath ../tests/test20/`
test_path=`realpath ../tests/test$1/`

# The directory inside which stava will output the results.
output_path=`realpath ../out/testcase/`
output_path=`realpath ../out/testcase$1/`

java_compiler="${java_install_path}/bin/javac"
java_vm="${java_install_path}/bin/java"
Expand Down
211 changes: 211 additions & 0 deletions src/analyser/MethodsLinkingAnalyser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package analyser;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import soot.*;
import main.CHATransform;
import ptg.ObjectNode;
import ptg.ObjectType;
import ptg.PointsToGraph;
import soot.jimple.Constant;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.internal.JInvokeStmt;
import soot.jimple.internal.JStaticInvokeExpr;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Edge;

public class MethodsLinkingAnalyser extends SceneTransformer {
public static ConcurrentHashMap<SootMethod, List<Local> > nativeLocals = new ConcurrentHashMap<>();

public static ArrayList<String> whitelistedNatives = new ArrayList<> (
Arrays.asList("<java.lang.System: arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V>")
);

public static ArrayList<String> blacklistedNatives = new ArrayList<> (
Arrays.asList("<sun.misc.Unsafe: putObject(Ljava/lang/Object;JLjava/lang/Object;)V>",
"<sun.misc.Unsafe: putObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;)V>",
"<sun.misc.Unsafe: compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z>")
);


private Set<SootMethod> methodsProcessed;
private Set<SootMethod> methodsProcessing;

public MethodsLinkingAnalyser() {
methodsProcessed = new HashSet<SootMethod>();
methodsProcessing = new HashSet<SootMethod>();
}

@Override
protected void internalTransform(String arg0, Map<String, String> arg1) {
// Get the call graph, and start processing the methods
CallGraph cg = Scene.v().getCallGraph();
Iterator<MethodOrMethodContext> callerEdges = cg.sourceMethods();

while (callerEdges.hasNext()) {
SootMethod methodCaller = (SootMethod) callerEdges.next();
// System.out.println("PRIYAM method caller: " + methodCaller);
processMethod(methodCaller);
}
}

private void processMethod(SootMethod methodCaller) {
if (methodCaller.isJavaLibraryMethod()) {
return;
}

if (methodsProcessed.contains(methodCaller)) {
// Method already computed
// we have the results ready
return;
}

if (methodsProcessing.contains(methodCaller)) {
// Recursive loop
// ASK - See what to do
return;
}

methodsProcessing.add(methodCaller);

System.out.println("PRIYAM Method Name: "+ methodCaller.getBytecodeSignature() + ":" + methodCaller.getName());
Body body = methodCaller.getActiveBody();
PatchingChain<Unit> units = body.getUnits();

for (Unit u : units) {
// System.out.println("PRIYAM unit: " + u);
if (u instanceof JInvokeStmt) {
JInvokeStmt stmt = (JInvokeStmt) u;
InvokeExpr expr = stmt.getInvokeExpr();
handleExpr(methodCaller, u, expr);
}
}

methodsProcessing.remove(methodCaller);
methodsProcessed.add(methodCaller);
}

public void handleExpr(
SootMethod methodCaller, Unit u, InvokeExpr expr) {
PointsToGraph ptg = StaticAnalyser.ptgs.get(methodCaller);

if (ptg == null) {
// If no points to graph, no need to process further
return;
}

CallGraph cg = Scene.v().getCallGraph();

Iterator<Edge> iedges = cg.edgesOutOf(u);
List<Value> args = expr.getArgs();

List<Edge> edges = new ArrayList<>();
if (!iedges.hasNext()) {
iedges = CHATransform.getCHA().edgesOutOf(u);
}

while (iedges.hasNext()) {
edges.add(iedges.next());
}

if (edges.size() == 0) {
// System.out.println("Empty edges: " + expr + ", function incoming edges: " + cg.edgesInto(methodCaller).hasNext() +
// " Method: " + methodCaller.getBytecodeSignature());
edges.add(new Edge(methodCaller, u, expr.getMethod(), Kind.SPECIAL));
}

if (expr instanceof InstanceInvokeExpr) {
// ASK - No need to handle instance invoke expr?
} else if (expr instanceof JStaticInvokeExpr) {
} else {
System.err.println("Unidentified invoke expr: " + expr.toString());
throw new IllegalArgumentException(expr.toString());
}

for (Edge edge : edges) {
/* 1.
* We traverse and find the caller callie relationship
* between ObjectNodes
*/
SootMethod method = edge.tgt();
int paramCount = method.getParameterCount();

// Recursion to first process the method
// if not already processed
if (!methodsProcessed.contains(method)) {
processMethod(method);
}

Map<ObjectNode, Set<ObjectNode>> paramMapping = new HashMap<ObjectNode,Set<ObjectNode>>();
for (int i = 0; i < paramCount; i++) {
ObjectNode obj = new ObjectNode(i, ObjectType.parameter);
// ConditionalValue cv = new ConditionalValue(method, obj, true);

if (edge.kind() == Kind.REFL_INVOKE)
paramMapping.put(obj, ptg.vars.get((Local) args.get(1)));
else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE)
paramMapping.put(obj, ptg.vars.get((Local) args.get(0)));
else {
Value arg = args.get(i);
if (arg.getType() instanceof RefType || arg.getType() instanceof ArrayType)
if (!(arg instanceof Constant)) { // Notice the not(!)
// ptg.addParametricEdge((Local) args.get(i), cv);
// System.out.println("args get i: " + args.get(i));
paramMapping.put(obj, ptg.vars.get((Local) args.get(i)));
}
}
}

// System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping);

/* 2.
* Now, loop in the callie method's ptg to find if there
* exists any relationship/node between the params
* If exists, add the realtion for corresponding values in
* paramsMapping also
*/
PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method);
System.out.println("PRIYAM METHOD: " + method);
System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs);
System.out.println("PRIYAM calliePTG: " + calliePTG);
// If ptg gives error, ensure StaticAnalysis has been done

for (int i = 0; i < paramCount; i++) {
ObjectNode obj = new ObjectNode(i, ObjectType.parameter);
Map<SootField, Set<ObjectNode>> pointingTo = calliePTG.fields.get(obj);

if (pointingTo == null) {
continue;
}

for (Map.Entry<SootField, Set<ObjectNode>> entry : pointingTo.entrySet()) {
for (ObjectNode fieldObj : entry.getValue()) {
System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey());
if (fieldObj.type != ObjectType.parameter) {
continue;
}

if (!paramMapping.containsKey(obj) || !paramMapping.containsKey(fieldObj)) {
// If paramsMapping does not have the object, it can happen if null is passed
continue;
}

// Find paramsMapping for obj
// Find paramsMapping for fieldObj
// Add an edge from objs to fieldObjs
for (ObjectNode objInCaller : paramMapping.get(obj)) {
for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) {
System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey());
ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller);
}
}
}
}
}

System.out.println("AFTER PRIYAM PTGS: " + StaticAnalyser.ptgs + "\n");
}
}
}
Loading