Skip to content
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

[Java Integration] : Dig up necessary information from the static analysis #547

Merged
merged 7 commits into from
Oct 18, 2022
Merged
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
26 changes: 16 additions & 10 deletions frontends/java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,46 @@

This is work in progress.

Download and install java / maven in ubuntu
-----------------------------------------
sudo apt-get install -y openjdk-8-jdk-headless maven


Using java-callgraph
-----------------------------------------
Depends on OpenJDK+JRE 11.0 or later
Depends on OpenJDK+JRE 8 or later

Depends on https://github.com/gousiosg/java-callgraph, which has compiled and packed as a jar file (javacg-0.1-SNAPSHOT-static.jar)

It requires the target source code compiled and packed into jar file.

The resulting call tree are shown in stdout.

Example of running: `java -jar javacg-0.1-SNAPSHOT-static.jar <TARGET_JAR_FILE>`
------------------------------------------


Using IBM's WALA
------------------------------------------
Depends on OpenJDK+JRE 11.0 or later
Depends on OpenJDK+JRE 8 or later

Depends on Maven 3.3 or later
Depends on IBM's WALA https://github.com/wala/WALA, the maven build process will automatically
download and pack the WALA jar libraries.

Depends on IBM's WALA https://github.com/wala/WALA, the maven build process will automatically download and pack the WALA jar libraries.

The resulting call tree are shown in stdout.

Example of running: `./run.sh <-j | --jarFile> <jarFile1:...:javaFileN> <-e | --entryclass> <Public Entry Class Name>`
------------------------------------------


Using Soot
------------------------------------------
Depends on OpenJDK+JRE 11.0 or later
Depends on OpenJDK+JRE 8 or later

Depends on Maven 3.3 or later
Depends on IBM's WALA https://github.com/soot-oss/soot, the maven build process will automatically
download and pack the Soot jar libraries.

Depends on IBM's WALA https://github.com/soot-oss/soot, the maven build process will automatically download and pack the Soot jar libraries.

The resulting call tree are shown in stdout.

