Added Inner/OuterClass support and TryCatchBlocks

This commit is contained in:
SuspiciousActivity committed 2018-04-21 12:48:54 +02:00
1 parent 7421c3af91
commit 96cb81a8ac
3 files changed
+79 -38

No files matched your search

+55 -18
View File
@@ -22,6 +22,7 @@ import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode; import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.IincInsnNode; import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode; import org.objectweb.asm.tree.IntInsnNode;
@@ -36,6 +37,7 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode; import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode; import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.VarInsnNode;
@@ -58,7 +60,19 @@ public class Assembler {
clazz.version = Integer.parseInt(s.substring(12)); clazz.version = Integer.parseInt(s.substring(12));
while (!(s = read.readLine()).startsWith("// #SourceFile: ")) { while ((s = read.readLine()).startsWith("// ")) {
if (s.startsWith("// #OuterClass: ")) {
clazz.outerClass = s.substring(16).equals("null") ? null : s.substring(16);
} else if (s.equals("// #InnerClasses:")) {
clazz.innerClasses = new ArrayList<>();
} else {
String split[] = s.split(" ");
clazz.innerClasses.add(new InnerClassNode(split[1], split[2].equals("null") ? null : split[2],
split[3].equals("null") ? null : split[3], Integer.parseInt(split[4])));
}
}
{
s = s.substring(0, s.length() - 2); s = s.substring(0, s.length() - 2);
if (s.contains(" implements ")) { if (s.contains(" implements ")) {
String interfaces = s.substring(s.indexOf(" implements ") + 12); String interfaces = s.substring(s.indexOf(" implements ") + 12);
@@ -108,9 +122,10 @@ public class Assembler {
clazz.access ^= ClassUtil.ACC_ABSTRACT; clazz.access ^= ClassUtil.ACC_ABSTRACT;
} }
} }
} }
s = read.readLine();
clazz.sourceFile = s.substring(16).equals("null") ? null : s.substring(16); clazz.sourceFile = s.substring(16).equals("null") ? null : s.substring(16);
while (!(s = read.readLine()).equals("// #Fields")) { while (!(s = read.readLine()).equals("// #Fields")) {
@@ -208,20 +223,16 @@ public class Assembler {
} }
} }
HashMap<String, HashMap<Label, Integer>> classLabelMap; HashMap<Label, Integer> methodLabelMap = new HashMap<Label, Integer>();
if ((classLabelMap = Main.labels.get(clazz.name)) == null) {
classLabelMap = new HashMap<String, HashMap<Label, Integer>>();
Main.labels.put(clazz.name, classLabelMap);
} else {
classLabelMap.clear();
}
HashMap<Label, Integer> methodLabelMap = null;
annotationsForNext.clear(); annotationsForNext.clear();
MethodNode node = null; MethodNode node = null;
String temp = ""; String temp = "";
ArrayList<String> localVarsToParse = new ArrayList<>(); ArrayList<String> localVarsToParse = new ArrayList<>();
ArrayList<String> tryCatchBlocksToParse = new ArrayList<>();
int stage = 0;
while ((s = read.readLine()) != null) { while ((s = read.readLine()) != null) {
if (s.trim().isEmpty() || s.equals("}")) if (s.trim().isEmpty() || s.equals("}"))
@@ -240,10 +251,19 @@ public class Assembler {
node.maxLocals = Integer.parseInt(s.split(" ")[0]); node.maxLocals = Integer.parseInt(s.split(" ")[0]);
node.maxStack = Integer.parseInt(s.split(" ")[1].substring(2)); node.maxStack = Integer.parseInt(s.split(" ")[1].substring(2));
localVarsToParse.clear(); localVarsToParse.clear();
tryCatchBlocksToParse.clear();
stage = 0;
} else if (s.equals("// #TryCatch:")) {
stage = 1;
} else if (s.equals("// #LocalVars:")) { } else if (s.equals("// #LocalVars:")) {
} else if (s.startsWith("// ")) { // LocalVars stage = 2;
} else if (s.startsWith("// ")) {
s = s.substring(3); s = s.substring(3);
localVarsToParse.add(s); if (stage == 1) {
tryCatchBlocksToParse.add(s);
} else if (stage == 2) {
localVarsToParse.add(s);
}
} else if (s.equals("}")) { } else if (s.equals("}")) {
if (!annotationsForNext.isEmpty()) { if (!annotationsForNext.isEmpty()) {
if (node.visibleAnnotations == null) { if (node.visibleAnnotations == null) {
@@ -272,6 +292,28 @@ public class Assembler {
node.localVariables.add(new LocalVariableNode(sp[0], sp[1].substring(1, sp[1].length() - 2), node.localVariables.add(new LocalVariableNode(sp[0], sp[1].substring(1, sp[1].length() - 2),
null, _start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2)))); null, _start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
} }
for (String st : tryCatchBlocksToParse) {
String[] sp = st.split(" ");
int start = Integer.parseInt(sp[1].substring(2));
int end = Integer.parseInt(sp[2].substring(2));
int handler = Integer.parseInt(sp[3].substring(2));
LabelNode _start = null;
LabelNode _end = null;
LabelNode _handler = null;
for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) {
if (entry.getValue() == start) {
_start = new LabelNode(entry.getKey());
}
if (entry.getValue() == end) {
_end = new LabelNode(entry.getKey());
}
if (entry.getValue() == handler) {
_handler = new LabelNode(entry.getKey());
}
}
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler, sp[0]));
}
clazz.methods.add(node); clazz.methods.add(node);
} else if (!s.startsWith("\t")) { } else if (!s.startsWith("\t")) {
s = s.substring(0, s.length() - 2); s = s.substring(0, s.length() - 2);
@@ -338,12 +380,7 @@ public class Assembler {
} }
} }
node.access = access; node.access = access;
if ((methodLabelMap = classLabelMap.get(node.name + "|" + node.desc)) == null) { methodLabelMap.clear();
methodLabelMap = new HashMap<Label, Integer>();
classLabelMap.put(node.name + "|" + node.desc, methodLabelMap);
} else {
methodLabelMap.clear();
}
} else { } else {
s = s.substring(1); s = s.substring(1);
if (!temp.isEmpty()) { if (!temp.isEmpty()) {
+23 -16
View File
@@ -16,6 +16,7 @@ import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode; import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.IincInsnNode; import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode; import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.InvokeDynamicInsnNode;
@@ -29,6 +30,7 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode; import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TableSwitchInsnNode; import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.VarInsnNode;
@@ -39,13 +41,6 @@ public class Disassembler {
return "ClassNode is null! This is not a valid java class file!"; return "ClassNode is null! This is not a valid java class file!";
} }
try { try {
HashMap<String, HashMap<Label, Integer>> classLabelMap;
if ((classLabelMap = Main.labels.get(classNode.name)) == null) {
classLabelMap = new HashMap<String, HashMap<Label, Integer>>();
Main.labels.put(classNode.name, classLabelMap);
} else {
classLabelMap.clear();
}
String s = ""; String s = "";
s += "// #Annotations\n"; s += "// #Annotations\n";
if (classNode.visibleAnnotations != null && !classNode.visibleAnnotations.isEmpty()) { if (classNode.visibleAnnotations != null && !classNode.visibleAnnotations.isEmpty()) {
@@ -104,6 +99,13 @@ public class Disassembler {
} }
} }
s += "// #Class v:" + classNode.version + "\n"; s += "// #Class v:" + classNode.version + "\n";
s += "// #OuterClass: " + classNode.outerClass + "\n";
s += "// #InnerClasses:\n";
if (classNode.innerClasses != null) {
for (InnerClassNode icn : classNode.innerClasses) {
s += "// " + icn.name + " " + icn.outerName + " " + icn.innerName + " " + icn.access + "\n";
}
}
s += ClassUtil.getAccessFlagsClass(classNode.access) + classNode.name + " "; s += ClassUtil.getAccessFlagsClass(classNode.access) + classNode.name + " ";
s += "extends " + classNode.superName + " "; s += "extends " + classNode.superName + " ";
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) { if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
@@ -188,14 +190,10 @@ public class Disassembler {
for (MethodNode mn : classNode.methods) { for (MethodNode mn : classNode.methods) {
try { try {
HashMap<Label, Integer> methodLabelMap;
if ((methodLabelMap = classLabelMap.get(mn.name + "|" + mn.desc)) == null) {
methodLabelMap = new HashMap<Label, Integer>();
classLabelMap.put(mn.name + "|" + mn.desc, methodLabelMap);
}
s += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n"; s += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
String[] dis = disassembleMethod(classNode.name, mn, methodLabelMap); String[] dis = disassembleMethod(classNode.name, mn);
s += dis[2];
s += dis[1]; s += dis[1];
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) { if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) {
@@ -286,19 +284,28 @@ public class Disassembler {
} }
} }
private static String[] disassembleMethod(String className, MethodNode mn, HashMap<Label, Integer> labels) { private static String[] disassembleMethod(String className, MethodNode mn) {
HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
String s = ""; String s = "";
String localVarTable = "\t// #LocalVars:\n"; String localVarTable = "\t// #LocalVars:\n";
String tryCatchTable = "\t// #TryCatch:\n";
for (AbstractInsnNode n : mn.instructions.toArray()) { for (AbstractInsnNode n : mn.instructions.toArray()) {
if (n instanceof LabelNode) { if (n instanceof LabelNode) {
labels.put(((LabelNode) n).getLabel(), labels.size() + 1); labels.put(((LabelNode) n).getLabel(), labels.size() + 1);
} }
} }
if (mn.localVariables != null) if (mn.localVariables != null) {
for (LocalVariableNode lvn : mn.localVariables) { for (LocalVariableNode lvn : mn.localVariables) {
localVarTable += "\t// " + lvn.name + ": " + lvn.desc + " i:" + lvn.index + " s:" localVarTable += "\t// " + lvn.name + ": " + lvn.desc + " i:" + lvn.index + " s:"
+ labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + "\n"; + labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + "\n";
} }
}
if (mn.tryCatchBlocks != null) {
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
tryCatchTable += "\t// " + tcbn.type + " s:" + labels.get(tcbn.start.getLabel()) + " e:"
+ labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n";
}
}
for (AbstractInsnNode n : mn.instructions.toArray()) { for (AbstractInsnNode n : mn.instructions.toArray()) {
switch (n.getClass().getSimpleName()) { switch (n.getClass().getSimpleName()) {
case "FieldInsnNode": { case "FieldInsnNode": {
@@ -520,7 +527,7 @@ public class Disassembler {
break; break;
} }
} }
return new String[] { s, localVarTable }; return new String[] { s, localVarTable, tryCatchTable };
} }
} }
+1 -4
View File
@@ -64,6 +64,7 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
public class Main extends JFrame { public class Main extends JFrame {
@@ -79,8 +80,6 @@ public class Main extends JFrame {
public static RSyntaxTextArea textArea; public static RSyntaxTextArea textArea;
public static SearchBox searchBox; public static SearchBox searchBox;
// Class, Method, LabelMap
public static HashMap<String, HashMap<String, HashMap<Label, Integer>>> labels = new HashMap<>();
/** /**
* Launch the application. * Launch the application.
@@ -237,7 +236,6 @@ public class Main extends JFrame {
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 116 && jarFile != null) { if (e.getKeyCode() == 116 && jarFile != null) {
try { try {
labels.clear();
isChangingFile = true; isChangingFile = true;
try { try {
tree.setModel(new ArchiveTreeModel(new JarFile(jarFile))); tree.setModel(new ArchiveTreeModel(new JarFile(jarFile)));
@@ -321,7 +319,6 @@ public class Main extends JFrame {
final File file = files.get(0); final File file = files.get(0);
if (file.getName().endsWith(".jar")) { if (file.getName().endsWith(".jar")) {
labels.clear();
jarFile = file; jarFile = file;
isChangingFile = true; isChangingFile = true;
try { try {