Skip to content

Commit

Permalink
Java-frontend: Extract edge processing methods
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Chan <[email protected]>
  • Loading branch information
arthurscchan committed Nov 7, 2023
1 parent 073e9df commit 94ce64b
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
Expand All @@ -36,7 +35,7 @@
import ossf.fuzz.introspector.soot.utils.BlockGraphInfoUtils;
import ossf.fuzz.introspector.soot.utils.CalculationUtils;
import ossf.fuzz.introspector.soot.utils.CalltreeUtils;
import ossf.fuzz.introspector.soot.utils.MergeUtils;
import ossf.fuzz.introspector.soot.utils.EdgeUtils;
import ossf.fuzz.introspector.soot.yaml.Callsite;
import ossf.fuzz.introspector.soot.yaml.FunctionConfig;
import ossf.fuzz.introspector.soot.yaml.FunctionElement;
Expand All @@ -50,7 +49,6 @@
import soot.jimple.IfStmt;
import soot.jimple.Stmt;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Edge;
import soot.toolkits.graph.Block;
import soot.toolkits.graph.BlockGraph;
import soot.toolkits.graph.BriefBlockGraph;
Expand Down Expand Up @@ -166,7 +164,8 @@ protected void internalTransform(String phaseName, Map<String, String> options)
System.out.println("[Callgraph] Internal transform init");
System.out.println("[Callgraph] Determining classes to use for analysis.");

Map<SootClass, List<SootMethod>> classMethodMap = this.generateClassMethodMap(Scene.v().getClasses().snapshotIterator());
Map<SootClass, List<SootMethod>> classMethodMap =
this.generateClassMethodMap(Scene.v().getClasses().snapshotIterator());

System.out.println("[Callgraph] Finished going through classes");

Expand Down Expand Up @@ -200,7 +199,8 @@ protected void internalTransform(String phaseName, Map<String, String> options)
fw.close();

// Extract other info and write to .data.yaml
System.out.println("[Callgraph] Generating fuzzerLogFile-" + this.entryClassStr + ".data.yaml");
System.out.println(
"[Callgraph] Generating fuzzerLogFile-" + this.entryClassStr + ".data.yaml");
ObjectMapper om = new ObjectMapper(new YAMLFactory());
file = new File("fuzzerLogFile-" + this.entryClassStr + ".data.yaml");
file.createNewFile();
Expand All @@ -218,7 +218,8 @@ protected void internalTransform(String phaseName, Map<String, String> options)
analyseFinished = true;
}

private Map<SootClass, List<SootMethod>> generateClassMethodMap(Iterator<SootClass> classIterator) {
private Map<SootClass, List<SootMethod>> generateClassMethodMap(
Iterator<SootClass> classIterator) {
Map<SootClass, List<SootMethod>> classMethodMap = new HashMap<SootClass, List<SootMethod>>();

while (classIterator.hasNext()) {
Expand Down Expand Up @@ -321,7 +322,8 @@ private Map<SootClass, List<SootMethod>> generateClassMethodMap(Iterator<SootCla
return classMethodMap;
}

private void processMethods(Map<SootClass, List<SootMethod>> classMethodMap, CallGraph callGraph) {
private void processMethods(
Map<SootClass, List<SootMethod>> classMethodMap, CallGraph callGraph) {
for (SootClass c : classMethodMap.keySet()) {
// Skip sink method classes
if (this.sinkMethodMap.containsKey(c.getName())) {
Expand Down Expand Up @@ -352,59 +354,17 @@ private void processMethods(Map<SootClass, List<SootMethod>> classMethodMap, Cal
element.setJavaMethodInfo(m);
}

// Identify in / out edges of each method.
int methodEdges = 0;
Iterator<Edge> outEdges =
MergeUtils.mergePolymorphism(
callGraph,
callGraph.edgesOutOf(m),
this.excludeList,
this.getIncludeList(),
this.edgeClassMap);
Iterator<Edge> inEdges = callGraph.edgesInto(m);
while (inEdges.hasNext()) {
methodEdges++;
inEdges.next();
}
element.setFunctionUses(methodEdges);
methodEdges = 0;
for (; outEdges.hasNext(); methodEdges++) {
Edge edge = outEdges.next();
SootMethod tgt = edge.tgt();
if (this.excludeMethodList.contains(tgt.getName())) {
methodEdges--;
continue;
}
String callerClass = edge.src().getDeclaringClass().getName();
String className = "";
Set<String> classNameSet =
new HashSet<String>(
this.edgeClassMap.getOrDefault(
callerClass
+ ":"
+ tgt.getName()
+ ":"
+ ((edge.srcStmt() == null)
? -1
: edge.srcStmt().getJavaSourceStartLineNumber()),
Collections.emptySet()));
className = MergeUtils.mergeClassName(classNameSet);
boolean merged = false;
for (String name : className.split(":")) {
if (name.equals(tgt.getDeclaringClass().getName())) {
merged = true;
break;
}
}
if (!merged) {
className = tgt.getDeclaringClass().getName();
}
element.addFunctionsReached("[" + className + "]." + tgt.getSubSignature().split(" ")[1]);
functionLineMap.put(
tgt.getSubSignature().split(" ")[1],
(edge.srcStmt() == null) ? -1 : edge.srcStmt().getJavaSourceStartLineNumber());
}
element.setEdgeCount(methodEdges);
// Retrieve and update incoming and outgoing edges of the target method
EdgeUtils.updateIncomingEdges(callGraph, m, element);
EdgeUtils.updateOutgoingEdges(
callGraph,
m,
element,
this.includeList,
this.excludeList,
this.excludeMethodList,
this.edgeClassMap,
functionLineMap);

// Identify blocks information
Body methodBody;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// Copyright 2022 Fuzz Introspector Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////

package ossf.fuzz.introspector.soot.utils;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ossf.fuzz.introspector.soot.yaml.FunctionElement;
import soot.SootMethod;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Edge;

public class EdgeUtils {
/**
* The method retrieves a list of incoming edges from the provided SootMethod and calculate the
* total number of incoming edges and store it in the provided FunctionElement object
*
* @param callGraph the CallGraph object for this target project
* @param m the target SootMethod object to be processed
* @param element the target FunctionElement object to be processed
*/
public static void updateIncomingEdges(
CallGraph callGraph, SootMethod m, FunctionElement element) {
Integer edges = 0;

Iterator<Edge> inEdges = callGraph.edgesInto(m);
while (inEdges.hasNext()) {
edges++;
inEdges.next();
}

element.setFunctionUses(edges);
}

/**
* The method retrieves a list of outgoing edges from the provided SootMethod and calculate the
* total number of outgoing edges. The process will include or exclude some classes and methods
* according to the three lists provided. Lastly, the edge count and method targets pointed out by
* the included edges are stored in the provided FunctionElement object.
*
* @param callGraph the CallGraph object for this target project
* @param m the target SootMethod object to be processed
* @param element the target FunctionElement object to be processed
* @param includeList a list to store all whitelist class names for this run
* @param excludeList a list to store all blacklist class names for this run
* @param excludeMethodList a list to store all backlist method names for this run
* @param edgeClassMap a map to store class names with polymorphism methods that are merged
* @param functionLineMap a map object to store the starting line number of known methods
*/
public static void updateOutgoingEdges(
CallGraph callGraph,
SootMethod m,
FunctionElement element,
List<String> includeList,
List<String> excludeList,
List<String> excludeMethodList,
Map<String, Set<String>> edgeClassMap,
Map<String, Integer> functionLineMap) {
Integer edges = 0;
Iterator<Edge> outEdges =
MergeUtils.mergePolymorphism(
callGraph, callGraph.edgesOutOf(m), excludeList, includeList, edgeClassMap);

for (; outEdges.hasNext(); edges++) {
Edge edge = outEdges.next();
SootMethod tgt = edge.tgt();

// Skip excluded method
if (excludeMethodList.contains(tgt.getName())) {
edges--;
continue;
}

// Retrieve class name set
String callerClass = edge.src().getDeclaringClass().getName();
String className = "";
Set<String> classNameSet =
new HashSet<String>(
edgeClassMap.getOrDefault(
callerClass
+ ":"
+ tgt.getName()
+ ":"
+ ((edge.srcStmt() == null)
? -1
: edge.srcStmt().getJavaSourceStartLineNumber()),
Collections.emptySet()));
className = MergeUtils.mergeClassName(classNameSet);

// Check if class name has been merged
boolean merged = false;
for (String name : className.split(":")) {
if (name.equals(tgt.getDeclaringClass().getName())) {
merged = true;
break;
}
}
if (!merged) {
className = tgt.getDeclaringClass().getName();
}

// Store details of reached methods
element.addFunctionsReached("[" + className + "]." + tgt.getSubSignature().split(" ")[1]);
functionLineMap.put(
tgt.getSubSignature().split(" ")[1],
(edge.srcStmt() == null) ? -1 : edge.srcStmt().getJavaSourceStartLineNumber());
}

element.setEdgeCount(edges);
}
}

0 comments on commit 94ce64b

Please sign in to comment.