Example of running: `./run.sh <-j | --jarFile> <jarFile1:...:javaFileN> <-c | --entryclass> <Public Entry Class Name>` <-m | --entrymethod <Public Entry Method Name>`
Example of running: `./run.sh <-j | --jarFile> <jarFile1:...:javaFileN> <-c | --entryclass> <Public Entry Class Name> <-m | --entrymethod <Public Entry Method Name>`

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.
///////////////////////////////////////////////////////////////////////////


package ossf.fuzz.introspector.soot;

import java.io.File;
Expand All @@ -23,18 +22,25 @@
import java.util.List;
import java.util.Map;

import soot.MethodOrMethodContext;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import ossf.fuzz.introspector.soot.yaml.FunctionConfig;
import ossf.fuzz.introspector.soot.yaml.FunctionElement;
import ossf.fuzz.introspector.soot.yaml.FuzzerConfig;
import soot.PackManager;
import soot.Scene;
import soot.SceneTransformer;
import soot.SootClass;
import soot.SootMethod;
import soot.Transform;
import soot.jimple.toolkits.callgraph.CallGraph;
import soot.jimple.toolkits.callgraph.Targets;
import soot.jimple.toolkits.callgraph.Edge;
import soot.options.Options;

public class CallGraphGenerator {
public class CallGraphGenerator
{
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("No entryClass or entryMethod.");
Expand All @@ -59,6 +65,7 @@ public static void main(String[] args) {
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);
Options.v().set_app(true);
Options.v().set_keep_line_number(true);

// Load and set main class
Options.v().set_main_class(entryClass);
Expand All @@ -85,6 +92,7 @@ class CustomSenceTransformer extends SceneTransformer {
public CustomSenceTransformer() {
excludeList = new LinkedList<String> ();

excludeList.add("jdk.");
excludeList.add("java.");
excludeList.add("javax.");
excludeList.add("sun.");
Expand All @@ -98,21 +106,101 @@ public CustomSenceTransformer() {
@Override
protected void internalTransform(String phaseName, Map<String, String> options) {
int numOfEdges = 0;
int numOfClasses = 0;
int numOfMethods = 0;
List<FuzzerConfig> classYaml = new ArrayList<FuzzerConfig>();

CallGraph callGraph = Scene.v().getCallGraph();
System.out.println("--------------------------------------------------");
for(SootClass c : Scene.v().getApplicationClasses()) {
for(SootMethod m : c.getMethods()){
Iterator<MethodOrMethodContext> targets = new Targets(callGraph.edgesOutOf(m));
for ( ; targets.hasNext(); numOfEdges++) {
SootMethod tgt = (SootMethod) targets.next();
System.out.println(m + " may call " + tgt);
if (c.getName().startsWith("jdk")) {
continue;
}

FuzzerConfig classConfig = new FuzzerConfig();
FunctionConfig methodConfig = new FunctionConfig();
classConfig.setFilename(c.getName());
methodConfig.setListName("All functions");

numOfClasses++;
System.out.println("Class #" + numOfClasses + ": " + c.getName());
for (SootMethod m : c.getMethods()) {
FunctionElement element= new FunctionElement();
element.setFunctionName(m.getName());
element.setFunctionSourceFile(c.getFilePath());
//element.setLinkageType("???");
element.setFunctionLinenumber(m.getJavaSourceStartLineNumber());
element.setReturnType(m.getReturnType().toString());
element.setArgCount(m.getParameterCount());
for (soot.Type type:m.getParameterTypes()) {
element.addArgType(type.toString());
}
//element.setConstantsTouched([]);
//element.setArgNames();
//element.setBBCount(0);
//element.setiCount(0);
//element.setCyclomaticComplexity(0);

numOfMethods++;
int methodEdges = 0;
Iterator<Edge> outEdges = callGraph.edgesOutOf(m);
Iterator<Edge> inEdges = callGraph.edgesInto(m);
System.out.println("Class #" + numOfClasses + " Method #" +
numOfMethods + ": " + m);

if (!inEdges.hasNext()) {
System.out.println("\t > No calls to this method.");
}

for ( ; inEdges.hasNext(); methodEdges++) {
Edge edge = inEdges.next();
SootMethod src = (SootMethod) edge.getSrc();
System.out.println("\t > called by " + src + " on Line " +
edge.srcStmt().getJavaSourceStartLineNumber());
}

System.out.println("\n\t Total: " + methodEdges + " internal calls.\n");

element.setFunctionUses(methodEdges);
methodEdges = 0;

if (!outEdges.hasNext()) {
System.out.println("\t > No calls from this method.");
}

for ( ; outEdges.hasNext(); methodEdges++) {
Edge edge = outEdges.next();
SootMethod tgt = (SootMethod) edge.getTgt();
System.out.println("\t > calls " + tgt + " on Line " +
edge.srcStmt().getJavaSourceStartLineNumber());
element.addFunctionReached(tgt.toString() + "; Line: " +
edge.srcStmt().getJavaSourceStartLineNumber());
}
System.out.println("\n\t Total: " + methodEdges + " external calls.\n");
numOfEdges += methodEdges;

element.setEdgeCount(methodEdges);
//element.setBranchProfiles(new BranchProfile());
methodConfig.addFunctionElement(element);
}
System.out.println("--------------------------------------------------");
classConfig.setFunctionConfig(methodConfig);
classYaml.add(classConfig);
}
System.out.println("Total Edges:" + numOfEdges);
System.out.println("--------------------------------------------------");
ObjectMapper om = new ObjectMapper(new YAMLFactory());
for(FuzzerConfig config:classYaml) {
try {
System.out.println(om.writeValueAsString(config) + "\n");
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

public List<String> getExcludeList() {
return excludeList;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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.yaml;

public class BranchProfile {
private String branchString;
private BranchSide branchSides;

public String getBranchString() {
return branchString;
}

public void setBranchString(String branchString) {
this.branchString = branchString;
}

public BranchSide getBranchSides() {
return branchSides;
}

public void setBranchSides(BranchSide branchSides) {
this.branchSides = branchSides;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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.yaml;

import java.util.ArrayList;
import java.util.List;

public class BranchSide {
private String trueSides;
private List<String> trueSidesFuncs;
private String falseSides;
private List<String> falseSidesFuncs;

public BranchSide() {
this.trueSidesFuncs = new ArrayList<String>();
this.falseSidesFuncs = new ArrayList<String>();
}

public String getTrueSides() {
return trueSides;
}

public void setTrueSides(String trueSides) {
this.trueSides = trueSides;
}

public List<String> getTrueSidesFuncs() {
return trueSidesFuncs;
}

public void addTrueSidesFuncs(String trueSidesFunc) {
this.trueSidesFuncs.add(trueSidesFunc);
}

public void setTrueSidesFuncs(List<String> trueSidesFuncs) {
this.trueSidesFuncs = trueSidesFuncs;
}

public String getFalseSides() {
return falseSides;
}

public void setFalseSides(String falseSides) {
this.falseSides = falseSides;
}

public List<String> getFalseSidesFuncs() {
return falseSidesFuncs;
}

public void addFalseSidesFuncs(String falseSidesFunc) {
this.falseSidesFuncs.add(falseSidesFunc);
}

public void setFalseSidesFuncs(List<String> falseSidesFuncs) {
this.falseSidesFuncs = falseSidesFuncs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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.yaml;

import java.util.ArrayList;
import java.util.List;

public class FunctionConfig {
private String listName;
private List<FunctionElement> functionElements;

public FunctionConfig() {
this.functionElements = new ArrayList<FunctionElement>();
}

public String getListName() {
return listName;
}

public void setListName(String listName) {
this.listName = listName;
}

public List<FunctionElement> getFunctionElements() {
return functionElements;
}

public void addFunctionElement(FunctionElement functionElement) {
this.functionElements.add(functionElement);
}

public void setFunctionElements(List<FunctionElement> functionElements) {
this.functionElements = functionElements;
}
}
Loading