From 6e1a0a26b35f394c68890004ebe9fe4893e51dad Mon Sep 17 00:00:00 2001 From: SuspiciousActivity <38253929+SuspiciousActivity@users.noreply.github.com> Date: Sun, 10 Feb 2019 00:07:32 +0100 Subject: [PATCH] Updated frames --- src/me/ByteEdit/edit/Assembler.java | 1705 +++++++++-------- src/me/ByteEdit/edit/Disassembler.java | 445 +++-- src/me/ByteEdit/main/Main.java | 2 + .../autocomplete/CompletionProviderBase.java | 65 +- 4 files changed, 1145 insertions(+), 1072 deletions(-) diff --git a/src/me/ByteEdit/edit/Assembler.java b/src/me/ByteEdit/edit/Assembler.java index d656c7d..e058c67 100644 --- a/src/me/ByteEdit/edit/Assembler.java +++ b/src/me/ByteEdit/edit/Assembler.java @@ -15,6 +15,7 @@ import javax.swing.text.BadLocationException; import org.objectweb.asm.Handle; import org.objectweb.asm.Label; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AnnotationNode; @@ -79,9 +80,10 @@ public class Assembler { clazz.innerClasses = new ArrayList<>(); } else { String split[] = s.split(" "); - clazz.innerClasses - .add(new InnerClassNode(UnicodeUtils.unescape(split[1]), split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]), - split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), Integer.parseInt(split[4].substring(2), 16))); + clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(split[1]), + split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]), + split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), + Integer.parseInt(split[4].substring(2), 16))); } } { @@ -100,22 +102,22 @@ public class Assembler { clazz.name = UnicodeUtils.unescape(split[split.length - 1]); clazz.access = ClassUtil.ACC_SUPER; switch (split[split.length - 2]) { - case "class": - break; - case "enum": - clazz.access ^= ClassUtil.ACC_ENUM; - break; - case "interface": - clazz.access = 0; - clazz.access ^= ClassUtil.ACC_ABSTRACT; - clazz.access ^= ClassUtil.ACC_INTERFACE; - break; - case "@interface": - clazz.access = 0; - clazz.access ^= ClassUtil.ACC_ABSTRACT; - clazz.access ^= ClassUtil.ACC_ANNOTATION; - clazz.access ^= ClassUtil.ACC_INTERFACE; - break; + case "class": + break; + case "enum": + clazz.access ^= ClassUtil.ACC_ENUM; + break; + case "interface": + clazz.access = 0; + clazz.access ^= ClassUtil.ACC_ABSTRACT; + clazz.access ^= ClassUtil.ACC_INTERFACE; + break; + case "@interface": + clazz.access = 0; + clazz.access ^= ClassUtil.ACC_ABSTRACT; + clazz.access ^= ClassUtil.ACC_ANNOTATION; + clazz.access ^= ClassUtil.ACC_INTERFACE; + break; } if (split.length > 2) { String cons = consolidateStrings(split, 0, split.length - 2); @@ -135,7 +137,8 @@ public class Assembler { } s = read.readLine(); clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16)); - while (!(s = read.readLine()).equals("// #Fields")) {} + while (!(s = read.readLine()).equals("// #Fields")) { + } clazz.fields = new ArrayList<>(); clazz.methods = new ArrayList<>(); String signature = null; @@ -297,8 +300,9 @@ public class Assembler { _end = new LabelNode(entry.getKey()); } } - node.localVariables.add(new LocalVariableNode(sp[0], UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), - signat, _start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2)))); + node.localVariables.add(new LocalVariableNode(sp[0], + UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat, _start, _end, + Integer.parseInt(sp[2].substring(0, sp[2].length() - 2)))); } for (String st : tryCatchBlocksToParse) { String[] sp = st.split(" "); @@ -319,8 +323,8 @@ public class Assembler { _handler = new LabelNode(entry.getKey()); } } - node.tryCatchBlocks - .add(new TryCatchBlockNode(_start, _end, _handler, sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0]))); + node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler, + sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0]))); } clazz.methods.add(node); } else if (!s.startsWith("\t")) { @@ -427,7 +431,8 @@ public class Assembler { } finally { try { read.close(); - } catch (Exception e) {} + } catch (Exception e) { + } } } @@ -458,7 +463,8 @@ public class Assembler { list.add(rofl.substring(1, index)); } else if (!rofl.startsWith("(")) { int index = rofl.indexOf(";"); - list.add(new String[] { rofl.substring(0, index) + ";", rofl.substring(index).substring(2) }); + list.add(new String[] { rofl.substring(0, index) + ";", + rofl.substring(index).substring(2) }); } else { list.add(ClassUtil.getCastedValue(rofl.split(" ")[1], rofl.split("\\) ")[0].substring(1))); } @@ -471,9 +477,11 @@ public class Assembler { node.values.add(value.substring(1, index)); } else if (!value.startsWith("(")) { int index = value.indexOf(";"); - node.values.add(new String[] { value.substring(0, index) + ";", value.substring(index).substring(2) }); + node.values.add( + new String[] { value.substring(0, index) + ";", value.substring(index).substring(2) }); } else { - node.values.add(ClassUtil.getCastedValue(value.split(" ")[1], value.split("\\) ")[0].substring(1))); + node.values.add( + ClassUtil.getCastedValue(value.split(" ")[1], value.split("\\) ")[0].substring(1))); } } } @@ -512,27 +520,27 @@ public class Assembler { return null; } switch (to) { - case "B": - return Byte.parseByte(s); - case "Z": - return Boolean.parseBoolean(s); - case "I": - return Integer.parseInt(s); - case "J": - return Long.parseLong(s.substring(0, s.length() - 1)); - case "C": - return (char) Integer.parseInt(s); - case "D": - return Double.parseDouble(s); - case "F": - return Float.parseFloat(s.substring(0, s.length() - 1)); - case "S": - return Short.parseShort(s); - case "Ljava/lang/String;": - return UnicodeUtils.unescape(s.substring(1, s.length() - 1)); - default: { - return null; - } + case "B": + return Byte.parseByte(s); + case "Z": + return Boolean.parseBoolean(s); + case "I": + return Integer.parseInt(s); + case "J": + return Long.parseLong(s.substring(0, s.length() - 1)); + case "C": + return (char) Integer.parseInt(s); + case "D": + return Double.parseDouble(s); + case "F": + return Float.parseFloat(s.substring(0, s.length() - 1)); + case "S": + return Short.parseShort(s); + case "Ljava/lang/String;": + return UnicodeUtils.unescape(s.substring(1, s.length() - 1)); + default: { + return null; + } } } @@ -559,8 +567,8 @@ public class Assembler { labels.put(l, labelNr); return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), new LabelNode(l)); } else if (s.startsWith("// frame ")) { - String str1 = s.substring(9); - String str = str1.substring(2); + String str1 = s.substring(7); + String str = str1.substring(str1.indexOf(' ', 3) + 1); Object[] local; Object[] stack; ArrayList arr = new ArrayList<>(); @@ -641,620 +649,575 @@ public class Assembler { } } } - return new FrameNode(Integer.parseInt(str1.split(" ")[0]), local != null ? local.length : 0, local, stack != null ? stack.length : 0, - stack); + int type = 0; + switch (str1.substring(str1.indexOf(' ', 1) + 1, str1.indexOf(' ', 3))) { + case "NEW": + type = Opcodes.F_NEW; + break; + case "FULL": + type = Opcodes.F_FULL; + break; + case "APPEND": + type = Opcodes.F_APPEND; + break; + case "CHOP": + type = Opcodes.F_CHOP; + break; + case "SAME": + type = Opcodes.F_SAME; + break; + case "SAME1": + type = Opcodes.F_SAME1; + break; + } + return new FrameNode(type, local.length, local, stack.length, stack); } else { String[] split = s.split(" "); String command = split[0]; switch (command) { - case "nop": - return new InsnNode(0); - case "aconst_null": - return new InsnNode(1); - case "iconst_m1": - return new InsnNode(2); - case "iconst_0": - return new InsnNode(3); - case "iconst_1": - return new InsnNode(4); - case "iconst_2": - return new InsnNode(5); - case "iconst_3": - return new InsnNode(6); - case "iconst_4": - return new InsnNode(7); - case "iconst_5": - return new InsnNode(8); - case "lconst_0": - return new InsnNode(9); - case "lconst_1": - return new InsnNode(10); - case "fconst_0": - return new InsnNode(11); - case "fconst_1": - return new InsnNode(12); - case "fconst_2": - return new InsnNode(13); - case "dconst_0": - return new InsnNode(14); - case "dconst_1": - return new InsnNode(15); - case "bipush": { - return new IntInsnNode(16, Integer.parseInt(split[1])); - } - case "sipush": { - return new IntInsnNode(17, Integer.parseInt(split[1])); - } - case "ldc": { - String str = consolidateStrings(split, 1); - Object val; - try { - if (str.startsWith("Type: ")) { - str = str.substring(8, str.length() - 2); - String[] split2 = str.split("\n\t"); - Constructor constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class, int.class); - constr.setAccessible(true); - String type = split2[0].substring(7); - val = constr.newInstance( - new Object[] { ClassUtil.getIDFromClassNameForType(type), split2[3].substring(6, split2[3].length() - 1), - Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)) }); - } else if (str.startsWith("\"") && str.endsWith("\"")) { - val = UnicodeUtils.unescape(str.substring(1, str.length() - 1)); - } else if (str.endsWith("l")) { - val = Long.parseLong(str.substring(0, str.length() - 1)); - } else if (str.endsWith("f")) { - val = Float.parseFloat(str.substring(0, str.length() - 1)); - } else if (str.contains(".")) { - val = Double.parseDouble(str); - } else { - val = Integer.parseInt(str); - } - } catch (Exception e) { - val = null; - throw e; - } - return new LdcInsnNode(val); - } - case "iload": { - return new VarInsnNode(21, Integer.parseInt(split[1])); - } - case "lload": { - return new VarInsnNode(22, Integer.parseInt(split[1])); - } - case "fload": { - return new VarInsnNode(23, Integer.parseInt(split[1])); - } - case "dload": { - return new VarInsnNode(24, Integer.parseInt(split[1])); - } - case "aload": { - return new VarInsnNode(25, Integer.parseInt(split[1])); - } - case "iaload": { - return new InsnNode(46); - } - case "laload": { - return new InsnNode(47); - } - case "faload": { - return new InsnNode(48); - } - case "daload": { - return new InsnNode(49); - } - case "aaload": { - return new InsnNode(50); - } - case "baload": { - return new InsnNode(51); - } - case "caload": { - return new InsnNode(52); - } - case "saload": { - return new InsnNode(53); - } - case "istore": { - return new VarInsnNode(54, Integer.parseInt(split[1])); - } - case "lstore": { - return new VarInsnNode(55, Integer.parseInt(split[1])); - } - case "fstore": { - return new VarInsnNode(56, Integer.parseInt(split[1])); - } - case "dstore": { - return new VarInsnNode(57, Integer.parseInt(split[1])); - } - case "astore": { - return new VarInsnNode(58, Integer.parseInt(split[1])); - } - case "iastore": { - return new InsnNode(79); - } - case "lastore": { - return new InsnNode(80); - } - case "fastore": { - return new InsnNode(81); - } - case "dastore": { - return new InsnNode(82); - } - case "aastore": { - return new InsnNode(83); - } - case "bastore": { - return new InsnNode(84); - } - case "castore": { - return new InsnNode(85); - } - case "sastore": { - return new InsnNode(86); - } - case "pop": { - return new InsnNode(87); - } - case "pop2": { - return new InsnNode(88); - } - case "dup": { - return new InsnNode(89); - } - case "dup_x1": { - return new InsnNode(90); - } - case "dup_x2": { - return new InsnNode(91); - } - case "dup2": { - return new InsnNode(92); - } - case "dup2_x1": { - return new InsnNode(93); - } - case "dup2_x2": { - return new InsnNode(94); - } - case "swap": { - return new InsnNode(95); - } - case "iadd": { - return new InsnNode(96); - } - case "ladd": { - return new InsnNode(97); - } - case "fadd": { - return new InsnNode(98); - } - case "dadd": { - return new InsnNode(99); - } - case "isub": { - return new InsnNode(100); - } - case "lsub": { - return new InsnNode(101); - } - case "fsub": { - return new InsnNode(102); - } - case "dsub": { - return new InsnNode(103); - } - case "imul": { - return new InsnNode(104); - } - case "lmul": { - return new InsnNode(105); - } - case "fmul": { - return new InsnNode(106); - } - case "dmul": { - return new InsnNode(107); - } - case "idiv": { - return new InsnNode(108); - } - case "ldiv": { - return new InsnNode(109); - } - case "fdiv": { - return new InsnNode(110); - } - case "ddiv": { - return new InsnNode(111); - } - case "irem": { - return new InsnNode(112); - } - case "lrem": { - return new InsnNode(113); - } - case "frem": { - return new InsnNode(114); - } - case "drem": { - return new InsnNode(115); - } - case "ineg": { - return new InsnNode(116); - } - case "lneg": { - return new InsnNode(117); - } - case "fneg": { - return new InsnNode(118); - } - case "dneg": { - return new InsnNode(119); - } - case "ishl": { - return new InsnNode(120); - } - case "lshl": { - return new InsnNode(121); - } - case "ishr": { - return new InsnNode(122); - } - case "lshr": { - return new InsnNode(123); - } - case "iushr": { - return new InsnNode(124); - } - case "lushr": { - return new InsnNode(125); - } - case "iand": { - return new InsnNode(126); - } - case "land": { - return new InsnNode(127); - } - case "ior": { - return new InsnNode(128); - } - case "lor": { - return new InsnNode(129); - } - case "ixor": { - return new InsnNode(130); - } - case "lxor": { - return new InsnNode(131); - } - case "iinc": { - return new IincInsnNode(Integer.parseInt(split[1]), Integer.parseInt(split[2])); - } - case "i2l": { - return new InsnNode(133); - } - case "i2f": { - return new InsnNode(134); - } - case "i2d": { - return new InsnNode(135); - } - case "l2i": { - return new InsnNode(136); - } - case "l2f": { - return new InsnNode(137); - } - case "l2d": { - return new InsnNode(138); - } - case "f2i": { - return new InsnNode(139); - } - case "f2l": { - return new InsnNode(140); - } - case "f2d": { - return new InsnNode(141); - } - case "d2i": { - return new InsnNode(142); - } - case "d2l": { - return new InsnNode(143); - } - case "d2f": { - return new InsnNode(144); - } - case "i2b": { - return new InsnNode(145); - } - case "i2c": { - return new InsnNode(146); - } - case "i2s": { - return new InsnNode(147); - } - case "lcmp": { - return new InsnNode(148); - } - case "fcmpl": { - return new InsnNode(149); - } - case "fcmpg": { - return new InsnNode(150); - } - case "dcmpl": { - return new InsnNode(151); - } - case "dcmpg": { - return new InsnNode(152); - } - case "ifeq": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(153, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(153, new LabelNode(l)); - } - case "ifne": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(154, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(154, new LabelNode(l)); - } - case "iflt": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(155, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(155, new LabelNode(l)); - } - case "ifge": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(156, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(156, new LabelNode(l)); - } - case "ifgt": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(157, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(157, new LabelNode(l)); - } - case "ifle": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(158, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(158, new LabelNode(l)); - } - case "if_icmpeq": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(159, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(159, new LabelNode(l)); - } - case "if_icmpne": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(160, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(160, new LabelNode(l)); - } - case "if_icmplt": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(161, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(161, new LabelNode(l)); - } - case "if_icmpge": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(162, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(162, new LabelNode(l)); - } - case "if_icmpgt": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(163, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(163, new LabelNode(l)); - } - case "if_icmple": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(164, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(164, new LabelNode(l)); - } - case "if_acmpeq": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(165, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(165, new LabelNode(l)); - } - case "if_acmpne": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(166, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(166, new LabelNode(l)); - } - case "goto": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(167, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(167, new LabelNode(l)); - } - case "jsr": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(168, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(168, new LabelNode(l)); - } - case "ret": { - return new VarInsnNode(169, Integer.parseInt(s.split(" ")[1])); - } - case "tableswitch": { - String str = s.substring(14, s.length() - 2).replace("\t", ""); - String split2[] = str.split("\n"); - LinkedHashMap labelMap = new LinkedHashMap<>(); - HashMap labelIDs = new HashMap<>(); - for (int i = 4; i < split2.length - 1; i++) { - if (split2[i].equals("null")) { - labelMap.put(new SwitchIntContainer(-1 - labelMap.size()), null); - } else { - labelMap.put(new SwitchIntContainer(Integer.parseInt(split2[i])), null); - } - } - LabelNode dflt = null; - if (!split2[2].substring(9).equals("null")) { - int dfltLabelNr = Integer.parseInt(split2[2].substring(9)); - for (Entry entry : labels.entrySet()) { - if (entry.getValue() == dfltLabelNr) { - dflt = new LabelNode(entry.getKey()); - labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt); - } - labelMap.replaceAll(new BiFunction() { - - @Override - public LabelNode apply(SwitchIntContainer t, LabelNode u) { - if (entry.getValue().intValue() == t.getId()) { - return new LabelNode(entry.getKey()); - } - return u; - } - - }); - } - if (dflt == null) { - Label l = new Label(); - labels.put(l, dfltLabelNr); - dflt = new LabelNode(l); - labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt); - } + case "nop": + return new InsnNode(0); + case "aconst_null": + return new InsnNode(1); + case "iconst_m1": + return new InsnNode(2); + case "iconst_0": + return new InsnNode(3); + case "iconst_1": + return new InsnNode(4); + case "iconst_2": + return new InsnNode(5); + case "iconst_3": + return new InsnNode(6); + case "iconst_4": + return new InsnNode(7); + case "iconst_5": + return new InsnNode(8); + case "lconst_0": + return new InsnNode(9); + case "lconst_1": + return new InsnNode(10); + case "fconst_0": + return new InsnNode(11); + case "fconst_1": + return new InsnNode(12); + case "fconst_2": + return new InsnNode(13); + case "dconst_0": + return new InsnNode(14); + case "dconst_1": + return new InsnNode(15); + case "bipush": { + return new IntInsnNode(16, Integer.parseInt(split[1])); + } + case "sipush": { + return new IntInsnNode(17, Integer.parseInt(split[1])); + } + case "ldc": { + String str = consolidateStrings(split, 1); + Object val; + try { + if (str.startsWith("Type: ")) { + str = str.substring(8, str.length() - 2); + String[] split2 = str.split("\n\t"); + Constructor constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class, + int.class); + constr.setAccessible(true); + String type = split2[0].substring(7); + val = constr.newInstance(new Object[] { ClassUtil.getIDFromClassNameForType(type), + split2[3].substring(6, split2[3].length() - 1), + Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)) }); + } else if (str.startsWith("\"") && str.endsWith("\"")) { + val = UnicodeUtils.unescape(str.substring(1, str.length() - 1)); + } else if (str.endsWith("l")) { + val = Long.parseLong(str.substring(0, str.length() - 1)); + } else if (str.endsWith("f")) { + val = Float.parseFloat(str.substring(0, str.length() - 1)); + } else if (str.contains(".")) { + val = Double.parseDouble(str); } else { - dflt = new LabelNode(new Label()); + val = Integer.parseInt(str); } - LabelNode[] arr = new LabelNode[labelMap.size()]; - int counter = 0; - for (Entry entry : labelMap.entrySet()) { - LabelNode ln; - if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) { - Label l = new Label(); - labels.put(l, entry.getKey().getId()); - ln = new LabelNode(l); - labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln); - } - arr[counter] = ln; - counter++; - } - return new TableSwitchInsnNode(Integer.parseInt(split2[0].substring(5)), Integer.parseInt(split2[1].substring(5)), dflt, arr); + } catch (Exception e) { + val = null; + throw e; } - case "lookupswitch": { - String str = s.substring(15, s.length() - 2).replace("\t", ""); - String split2[] = str.split("\n"); - ArrayList keys = new ArrayList<>(); - LinkedHashMap labelMap = new LinkedHashMap<>(); - HashMap labelIDs = new HashMap<>(); - int stage = 0; - for (int i = 2; i < split2.length; i++) { - String spl = split2[i]; - if (spl.equals("]")) { - stage = 1; - } else if (spl.equals("labels: [")) { - stage = 2; - } else if (stage == 0) { - keys.add(Integer.parseInt(spl)); - } else if (stage == 2) { - if (spl.equals("null")) { - labelMap.put(new SwitchIntContainer(-1 - labelMap.size()), null); - } else { - labelMap.put(new SwitchIntContainer(Integer.parseInt(spl)), null); - } - } + return new LdcInsnNode(val); + } + case "iload": { + return new VarInsnNode(21, Integer.parseInt(split[1])); + } + case "lload": { + return new VarInsnNode(22, Integer.parseInt(split[1])); + } + case "fload": { + return new VarInsnNode(23, Integer.parseInt(split[1])); + } + case "dload": { + return new VarInsnNode(24, Integer.parseInt(split[1])); + } + case "aload": { + return new VarInsnNode(25, Integer.parseInt(split[1])); + } + case "iaload": { + return new InsnNode(46); + } + case "laload": { + return new InsnNode(47); + } + case "faload": { + return new InsnNode(48); + } + case "daload": { + return new InsnNode(49); + } + case "aaload": { + return new InsnNode(50); + } + case "baload": { + return new InsnNode(51); + } + case "caload": { + return new InsnNode(52); + } + case "saload": { + return new InsnNode(53); + } + case "istore": { + return new VarInsnNode(54, Integer.parseInt(split[1])); + } + case "lstore": { + return new VarInsnNode(55, Integer.parseInt(split[1])); + } + case "fstore": { + return new VarInsnNode(56, Integer.parseInt(split[1])); + } + case "dstore": { + return new VarInsnNode(57, Integer.parseInt(split[1])); + } + case "astore": { + return new VarInsnNode(58, Integer.parseInt(split[1])); + } + case "iastore": { + return new InsnNode(79); + } + case "lastore": { + return new InsnNode(80); + } + case "fastore": { + return new InsnNode(81); + } + case "dastore": { + return new InsnNode(82); + } + case "aastore": { + return new InsnNode(83); + } + case "bastore": { + return new InsnNode(84); + } + case "castore": { + return new InsnNode(85); + } + case "sastore": { + return new InsnNode(86); + } + case "pop": { + return new InsnNode(87); + } + case "pop2": { + return new InsnNode(88); + } + case "dup": { + return new InsnNode(89); + } + case "dup_x1": { + return new InsnNode(90); + } + case "dup_x2": { + return new InsnNode(91); + } + case "dup2": { + return new InsnNode(92); + } + case "dup2_x1": { + return new InsnNode(93); + } + case "dup2_x2": { + return new InsnNode(94); + } + case "swap": { + return new InsnNode(95); + } + case "iadd": { + return new InsnNode(96); + } + case "ladd": { + return new InsnNode(97); + } + case "fadd": { + return new InsnNode(98); + } + case "dadd": { + return new InsnNode(99); + } + case "isub": { + return new InsnNode(100); + } + case "lsub": { + return new InsnNode(101); + } + case "fsub": { + return new InsnNode(102); + } + case "dsub": { + return new InsnNode(103); + } + case "imul": { + return new InsnNode(104); + } + case "lmul": { + return new InsnNode(105); + } + case "fmul": { + return new InsnNode(106); + } + case "dmul": { + return new InsnNode(107); + } + case "idiv": { + return new InsnNode(108); + } + case "ldiv": { + return new InsnNode(109); + } + case "fdiv": { + return new InsnNode(110); + } + case "ddiv": { + return new InsnNode(111); + } + case "irem": { + return new InsnNode(112); + } + case "lrem": { + return new InsnNode(113); + } + case "frem": { + return new InsnNode(114); + } + case "drem": { + return new InsnNode(115); + } + case "ineg": { + return new InsnNode(116); + } + case "lneg": { + return new InsnNode(117); + } + case "fneg": { + return new InsnNode(118); + } + case "dneg": { + return new InsnNode(119); + } + case "ishl": { + return new InsnNode(120); + } + case "lshl": { + return new InsnNode(121); + } + case "ishr": { + return new InsnNode(122); + } + case "lshr": { + return new InsnNode(123); + } + case "iushr": { + return new InsnNode(124); + } + case "lushr": { + return new InsnNode(125); + } + case "iand": { + return new InsnNode(126); + } + case "land": { + return new InsnNode(127); + } + case "ior": { + return new InsnNode(128); + } + case "lor": { + return new InsnNode(129); + } + case "ixor": { + return new InsnNode(130); + } + case "lxor": { + return new InsnNode(131); + } + case "iinc": { + return new IincInsnNode(Integer.parseInt(split[1]), Integer.parseInt(split[2])); + } + case "i2l": { + return new InsnNode(133); + } + case "i2f": { + return new InsnNode(134); + } + case "i2d": { + return new InsnNode(135); + } + case "l2i": { + return new InsnNode(136); + } + case "l2f": { + return new InsnNode(137); + } + case "l2d": { + return new InsnNode(138); + } + case "f2i": { + return new InsnNode(139); + } + case "f2l": { + return new InsnNode(140); + } + case "f2d": { + return new InsnNode(141); + } + case "d2i": { + return new InsnNode(142); + } + case "d2l": { + return new InsnNode(143); + } + case "d2f": { + return new InsnNode(144); + } + case "i2b": { + return new InsnNode(145); + } + case "i2c": { + return new InsnNode(146); + } + case "i2s": { + return new InsnNode(147); + } + case "lcmp": { + return new InsnNode(148); + } + case "fcmpl": { + return new InsnNode(149); + } + case "fcmpg": { + return new InsnNode(150); + } + case "dcmpl": { + return new InsnNode(151); + } + case "dcmpg": { + return new InsnNode(152); + } + case "ifeq": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(153, new LabelNode(entry.getKey())); } - LabelNode dflt = null; - int labelNr = Integer.parseInt(split2[0].substring(9)); + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(153, new LabelNode(l)); + } + case "ifne": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(154, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(154, new LabelNode(l)); + } + case "iflt": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(155, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(155, new LabelNode(l)); + } + case "ifge": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(156, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(156, new LabelNode(l)); + } + case "ifgt": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(157, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(157, new LabelNode(l)); + } + case "ifle": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(158, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(158, new LabelNode(l)); + } + case "if_icmpeq": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(159, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(159, new LabelNode(l)); + } + case "if_icmpne": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(160, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(160, new LabelNode(l)); + } + case "if_icmplt": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(161, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(161, new LabelNode(l)); + } + case "if_icmpge": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(162, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(162, new LabelNode(l)); + } + case "if_icmpgt": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(163, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(163, new LabelNode(l)); + } + case "if_icmple": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(164, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(164, new LabelNode(l)); + } + case "if_acmpeq": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(165, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(165, new LabelNode(l)); + } + case "if_acmpne": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(166, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(166, new LabelNode(l)); + } + case "goto": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(167, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(167, new LabelNode(l)); + } + case "jsr": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(168, new LabelNode(entry.getKey())); + } + } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(168, new LabelNode(l)); + } + case "ret": { + return new VarInsnNode(169, Integer.parseInt(s.split(" ")[1])); + } + case "tableswitch": { + String str = s.substring(14, s.length() - 2).replace("\t", ""); + String split2[] = str.split("\n"); + LinkedHashMap labelMap = new LinkedHashMap<>(); + HashMap labelIDs = new HashMap<>(); + for (int i = 4; i < split2.length - 1; i++) { + if (split2[i].equals("null")) { + labelMap.put(new SwitchIntContainer(-1 - labelMap.size()), null); + } else { + labelMap.put(new SwitchIntContainer(Integer.parseInt(split2[i])), null); + } + } + LabelNode dflt = null; + if (!split2[2].substring(9).equals("null")) { + int dfltLabelNr = Integer.parseInt(split2[2].substring(9)); for (Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { + if (entry.getValue() == dfltLabelNr) { dflt = new LabelNode(entry.getKey()); - labelIDs.put(BigInteger.valueOf(labelNr), dflt); + labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt); } labelMap.replaceAll(new BiFunction() { @@ -1270,202 +1233,274 @@ public class Assembler { } if (dflt == null) { Label l = new Label(); - labels.put(l, labelNr); + labels.put(l, dfltLabelNr); dflt = new LabelNode(l); + labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt); + } + } else { + dflt = new LabelNode(new Label()); + } + LabelNode[] arr = new LabelNode[labelMap.size()]; + int counter = 0; + for (Entry entry : labelMap.entrySet()) { + LabelNode ln; + if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) { + Label l = new Label(); + labels.put(l, entry.getKey().getId()); + ln = new LabelNode(l); + labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln); + } + arr[counter] = ln; + counter++; + } + return new TableSwitchInsnNode(Integer.parseInt(split2[0].substring(5)), + Integer.parseInt(split2[1].substring(5)), dflt, arr); + } + case "lookupswitch": { + String str = s.substring(15, s.length() - 2).replace("\t", ""); + String split2[] = str.split("\n"); + ArrayList keys = new ArrayList<>(); + LinkedHashMap labelMap = new LinkedHashMap<>(); + HashMap labelIDs = new HashMap<>(); + int stage = 0; + for (int i = 2; i < split2.length; i++) { + String spl = split2[i]; + if (spl.equals("]")) { + stage = 1; + } else if (spl.equals("labels: [")) { + stage = 2; + } else if (stage == 0) { + keys.add(Integer.parseInt(spl)); + } else if (stage == 2) { + if (spl.equals("null")) { + labelMap.put(new SwitchIntContainer(-1 - labelMap.size()), null); + } else { + labelMap.put(new SwitchIntContainer(Integer.parseInt(spl)), null); + } + } + } + LabelNode dflt = null; + int labelNr = Integer.parseInt(split2[0].substring(9)); + for (Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + dflt = new LabelNode(entry.getKey()); labelIDs.put(BigInteger.valueOf(labelNr), dflt); } - LabelNode[] arr = new LabelNode[labelMap.size()]; - int counter = 0; - for (Entry entry : labelMap.entrySet()) { - LabelNode ln; - if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) { - Label l = new Label(); - labels.put(l, entry.getKey().getId()); - ln = new LabelNode(l); - labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln); + labelMap.replaceAll(new BiFunction() { + + @Override + public LabelNode apply(SwitchIntContainer t, LabelNode u) { + if (entry.getValue().intValue() == t.getId()) { + return new LabelNode(entry.getKey()); + } + return u; } - arr[counter] = ln; - counter++; - } - int[] _keys = new int[keys.size()]; - counter = 0; - for (int i : keys) { - _keys[counter] = i; - counter++; - } - return new LookupSwitchInsnNode(dflt, _keys, arr); + + }); } - case "ireturn": { - return new InsnNode(172); + if (dflt == null) { + Label l = new Label(); + labels.put(l, labelNr); + dflt = new LabelNode(l); + labelIDs.put(BigInteger.valueOf(labelNr), dflt); } - case "lreturn": { - return new InsnNode(173); - } - case "freturn": { - return new InsnNode(174); - } - case "dreturn": { - return new InsnNode(175); - } - case "areturn": { - return new InsnNode(176); - } - case "return": { - return new InsnNode(177); - } - case "getstatic": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new FieldInsnNode(178, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); - } - case "putstatic": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new FieldInsnNode(179, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); - } - case "getfield": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new FieldInsnNode(180, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); - } - case "putfield": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new FieldInsnNode(181, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); - } - case "invokevirtual": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new MethodInsnNode(182, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); - } - case "invokespecial": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new MethodInsnNode(183, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); - } - case "invokestatic": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new MethodInsnNode(184, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); + LabelNode[] arr = new LabelNode[labelMap.size()]; + int counter = 0; + for (Entry entry : labelMap.entrySet()) { + LabelNode ln; + if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) { + Label l = new Label(); + labels.put(l, entry.getKey().getId()); + ln = new LabelNode(l); + labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln); + } + arr[counter] = ln; + counter++; } - case "invokeinterface": { - String target = split[2]; - int index = target.lastIndexOf("/"); - return new MethodInsnNode(185, UnicodeUtils.unescape(target.substring(0, index)), - UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), true); + int[] _keys = new int[keys.size()]; + counter = 0; + for (int i : keys) { + _keys[counter] = i; + counter++; } - case "invokedynamic": { - String str = s.substring(16, s.length() - 2).replace("", ""); - String sp[] = str.split("\n\t"); - ArrayList args = new ArrayList<>(); - ArrayList vals = new ArrayList<>(); - int stage = 0; - for (int i = 10; i < sp.length - 1; i++) { - String st = sp[i].substring(1); - if (st.equals("]")) { - if (stage == 1) { - try { - Constructor constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class, int.class); - constr.setAccessible(true); - args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)), - UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)), - Integer.parseInt(vals.get(1).substring(7)), Integer.parseInt(vals.get(2).substring(5)) })); - } catch (Exception e) { - throw e; - } - } else if (stage == 2) { - args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)), UnicodeUtils.unescape(vals.get(1).substring(7)), - UnicodeUtils.unescape(vals.get(0).substring(6)), UnicodeUtils.unescape(vals.get(2).substring(6)), - Boolean.parseBoolean(vals.get(3).substring(13)))); - vals.clear(); + return new LookupSwitchInsnNode(dflt, _keys, arr); + } + case "ireturn": { + return new InsnNode(172); + } + case "lreturn": { + return new InsnNode(173); + } + case "freturn": { + return new InsnNode(174); + } + case "dreturn": { + return new InsnNode(175); + } + case "areturn": { + return new InsnNode(176); + } + case "return": { + return new InsnNode(177); + } + case "getstatic": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new FieldInsnNode(178, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); + } + case "putstatic": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new FieldInsnNode(179, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); + } + case "getfield": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new FieldInsnNode(180, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); + } + case "putfield": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new FieldInsnNode(181, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1])); + } + case "invokevirtual": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new MethodInsnNode(182, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); + } + case "invokespecial": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new MethodInsnNode(183, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); + } + case "invokestatic": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new MethodInsnNode(184, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false); + } + case "invokeinterface": { + String target = split[2]; + int index = target.lastIndexOf("/"); + return new MethodInsnNode(185, UnicodeUtils.unescape(target.substring(0, index)), + UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), true); + } + case "invokedynamic": { + String str = s.substring(16, s.length() - 2).replace("", ""); + String sp[] = str.split("\n\t"); + ArrayList args = new ArrayList<>(); + ArrayList vals = new ArrayList<>(); + int stage = 0; + for (int i = 10; i < sp.length - 1; i++) { + String st = sp[i].substring(1); + if (st.equals("]")) { + if (stage == 1) { + try { + Constructor constr = Type.class.getDeclaredConstructor(int.class, String.class, + int.class, int.class); + constr.setAccessible(true); + args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)), + UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)), + Integer.parseInt(vals.get(1).substring(7)), + Integer.parseInt(vals.get(2).substring(5)) })); + } catch (Exception e) { + throw e; } - stage = 0; - } else if (st.equals("Type: [")) { - stage = 1; - } else if (stage == 1) { - st = st.substring(1); - vals.add(st); - } else if (st.equals("Handle: [")) { - vals.clear(); - stage = 2; } else if (stage == 2) { - st = st.substring(1); - vals.add(st); + args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)), + UnicodeUtils.unescape(vals.get(1).substring(7)), + UnicodeUtils.unescape(vals.get(0).substring(6)), + UnicodeUtils.unescape(vals.get(2).substring(6)), + Boolean.parseBoolean(vals.get(3).substring(13)))); + vals.clear(); } + stage = 0; + } else if (st.equals("Type: [")) { + stage = 1; + } else if (stage == 1) { + st = st.substring(1); + vals.add(st); + } else if (st.equals("Handle: [")) { + vals.clear(); + stage = 2; + } else if (stage == 2) { + st = st.substring(1); + vals.add(st); } - Object[] _args = new Object[args.size()]; - stage = 0; - for (Object o : args) { - _args[stage] = o; - stage++; + } + Object[] _args = new Object[args.size()]; + stage = 0; + for (Object o : args) { + _args[stage] = o; + stage++; + } + return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)), + UnicodeUtils.unescape(sp[1].substring(6)), + new Handle(Integer.parseInt(sp[7].substring(6)), UnicodeUtils.unescape(sp[4].substring(8)), + UnicodeUtils.unescape(sp[3].substring(7)), UnicodeUtils.unescape(sp[5].substring(7)), + Boolean.parseBoolean(sp[6].substring(14))), + _args); + } + case "new": { + return new TypeInsnNode(187, UnicodeUtils.unescape(split[1])); + } + case "newarray": { + return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1])); + } + case "anewarray": { + return new TypeInsnNode(189, split[1]); + } + case "arraylength": { + return new InsnNode(190); + } + case "athrow": { + return new InsnNode(191); + } + case "checkcast": { + return new TypeInsnNode(192, split[1]); + } + case "instanceof": { + return new TypeInsnNode(193, split[1]); + } + case "monitorenter": { + return new InsnNode(194); + } + case "monitorexit": { + return new InsnNode(195); + } + case "multianewarray": { + return new MultiANewArrayInsnNode(UnicodeUtils.unescape(split[1]), Integer.parseInt(split[2])); + } + case "ifnull": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(198, new LabelNode(entry.getKey())); } - return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)), UnicodeUtils.unescape(sp[1].substring(6)), - new Handle(Integer.parseInt(sp[7].substring(6)), UnicodeUtils.unescape(sp[4].substring(8)), - UnicodeUtils.unescape(sp[3].substring(7)), UnicodeUtils.unescape(sp[5].substring(7)), - Boolean.parseBoolean(sp[6].substring(14))), - _args); } - case "new": { - return new TypeInsnNode(187, UnicodeUtils.unescape(split[1])); - } - case "newarray": { - return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1])); - } - case "anewarray": { - return new TypeInsnNode(189, split[1]); - } - case "arraylength": { - return new InsnNode(190); - } - case "athrow": { - return new InsnNode(191); - } - case "checkcast": { - return new TypeInsnNode(192, split[1]); - } - case "instanceof": { - return new TypeInsnNode(193, split[1]); - } - case "monitorenter": { - return new InsnNode(194); - } - case "monitorexit": { - return new InsnNode(195); - } - case "multianewarray": { - return new MultiANewArrayInsnNode(UnicodeUtils.unescape(split[1]), Integer.parseInt(split[2])); - } - case "ifnull": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(198, new LabelNode(entry.getKey())); - } + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(198, new LabelNode(l)); + } + case "ifnonnull": { + int labelNr = Integer.parseInt(s.split(" ")[1]); + for (Map.Entry entry : labels.entrySet()) { + if (entry.getValue() == labelNr) { + return new JumpInsnNode(199, new LabelNode(entry.getKey())); } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(198, new LabelNode(l)); } - case "ifnonnull": { - int labelNr = Integer.parseInt(s.split(" ")[1]); - for (Map.Entry entry : labels.entrySet()) { - if (entry.getValue() == labelNr) { - return new JumpInsnNode(199, new LabelNode(entry.getKey())); - } - } - Label l = new Label(); - labels.put(l, labelNr); - return new JumpInsnNode(199, new LabelNode(l)); - } - default: - throw new IllegalArgumentException("Illegal Instruction: " + s); + Label l = new Label(); + labels.put(l, labelNr); + return new JumpInsnNode(199, new LabelNode(l)); + } + default: + throw new IllegalArgumentException("Illegal Instruction: " + s); } } } diff --git a/src/me/ByteEdit/edit/Disassembler.java b/src/me/ByteEdit/edit/Disassembler.java index 4646f4a..f0bf2f7 100644 --- a/src/me/ByteEdit/edit/Disassembler.java +++ b/src/me/ByteEdit/edit/Disassembler.java @@ -139,16 +139,18 @@ public class Disassembler { } s += "// #Class v:" + classNode.version + "\n"; s += "// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n"; - s += "// #OuterMethod: " - + (classNode.outerMethod == null ? "null" - : (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " " + UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc))) + s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null" + : (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " " + + UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc))) + "\n"; s += "// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n"; s += "// #InnerClasses:\n"; if (classNode.innerClasses != null) { for (InnerClassNode icn : classNode.innerClasses) { - s += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " " + UnicodeUtils.escapeWithSpaces(icn.outerName) + " " - + UnicodeUtils.escapeWithSpaces(icn.innerName) + " 0x" + Integer.toHexString(icn.access) + "\n"; + s += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " " + + UnicodeUtils.escapeWithSpaces(icn.outerName) + " " + + UnicodeUtils.escapeWithSpaces(icn.innerName) + " 0x" + Integer.toHexString(icn.access) + + "\n"; } } s += ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(classNode.name) + " "; @@ -165,7 +167,9 @@ public class Disassembler { if (!interfaceStr.isEmpty()) s += "implements " + interfaceStr + " "; } - s += "{\n// #SourceFile: " + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile)) + "\n\n// #Fields\n"; + s += "{\n// #SourceFile: " + + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile)) + + "\n\n// #Fields\n"; for (FieldNode fn : classNode.fields) { if (fn.signature != null) s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n"; @@ -231,8 +235,8 @@ public class Disassembler { if (fn.equals(nodeToFind)) { lineFound = s.split("\\n").length; } - s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escapeWithSpaces(fn.desc) + " " - + UnicodeUtils.escapeWithSpaces(fn.name); + s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + + UnicodeUtils.escapeWithSpaces(fn.desc) + " " + UnicodeUtils.escapeWithSpaces(fn.name); if (fn.value != null) { s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true); } @@ -327,16 +331,19 @@ public class Disassembler { s += dis[0]; s += "\t}\n\n"; } catch (Exception e) { - s += "\t\t// Method couldn't be disassembled:\n\t\t// " + e.getClass().getName() + ": " + e.getMessage() + "\n" - + Arrays.toString(e.getStackTrace()).replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "") + s += "\t\t// Method couldn't be disassembled:\n\t\t// " + + e.getClass().getName() + ": " + e.getMessage() + "\n" + Arrays.toString(e.getStackTrace()) + .replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "") + "\n\t}\n\n"; } } s += "}\n"; return new DisassembleTuple(s, lineFound); } catch (Throwable e) { - return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": " + e.getMessage() + "\n" - + Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "") + "\n"); + return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": " + + e.getMessage() + "\n" + + Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "") + + "\n"); } } @@ -352,15 +359,17 @@ public class Disassembler { } if (mn.localVariables != null) { for (LocalVariableNode lvn : mn.localVariables) { - localVarTable += "\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": " + UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" - + lvn.index + " s:" + labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:" + localVarTable += "\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": " + + UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" + lvn.index + " s:" + + labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:" + UnicodeUtils.escapeWithSpaces(lvn.signature) + "\n"; } } if (mn.tryCatchBlocks != null) { for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) { - tryCatchTable += "\t// " + UnicodeUtils.escapeWithSpaces(tcbn.type) + " s:" + labels.get(tcbn.start.getLabel()) + " e:" - + labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n"; + tryCatchTable += "\t// " + UnicodeUtils.escapeWithSpaces(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()) { @@ -371,208 +380,242 @@ public class Disassembler { public static String disassembleInstruction(AbstractInsnNode n, HashMap labels) { switch (n.getClass().getSimpleName()) { - case "FieldInsnNode": { - FieldInsnNode node = (FieldInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + " " - + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; + case "FieldInsnNode": { + FieldInsnNode node = (FieldInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; + } + case "LabelNode": { + LabelNode node = (LabelNode) n; + return "\t\t// label " + labels.get(node.getLabel()) + "\n"; + } + case "FrameNode": { + FrameNode node = (FrameNode) n; + String type = ""; + switch (node.type) { + case Opcodes.F_NEW: + type = "NEW"; + break; + case Opcodes.F_FULL: + type = "FULL"; + break; + case Opcodes.F_APPEND: + type = "APPEND"; + break; + case Opcodes.F_CHOP: + type = "CHOP"; + break; + case Opcodes.F_SAME: + type = "SAME"; + break; + case Opcodes.F_SAME1: + type = "SAME1"; + break; } - case "LabelNode": { - LabelNode node = (LabelNode) n; - return "\t\t// label " + labels.get(node.getLabel()) + "\n"; - } - case "FrameNode": { - FrameNode node = (FrameNode) n; - String s = "\t\t// frame " + node.type + " l:"; - ArrayList arr = new ArrayList<>(); - if (node.local != null) { - for (Object o : node.local) { - if (o == null) { - arr.add(null); - } else { - if (o instanceof String) { - arr.add(UnicodeUtils.escapeWithSpaces((String) o)); - } else if (o instanceof LabelNode) { - arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); - } else { - arr.add("(" + o.getClass().getName().replace(".", "/") + ") " + o); - } - } - } - s += arr.toString(); - } else { - s += "null"; - } - arr.clear(); - s += " s:"; - if (node.stack != null) { - for (Object o : node.stack) { - if (o == null) { - arr.add(null); - } else { - if (o instanceof String) { - arr.add(UnicodeUtils.escapeWithSpaces((String) o)); - } else if (o instanceof LabelNode) { - arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); - } else { - arr.add("(" + o.getClass().getName().replace(".", "/") + ") " + o); - } - } - } - s += arr.toString(); - } else { - s += "null"; - } - s += "\n"; - return s; - } - case "LineNumberNode": { - LineNumberNode node = (LineNumberNode) n; - return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n"; - } - case "InvokeDynamicInsnNode": { - InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n; - String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " - + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: " - + UnicodeUtils.escapeWithSpaces(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: " - + UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) - + "\n\t\t\t\tdesc: " + UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + node.bsm.isInterface() - + "\n\t\t\t\ttag: " + node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n"; - for (Object l : node.bsmArgs) { - if (l.getClass().getName().equals("org.objectweb.asm.Type")) { - Type type = (Type) l; - int valueBegin = 0; - int valueEnd = 0; - String buf = null; - try { - Field f_off = Type.class.getDeclaredField("valueBegin"); - f_off.setAccessible(true); - valueBegin = f_off.getInt(type); - Field f_len = Type.class.getDeclaredField("valueEnd"); - f_len.setAccessible(true); - valueEnd = f_len.getInt(type); - Field f_buf = Type.class.getDeclaredField("valueBuffer"); - f_buf.setAccessible(true); - buf = (String) f_buf.get(type); - } catch (Exception e) {} - s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type) + "\n\t\t\t\t\tstart: " + valueBegin - + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, ""); - s += "\n\t\t\t\t]\n"; - } else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) { - Handle h = (Handle) l; - s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") - + "\n\t\t\t\t\towner: " + UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: " - + UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: " - + h.getTag(); - s += "\n\t\t\t\t]\n"; + String s = "\t\t// frame " + type + " l:"; + ArrayList arr = new ArrayList<>(); + if (node.local != null) { + for (Object o : node.local) { + if (o == null) { + arr.add(null); } else { - s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n"; + if (o instanceof String) { + arr.add(UnicodeUtils.escapeWithSpaces((String) o)); + } else if (o instanceof LabelNode) { + arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); + } else { + arr.add("(" + o.getClass().getName().replace(".", "/") + ") " + o); + } } } - s += "\t\t\t]\n\t\t]\n"; - return s; + s += arr.toString(); + } else { + s += "null"; } - case "MethodInsnNode": { - MethodInsnNode node = (MethodInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + " " - + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; - } - case "TypeInsnNode": { - TypeInsnNode node = (TypeInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + "\n"; - } - case "MultiANewArrayInsnNode": { - MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims - + "\n"; - } - case "LdcInsnNode": { - LdcInsnNode node = (LdcInsnNode) n; - switch (node.cst.getClass().getSimpleName()) { - case "String": - case "Double": - case "Integer": - case "Float": - case "Long": { - return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + ClassUtil.getDecompiledValue(node.cst, "") + "\n"; - } - case "Type": { - Type type = (Type) node.cst; - int valueBegin = 0; - int valueEnd = 0; - String buf = null; - try { - Field f_off = Type.class.getDeclaredField("valueBegin"); - f_off.setAccessible(true); - valueBegin = f_off.getInt(type); - Field f_len = Type.class.getDeclaredField("valueEnd"); - f_len.setAccessible(true); - valueEnd = f_len.getInt(type); - Field f_buf = Type.class.getDeclaredField("valueBuffer"); - f_buf.setAccessible(true); - buf = (String) f_buf.get(type); - } catch (Exception e) {} - String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: " - + ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: " + valueEnd + "\n\t\t\tbuf: " - + ClassUtil.getDecompiledValue(buf, ""); - s += "\n\t\t]\n"; - return s; - } - default: { - return "\t\tUNRESOLVED TYPE! " + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " - + node.cst.getClass().getName().replace(".", "/") + " " + node.cst + "\n"; + arr.clear(); + s += " s:"; + if (node.stack != null) { + for (Object o : node.stack) { + if (o == null) { + arr.add(null); + } else { + if (o instanceof String) { + arr.add(UnicodeUtils.escapeWithSpaces((String) o)); + } else if (o instanceof LabelNode) { + arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); + } else { + arr.add("(" + o.getClass().getName().replace(".", "/") + ") " + o); + } } } + s += arr.toString(); + } else { + s += "null"; } - case "VarInsnNode": { - VarInsnNode node = (VarInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n"; - } - case "InsnNode": { - InsnNode node = (InsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n"; - } - case "IntInsnNode": { - IntInsnNode node = (IntInsnNode) n; - if (n.getOpcode() == Opcodes.NEWARRAY) { - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + ClassUtil.getArrayTypeByID(node.operand) + "\n"; + s += "\n"; + return s; + } + case "LineNumberNode": { + LineNumberNode node = (LineNumberNode) n; + return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n"; + } + case "InvokeDynamicInsnNode": { + InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n; + String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " + + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: " + + UnicodeUtils.escapeWithSpaces(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: " + + UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: " + + UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: " + + UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + + node.bsm.isInterface() + "\n\t\t\t\ttag: " + node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n"; + for (Object l : node.bsmArgs) { + if (l.getClass().getName().equals("org.objectweb.asm.Type")) { + Type type = (Type) l; + int valueBegin = 0; + int valueEnd = 0; + String buf = null; + try { + Field f_off = Type.class.getDeclaredField("valueBegin"); + f_off.setAccessible(true); + valueBegin = f_off.getInt(type); + Field f_len = Type.class.getDeclaredField("valueEnd"); + f_len.setAccessible(true); + valueEnd = f_len.getInt(type); + Field f_buf = Type.class.getDeclaredField("valueBuffer"); + f_buf.setAccessible(true); + buf = (String) f_buf.get(type); + } catch (Exception e) { + } + s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type) + + "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: " + + ClassUtil.getDecompiledValue(buf, ""); + s += "\n\t\t\t\t]\n"; + } else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) { + Handle h = (Handle) l; + s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + + UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: " + + UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: " + + UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface() + + "\n\t\t\t\t\ttag: " + h.getTag(); + s += "\n\t\t\t\t]\n"; } else { - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n"; + s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n"; } } - case "JumpInsnNode": { - JumpInsnNode node = (JumpInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel()) + "\n"; + s += "\t\t\t]\n\t\t]\n"; + return s; + } + case "MethodInsnNode": { + MethodInsnNode node = (MethodInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/" + + UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n"; + } + case "TypeInsnNode": { + TypeInsnNode node = (TypeInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + UnicodeUtils.escapeWithSpaces(node.desc) + "\n"; + } + case "MultiANewArrayInsnNode": { + MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims + "\n"; + } + case "LdcInsnNode": { + LdcInsnNode node = (LdcInsnNode) n; + switch (node.cst.getClass().getSimpleName()) { + case "String": + case "Double": + case "Integer": + case "Float": + case "Long": { + return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + ClassUtil.getDecompiledValue(node.cst, "") + "\n"; } - case "TableSwitchInsnNode": { - TableSwitchInsnNode node = (TableSwitchInsnNode) n; - String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min + "\n\t\t\tmax: " + node.max - + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) + "\n\t\t\tlabels: [\n"; - for (LabelNode l : node.labels) { - s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n"; + case "Type": { + Type type = (Type) node.cst; + int valueBegin = 0; + int valueEnd = 0; + String buf = null; + try { + Field f_off = Type.class.getDeclaredField("valueBegin"); + f_off.setAccessible(true); + valueBegin = f_off.getInt(type); + Field f_len = Type.class.getDeclaredField("valueEnd"); + f_len.setAccessible(true); + valueEnd = f_len.getInt(type); + Field f_buf = Type.class.getDeclaredField("valueBuffer"); + f_buf.setAccessible(true); + buf = (String) f_buf.get(type); + } catch (Exception e) { } - s += "\t\t\t]\n\t\t]\n"; + String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: " + + ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: " + + valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, ""); + s += "\n\t\t]\n"; return s; } - case "LookupSwitchInsnNode": { - LookupSwitchInsnNode node = (LookupSwitchInsnNode) n; - String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) - + "\n\t\t\tkeys: [\n"; - for (Integer l : node.keys) { - s += "\t\t\t\t" + l + "\n"; - } - s += "\t\t\t]" + "\n\t\t\tlabels: [\n"; - for (LabelNode l : node.labels) { - s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n"; - } - s += "\t\t\t]\n\t\t]\n"; - return s; + default: { + return "\t\tUNRESOLVED TYPE! " + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + + node.cst.getClass().getName().replace(".", "/") + " " + node.cst + "\n"; } - case "IincInsnNode": { - IincInsnNode node = (IincInsnNode) n; - return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n"; } - default: - return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + n.getClass().getSimpleName() + "\n"; + } + case "VarInsnNode": { + VarInsnNode node = (VarInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n"; + } + case "InsnNode": { + InsnNode node = (InsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n"; + } + case "IntInsnNode": { + IntInsnNode node = (IntInsnNode) n; + if (n.getOpcode() == Opcodes.NEWARRAY) { + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + + ClassUtil.getArrayTypeByID(node.operand) + "\n"; + } else { + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n"; + } + } + case "JumpInsnNode": { + JumpInsnNode node = (JumpInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel()) + + "\n"; + } + case "TableSwitchInsnNode": { + TableSwitchInsnNode node = (TableSwitchInsnNode) n; + String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min + + "\n\t\t\tmax: " + node.max + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) + + "\n\t\t\tlabels: [\n"; + for (LabelNode l : node.labels) { + s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n"; + } + s += "\t\t\t]\n\t\t]\n"; + return s; + } + case "LookupSwitchInsnNode": { + LookupSwitchInsnNode node = (LookupSwitchInsnNode) n; + String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: " + + labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n"; + for (Integer l : node.keys) { + s += "\t\t\t\t" + l + "\n"; + } + s += "\t\t\t]" + "\n\t\t\tlabels: [\n"; + for (LabelNode l : node.labels) { + s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n"; + } + s += "\t\t\t]\n\t\t]\n"; + return s; + } + case "IincInsnNode": { + IincInsnNode node = (IincInsnNode) n; + return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n"; + } + default: + return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + + n.getClass().getSimpleName() + "\n"; } } diff --git a/src/me/ByteEdit/main/Main.java b/src/me/ByteEdit/main/Main.java index 35dd6b9..0ffc9db 100644 --- a/src/me/ByteEdit/main/Main.java +++ b/src/me/ByteEdit/main/Main.java @@ -178,6 +178,8 @@ public class Main extends JFrame { provider.addCompletion(new ShorthandCompletion(provider, "method", "// #Max: l:0 s:0\n\t// #TryCatch:\n\t// #LocalVars:\n\tpublic static method ()V {\n\t\treturn\n\t}", null, "method
Creates an example method")); + provider.addCompletion(new ShorthandCompletion(provider, "frame", "frame FULL l:[] s:[]", null, + "frame
Creates a stack map frame")); return provider; } diff --git a/src/org/fife/ui/autocomplete/CompletionProviderBase.java b/src/org/fife/ui/autocomplete/CompletionProviderBase.java index 5e2a7be..d29eb4e 100644 --- a/src/org/fife/ui/autocomplete/CompletionProviderBase.java +++ b/src/org/fife/ui/autocomplete/CompletionProviderBase.java @@ -26,7 +26,7 @@ import javax.swing.text.Segment; * @see AbstractCompletionProvider */ public abstract class CompletionProviderBase implements CompletionProvider { - + /** * The parent completion provider. */ @@ -66,11 +66,11 @@ public abstract class CompletionProviderBase implements CompletionProvider { private Segment s = new Segment(); protected static final String EMPTY_STRING = ""; /** - * Comparator used to sort completions by their relevance before sorting - * them lexicographically. + * Comparator used to sort completions by their relevance before sorting them + * lexicographically. */ private static final Comparator sortByRelevanceComparator = new SortByRelevanceComparator(); - + /** * {@inheritDoc} */ @@ -79,7 +79,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { paramListEnd = paramListStart = 0; paramListSeparator = null; } - + /** * {@inheritDoc} */ @@ -112,17 +112,15 @@ public abstract class CompletionProviderBase implements CompletionProvider { } return completions; } - + /** * Does the dirty work of creating a list of completions. * - * @param comp - * The text component to look in. - * @return The list of possible completions, or an empty list if there - * are none. + * @param comp The text component to look in. + * @return The list of possible completions, or an empty list if there are none. */ protected abstract List getCompletionsImpl(JTextComponent comp); - + /** * {@inheritDoc} */ @@ -130,7 +128,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public ListCellRenderer getListCellRenderer() { return listCellRenderer; } - + /** * {@inheritDoc} */ @@ -138,7 +136,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public ParameterChoicesProvider getParameterChoicesProvider() { return paramChoicesProvider; } - + /** * {@inheritDoc} */ @@ -146,7 +144,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public char getParameterListEnd() { return paramListEnd; } - + /** * {@inheritDoc} */ @@ -154,7 +152,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public String getParameterListSeparator() { return paramListSeparator; } - + /** * {@inheritDoc} */ @@ -162,7 +160,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public char getParameterListStart() { return paramListStart; } - + /** * {@inheritDoc} */ @@ -170,7 +168,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public CompletionProvider getParent() { return parent; } - + /** * {@inheritDoc} */ @@ -186,38 +184,33 @@ public abstract class CompletionProviderBase implements CompletionProvider { } return (autoActivateAfterLetters && Character.isLetter(ch)) || (autoActivateChars != null && autoActivateChars.indexOf(ch) > -1); } - + /** * Sets the characters that auto-activation should occur after. A Java - * completion provider, for example, might want to set others - * to ".", to allow auto-activation for members of an object. + * completion provider, for example, might want to set others to + * ".", to allow auto-activation for members of an object. * - * @param letters - * Whether auto-activation should occur after any letter. - * @param others - * A string of (non-letter) chars that auto-activation should - * occur after. This may be null. + * @param letters Whether auto-activation should occur after any letter. + * @param others A string of (non-letter) chars that auto-activation should + * occur after. This may be null. */ public void setAutoActivationRules(boolean letters, String others) { autoActivateAfterLetters = letters; autoActivateChars = others; } - + /** - * Sets the param choices provider. This is used when a user - * code-completes a parameterized completion, such as a function or method. - * For any parameter to the function/method, this object can return - * possible completions. + * Sets the param choices provider. This is used when a user code-completes a + * parameterized completion, such as a function or method. For any parameter to + * the function/method, this object can return possible completions. * - * @param pcp - * The parameter choices provider, or null for - * none. + * @param pcp The parameter choices provider, or null for none. * @see #getParameterChoicesProvider() */ public void setParameterChoicesProvider(ParameterChoicesProvider pcp) { paramChoicesProvider = pcp; } - + /** * {@inheritDoc} */ @@ -225,7 +218,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { public void setListCellRenderer(ListCellRenderer r) { listCellRenderer = r; } - + /** * {@inheritDoc} */ @@ -244,7 +237,7 @@ public abstract class CompletionProviderBase implements CompletionProvider { paramListSeparator = separator; paramListEnd = listEnd; } - + /** * {@inheritDoc} */