From accd3f525e13ce1a8f5fb6d0683447bc2a5c3004 Mon Sep 17 00:00:00 2001 From: 0xchrisM <> Date: Fri, 14 Sep 2018 11:27:28 -0700 Subject: [PATCH] Add javacg static option for printing method and class modifiers --- README.md | 10 ++++ .../gr/gousiosg/javacg/stat/ClassVisitor.java | 17 ++++++- .../gr/gousiosg/javacg/stat/JCallGraph.java | 32 +++++++++--- .../gousiosg/javacg/stat/MethodVisitor.java | 22 ++++++-- .../java/gr/gousiosg/javacg/stat/Options.java | 50 +++++++++++++++++++ 5 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 src/main/java/gr/gousiosg/javacg/stat/Options.java diff --git a/README.md b/README.md index b14037fe..d553041d 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,16 @@ java -jar javacg-0.1-SNAPSHOT-static.jar lib1.jar lib2.jar... ``` M:class1:(arg_types) (typeofcall)class2:(arg_types) ``` +###### For static options + +`javacg-static` includes option -m or --modifier which will provide the comma seperated modifier(s) (public, static, private, etc...) for the methods and classes + +for example: +``` + java -jar javacg-0.1-SNAPSHOT-static.jar -m lib1.jar lib2.jar... + + M::class1:(arg_types) (typeofcall)class2:(arg_types) +``` The line means that `method1` of `class1` called `method2` of `class2`. The type of call can have one of the following values (refer to diff --git a/src/main/java/gr/gousiosg/javacg/stat/ClassVisitor.java b/src/main/java/gr/gousiosg/javacg/stat/ClassVisitor.java index e03d72c6..7f18f543 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/ClassVisitor.java +++ b/src/main/java/gr/gousiosg/javacg/stat/ClassVisitor.java @@ -28,6 +28,9 @@ package gr.gousiosg.javacg.stat; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + import org.apache.bcel.classfile.Constant; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.classfile.EmptyVisitor; @@ -45,13 +48,23 @@ public class ClassVisitor extends EmptyVisitor { private JavaClass clazz; private ConstantPoolGen constants; private String classReferenceFormat; + private ArrayList options = null; public ClassVisitor(JavaClass jc) { clazz = jc; constants = new ConstantPoolGen(clazz.getConstantPool()); classReferenceFormat = "C:" + clazz.getClassName() + " %s"; } - + public ClassVisitor(JavaClass jc, ArrayList options) { + this(jc); + this.options = options; + + // if option arguments include modifier add modifier attribute + if(Options.MODIFIER.matches(options)) { + classReferenceFormat = "C:" + Modifier.toString(clazz.getModifiers()).replaceAll(" ", ",") + ":" + clazz.getClassName() + " %s"; + } + } + public void visitJavaClass(JavaClass jc) { jc.getConstantPool().accept(this); Method[] methods = jc.getMethods(); @@ -75,7 +88,7 @@ public void visitConstantPool(ConstantPool constantPool) { public void visitMethod(Method method) { MethodGen mg = new MethodGen(method, clazz.getClassName(), constants); - MethodVisitor visitor = new MethodVisitor(mg, clazz); + MethodVisitor visitor = new MethodVisitor(mg, clazz, options); visitor.start(); } diff --git a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java index 4d19408d..c3e4072e 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java +++ b/src/main/java/gr/gousiosg/javacg/stat/JCallGraph.java @@ -30,9 +30,11 @@ import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import gr.gousiosg.javacg.stat.Options; import org.apache.bcel.classfile.ClassParser; @@ -44,16 +46,33 @@ * */ public class JCallGraph { - + + public static void main(String[] args) { + ClassParser cp; try { - for (String arg : args) { + ArrayList allowedOptions = Options.getAllReferences(); + ArrayList options = new ArrayList(); + ArrayList jars = new ArrayList(); + + //parse out any option arguments + for (String arg : args) { + + if(allowedOptions.contains(arg)) { + options.add(arg); + } + else { + jars.add(arg); + } + } + + for (String jarFile : jars) { - File f = new File(arg); + File f = new File(jarFile); if (!f.exists()) { - System.err.println("Jar file " + arg + " does not exist"); + System.err.println("Jar file " + jarFile + " does not exist"); } JarFile jar = new JarFile(f); @@ -67,8 +86,9 @@ public static void main(String[] args) { if (!entry.getName().endsWith(".class")) continue; - cp = new ClassParser(arg,entry.getName()); - ClassVisitor visitor = new ClassVisitor(cp.parse()); + cp = new ClassParser(jarFile,entry.getName()); + ClassVisitor visitor; + visitor = new ClassVisitor(cp.parse(), options); visitor.start(); } } diff --git a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java index 4dd0821b..e9b3a295 100644 --- a/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java +++ b/src/main/java/gr/gousiosg/javacg/stat/MethodVisitor.java @@ -28,6 +28,9 @@ package gr.gousiosg.javacg.stat; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.generic.*; @@ -44,14 +47,27 @@ public class MethodVisitor extends EmptyVisitor { private ConstantPoolGen cp; private String format; + public MethodVisitor(MethodGen m, JavaClass jc) { + this(m, jc, null); + } + public MethodVisitor(MethodGen m, JavaClass jc, ArrayList options) { + visitedClass = jc; mg = m; cp = mg.getConstantPool(); - format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + ")" - + " " + "(%s)%s:%s(%s)"; + String mStr = "Pub"; + + // if option arguments include modifier add modifier attribute + if(options != null && Options.MODIFIER.matches(options)){ + format = "M:" + Modifier.toString(mg.getModifiers()).replaceAll(" ", ",") + ":" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + ")" + + " " + "(%s)%s:%s(%s)"; + } + else{ + format = "M:" + visitedClass.getClassName() + ":" + mg.getName() + "(" + argumentList(mg.getArgumentTypes()) + ")" + + " " + "(%s)%s:%s(%s)"; + } } - private String argumentList(Type[] arguments) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < arguments.length; i++) { diff --git a/src/main/java/gr/gousiosg/javacg/stat/Options.java b/src/main/java/gr/gousiosg/javacg/stat/Options.java new file mode 100644 index 00000000..94dea9a1 --- /dev/null +++ b/src/main/java/gr/gousiosg/javacg/stat/Options.java @@ -0,0 +1,50 @@ +package gr.gousiosg.javacg.stat; + +import java.util.ArrayList; + + +/** + * Enum class to allow for different option arguments in the future and variations of those argument flags + */ + + +public enum Options { + + MODIFIER( new String[]{"-m", "--modifier"}); + + private String[] references; + Options(String[] args){ + references = args; + } + public boolean matches(ArrayList options) { + for(String reference: references) { + if(options.contains(reference)) { + return true; + } + } + return false; + } + public String[] getReferences() { + return references; + } + public boolean containsReference(String option) { + for(String ref: references) { + if(ref.equals(option)) + return true; + } + return false; + } + public static ArrayList getAllReferences() { + ArrayList allReferences = new ArrayList(); + Options[] opts = Options.class.getEnumConstants(); + for(Options opt : opts) { + String[] refs = opt.getReferences(); + for(String ref: refs) { + allReferences.add(ref); + } + + } + return allReferences; + } + +} \ No newline at end of file