Skip to content

Instantly share code, notes, and snippets.

@DinisCruz
Last active September 5, 2016 13:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DinisCruz/cb434226ae7e974e7cfe3ea7f1c890bd to your computer and use it in GitHub Desktop.
Save DinisCruz/cb434226ae7e974e7cfe3ea7f1c890bd to your computer and use it in GitHub Desktop.
javap helper to quickly extract list of methods called from method
package ....appsec.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class JavapHelper {
public Class target;
public JavapHelper(Class clazz)
{
target = clazz;
}
public String pathToClass()
{
return this.target.getResource("/" + this.target.getName().replace(".","/") + ".class").toString();
}
/**
* returns the result of javap with option -v on the provided class
*/
public String decompileClass() {
String path = this.pathToClass(); // full path to class to map
String[] args = new String[] {"-v", path}; // trigger javap -v option
StringWriter stringWriter = new StringWriter(); // create StringWritter
PrintWriter printWriter = new PrintWriter(stringWriter); // for PrintWriter
com.sun.tools.javap.Main.run(args, printWriter); // that is used by the javap main.run method
printWriter.close();
return stringWriter.toString(); // get result as string
}
/**
* returns class contant pool values as hashmap
*/
public HashMap<String,List<String>> constantPool()
{
String rawData = this.decompileClass();
String[] lines = rawData.split("\n");
HashMap<String,List<String>> results = new HashMap<String,List<String>>();
boolean insideConstantPool = false;
for (String line :lines) {
if(line.equals("Constant pool:")) // start of Constant pool data
{
System.out.println(line);
insideConstantPool = true;
continue;
}
if(insideConstantPool)
{
if (line.equals("{"))
break;
String[] data = line.split("=",2) // extract the data to the right of the first =
[1].trim() // [0] is the id [1] is the rest of the line
.split(" ", 2); // split the constant pool name and its value
if (data.length == 2) {
String key = data[0]; // constant pool name
String value = data[1]; // constant pool value
if (!results.containsKey(key)) // if it is the first time we see this key
results.put(key, new ArrayList<>());
results.get(key).add(value.trim()); // add key's value to key's list<String>
}
}
}
return results;
}
/**
* returns list of methodsRef found in constant pool (these are the methods called by class' methods
*/
public List<String> methodRefs()
{
ArrayList<String> methodRefs = new ArrayList<>();
HashMap<String,List<String>> constantPool = this.constantPool();
for(String entry : constantPool.get("Methodref")) // for each methodRef
{
String[] items = entry.split("//", 2); // split by comment
methodRefs.add(items[1].trim()); // use the right-hand side
}
return methodRefs;
}
}
package ....appsec.utils;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.greaterThan;
public class JavapHelperTest {
JavapHelper javapHelper = null;
Class target = null;
@Before
public void beforeClass()
{
target = JavapHelper.class;
javapHelper = new JavapHelper(target);
}
@Test
public void pathToClass()
{
String result = javapHelper.pathToClass();
assertThat(result, containsString(".../appsec/utils/JavapHelper.class"));
}
@Test
public void decompileTest() {
String result = javapHelper.decompileClass();
assertThat(result, containsString("public java.lang.String decompileClass();"));
assertThat(result, containsString("13: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;"));
}
@Test
public void constantPool() throws Exception {
HashMap<String,List<String>> result = javapHelper.constantPool();
assertThat(result.keySet().toArray(), is(new String[] { "Methodref", "Fieldref", "Utf8", "NameAndType", "Class", "String", "InterfaceMethodref"}));
}
@Test
public void methodsRefs() throws Exception {
List<String> result = javapHelper.methodRefs();
assertThat(result.size(), greaterThan(10));
assertThat(result, hasItem("java/lang/Object.\"<init>\":()V"));
assertThat(result, hasItem("java/lang/StringBuilder.\"<init>\":()V"));
assertThat(result, hasItem("java/lang/Class.getResource:(Ljava/lang/String;)Ljava/net/URL;"));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment