diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java index 7fbc44b8..04c16c3c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java @@ -1,37 +1,19 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode; import eu.bibl.banalysis.asm.desc.OpcodeInfo; +import org.apache.commons.text.StringEscapeUtils; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.commons.text.StringEscapeUtils; -import org.objectweb.asm.Type; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.FrameNode; -import org.objectweb.asm.tree.IincInsnNode; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.IntInsnNode; -import org.objectweb.asm.tree.InvokeDynamicInsnNode; -import org.objectweb.asm.tree.JumpInsnNode; -import org.objectweb.asm.tree.LabelNode; -import org.objectweb.asm.tree.LdcInsnNode; -import org.objectweb.asm.tree.LineNumberNode; -import org.objectweb.asm.tree.LookupSwitchInsnNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.MultiANewArrayInsnNode; -import org.objectweb.asm.tree.TableSwitchInsnNode; -import org.objectweb.asm.tree.TypeInsnNode; -import org.objectweb.asm.tree.VarInsnNode; -import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import java.util.*; +import java.util.stream.Collectors; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -54,340 +36,361 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer; /** * @author Konloch * @author Bibl + * @author GraxCode */ -public class InstructionPrinter { +public class InstructionPrinter implements Opcodes { - /** - * The MethodNode to print - **/ - private final MethodNode mNode; - private final TypeAndName[] args; + /** + * The MethodNode to print + **/ + private final MethodNode mNode; + private final TypeAndName[] args; - protected int[] pattern; - protected boolean match; + protected int[] pattern; + protected boolean match; - protected List matchedInsns; - protected Map labels; - private boolean firstLabel = false; - private final List info = new ArrayList<>(); + protected List matchedInsns; + protected Map labels; + private boolean firstLabel = false; + private final List info = new ArrayList<>(); - public InstructionPrinter(MethodNode m, TypeAndName[] args) { - this.args = args; - mNode = m; - labels = new HashMap<>(); - // matchedInsns = new ArrayList(); // ingnored because - // match = false - match = false; + public InstructionPrinter(MethodNode m, TypeAndName[] args) { + this.args = args; + mNode = m; + labels = new HashMap<>(); + precalculateLabelIndexes(m); + // matchedInsns = new ArrayList(); // ingnored because + // match = false + match = false; + } + + public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args) { + this(m, args); + InstructionSearcher searcher = new InstructionSearcher(m.instructions, pattern); + match = searcher.search(); + if (match) { + for (AbstractInsnNode[] ains : searcher.getMatches()) { + Collections.addAll(matchedInsns, ains); + } + } + } + + private void precalculateLabelIndexes(MethodNode m) { + int lIdx = 0; + for (AbstractInsnNode ain : m.instructions) { + if (ain.getType() == AbstractInsnNode.LABEL) { + labels.put((LabelNode) ain, lIdx++); + } + } + } + + /** + * Creates the print + * + * @return The print as an ArrayList + */ + public List createPrint() { + firstLabel = false; + info.clear(); + for (AbstractInsnNode ain : mNode.instructions) { + String line = printInstruction(ain); + if (!line.isEmpty()) { + if (match) if (matchedInsns.contains(ain)) line = " -> " + line; + + info.add(line); + } + } + if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) info.add("}"); + return info; + } + + public String printInstruction(AbstractInsnNode ain) { + String line = ""; + if (ain instanceof VarInsnNode) { + line = printVarInsnNode((VarInsnNode) ain); + } else if (ain instanceof IntInsnNode) { + line = printIntInsnNode((IntInsnNode) ain); + } else if (ain instanceof FieldInsnNode) { + line = printFieldInsnNode((FieldInsnNode) ain); + } else if (ain instanceof MethodInsnNode) { + line = printMethodInsnNode((MethodInsnNode) ain); + } else if (ain instanceof LdcInsnNode) { + line = printLdcInsnNode((LdcInsnNode) ain); + } else if (ain instanceof InsnNode) { + line = printInsnNode((InsnNode) ain); + } else if (ain instanceof JumpInsnNode) { + line = printJumpInsnNode((JumpInsnNode) ain); + } else if (ain instanceof LineNumberNode) { + line = printLineNumberNode((LineNumberNode) ain); + } else if (ain instanceof LabelNode) { + if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) info.add("}"); + + LabelNode label = (LabelNode) ain; + if (mNode.tryCatchBlocks != null) { + List tcbs = mNode.tryCatchBlocks; + String starting = tcbs.stream().filter(tcb -> tcb.start == label).map(tcb -> "start TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", ")); + String ending = tcbs.stream().filter(tcb -> tcb.end == label).map(tcb -> "end TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", ")); + String handlers = tcbs.stream().filter(tcb -> tcb.handler == label).map(tcb -> "handler TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", ")); + if (!ending.isEmpty()) info.add("// " + ending); + if (!starting.isEmpty()) info.add("// " + starting); + if (!handlers.isEmpty()) info.add("// " + starting); + } + line = printLabelNode((LabelNode) ain); + + if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) { + if (!firstLabel) firstLabel = true; + line += " {"; + } + } else if (ain instanceof TypeInsnNode) { + line = printTypeInsnNode((TypeInsnNode) ain); + } else if (ain instanceof FrameNode) { + line = printFrameNode((FrameNode) ain); + } else if (ain instanceof IincInsnNode) { + line = printIincInsnNode((IincInsnNode) ain); + } else if (ain instanceof TableSwitchInsnNode) { + line = printTableSwitchInsnNode((TableSwitchInsnNode) ain); + } else if (ain instanceof LookupSwitchInsnNode) { + line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain); + } else if (ain instanceof InvokeDynamicInsnNode) { + line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain); + } else if (ain instanceof MultiANewArrayInsnNode) { + line = printMultiANewArrayInsNode((MultiANewArrayInsnNode) ain); + } else { + line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain; } - public InstructionPrinter(MethodNode m, InstructionPattern pattern, - TypeAndName[] args) { - this.args = args; - mNode = m; - labels = new HashMap<>(); - InstructionSearcher searcher = new InstructionSearcher(m.instructions, pattern); - match = searcher.search(); - if (match) { - for (AbstractInsnNode[] ains : searcher.getMatches()) { - Collections.addAll(matchedInsns, ains); - } + return line; + } + + protected String printVarInsnNode(VarInsnNode vin) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(vin.getOpcode())); + sb.append(" "); + sb.append(vin.var); + if (BytecodeViewer.viewer.debugHelpers.isSelected()) { + if (vin.var == 0 && !Modifier.isStatic(mNode.access)) { + sb.append(" // reference to self"); + } else { + final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1); + if (refIndex >= 0 && refIndex < args.length - 1) { + sb.append(" // reference to ").append(args[refIndex].name); } + } } - /** - * Creates the print - * - * @return The print as an ArrayList - */ - public List createPrint() { - firstLabel = false; - info.clear(); - for (AbstractInsnNode ain : mNode.instructions) { - String line = printInstruction(ain); - if (!line.isEmpty()) { - if (match) - if (matchedInsns.contains(ain)) - line = " -> " + line; + return sb.toString(); + } - info.add(line); - } - } - if (firstLabel - && BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) - info.add("}"); - return info; + protected String printIntInsnNode(IntInsnNode iin) { + return nameOpcode(iin.getOpcode()) + " " + iin.operand; + } + + protected String printFieldInsnNode(FieldInsnNode fin) { + String desc = Type.getType(fin.desc).getClassName(); + if (desc.equals("null")) desc = fin.desc; + return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name + ":" + desc; + } + + protected String printMethodInsnNode(MethodInsnNode min) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(min.getOpcode())).append(" ").append(min.owner).append(".").append(min.name); + + String desc = min.desc; + try { + if (Type.getType(min.desc) != null) desc = Type.getType(min.desc).getClassName(); + } catch (java.lang.AssertionError e) { + //e.printStackTrace(); + } catch (java.lang.Exception e) { + e.printStackTrace(); } - public String printInstruction(AbstractInsnNode ain) - { - String line = ""; - if (ain instanceof VarInsnNode) { - line = printVarInsnNode((VarInsnNode) ain); - } else if (ain instanceof IntInsnNode) { - line = printIntInsnNode((IntInsnNode) ain); - } else if (ain instanceof FieldInsnNode) { - line = printFieldInsnNode((FieldInsnNode) ain); - } else if (ain instanceof MethodInsnNode) { - line = printMethodInsnNode((MethodInsnNode) ain); - } else if (ain instanceof LdcInsnNode) { - line = printLdcInsnNode((LdcInsnNode) ain); - } else if (ain instanceof InsnNode) { - line = printInsnNode((InsnNode) ain); - } else if (ain instanceof JumpInsnNode) { - line = printJumpInsnNode((JumpInsnNode) ain); - } else if (ain instanceof LineNumberNode) { - line = printLineNumberNode((LineNumberNode) ain); - } else if (ain instanceof LabelNode) { - if (firstLabel - && BytecodeViewer.viewer.appendBracketsToLabels - .isSelected()) - info.add("}"); + if (desc == null || desc.equals("null")) desc = min.desc; - line = printLabelnode((LabelNode) ain); + sb.append(desc); - if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) { - if (!firstLabel) - firstLabel = true; - line += " {"; - } - } else if (ain instanceof TypeInsnNode) { - line = printTypeInsnNode((TypeInsnNode) ain); - } else if (ain instanceof FrameNode) { - line = printFrameNode((FrameNode) ain); - } else if (ain instanceof IincInsnNode) { - line = printIincInsnNode((IincInsnNode) ain); - } else if (ain instanceof TableSwitchInsnNode) { - line = printTableSwitchInsnNode((TableSwitchInsnNode) ain); - } else if (ain instanceof LookupSwitchInsnNode) { - line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain); - } else if (ain instanceof InvokeDynamicInsnNode) { - line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain); - } else if (ain instanceof MultiANewArrayInsnNode) { - line = printMultiANewArrayInsNode((MultiANewArrayInsnNode) ain); - } else { - line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " - + ain; - } + return sb.toString(); + } - return line; + protected String printLdcInsnNode(LdcInsnNode ldc) { + if (ldc.cst instanceof String) + return nameOpcode(ldc.getOpcode()) + " \"" + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" + ldc.cst.getClass().getCanonicalName() + ")"; + + return nameOpcode(ldc.getOpcode()) + " " + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" + ldc.cst.getClass().getCanonicalName() + ")"; + } + + protected String printInsnNode(InsnNode in) { + return nameOpcode(in.getOpcode()); + } + + protected String printJumpInsnNode(JumpInsnNode jin) { + return nameOpcode(jin.getOpcode()) + " L" + resolveLabel(jin.label); + } + + protected String printLineNumberNode(LineNumberNode lnn) { + return "// line " + lnn.line; + } + + protected String printLabelNode(LabelNode label) { + return "L" + resolveLabel(label); + } + + protected String printTypeInsnNode(TypeInsnNode tin) { + try { + String desc = tin.desc; + try { + if (Type.getType(tin.desc) != null) desc = Type.getType(tin.desc).getClassName(); + + if (desc.equals("null")) desc = tin.desc; + } catch (java.lang.ArrayIndexOutOfBoundsException ignored) { + + } + return nameOpcode(tin.getOpcode()) + " " + desc; + } catch (Exception e) { + return nameOpcode(tin.getOpcode()) + " " + tin.desc; + } + } + + protected String printIincInsnNode(IincInsnNode iin) { + return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr; + } + + protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) { + StringBuilder line = new StringBuilder(nameOpcode(tin.getOpcode()) + " \n"); + List labels = tin.labels; + int count = 0; + for (int i = tin.min; i < tin.max + 1; i++) { + line.append(" val: ").append(i).append(" -> ").append("L").append(resolveLabel((LabelNode) labels.get(count++))).append("\n"); + } + line.append(" default" + " -> L").append(resolveLabel(tin.dflt)); + return line.toString(); + } + + protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) { + StringBuilder line = new StringBuilder(nameOpcode(lin.getOpcode()) + ": \n"); + List keys = lin.keys; + List labels = lin.labels; + + for (int i = 0; i < keys.size(); i++) { + int key = (Integer) keys.get(i); + LabelNode label = (LabelNode) labels.get(i); + line.append(" val: ").append(key).append(" -> ").append("L").append(resolveLabel(label)).append("\n"); } - protected String printVarInsnNode(VarInsnNode vin) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(vin.getOpcode())); - sb.append(vin.var); - if (BytecodeViewer.viewer.debugHelpers.isSelected()) { - if (vin.var == 0 && !Modifier.isStatic(mNode.access)) { - sb.append(" // reference to self"); - } else { - final int refIndex = vin.var - - (Modifier.isStatic(mNode.access) ? 0 : 1); - if (refIndex >= 0 && refIndex < args.length - 1) { - sb.append(" // reference to ").append(args[refIndex].name); - } - } - } + line.append(" default" + " -> L").append(resolveLabel(lin.dflt)); + return line.toString(); + } - return sb.toString(); + protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(idin.getOpcode())).append(" ").append(idin.bsm.getOwner()).append('.').append(idin.bsm.getName()).append(idin.bsm.getDesc()).append(" : ").append(idin.name).append(idin.desc); + + if (idin.bsmArgs != null) { + for (Object o : idin.bsmArgs) { + sb.append(" "); + sb.append(o.toString()); + } } - protected String printIntInsnNode(IntInsnNode iin) { - return nameOpcode(iin.getOpcode()) + " " + iin.operand; + return sb.toString(); + } + + protected String printMultiANewArrayInsNode(MultiANewArrayInsnNode mana) { + return nameOpcode(mana.getOpcode()) + " " + mana.dims + " : " + mana.desc; + } + + private String printFrameNode(FrameNode frame) { + StringBuilder sb = new StringBuilder(); + sb.append(nameFrameType(frame.type)).append(" "); + sb.append("(Locals"); + if (frame.local != null && !frame.local.isEmpty()) { + sb.append("[").append(frame.local.size()).append("]: "); + sb.append(frame.local.stream().map(this::printFrameObject).collect(Collectors.joining(", "))); + } else { + sb.append("[0]"); } + sb.append(") "); - protected String printFieldInsnNode(FieldInsnNode fin) { - String desc = Type.getType(fin.desc).getClassName(); - if (desc.equals("null")) - desc = fin.desc; - return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name - + ":" + desc; + sb.append("(Stack"); + if (frame.stack != null && !frame.stack.isEmpty()) { + sb.append("[").append(frame.stack.size()).append("]: "); + sb.append(frame.stack.stream().map(this::printFrameObject).collect(Collectors.joining(", "))); + } else { + sb.append("[0]"); } + sb.append(") "); - protected String printMethodInsnNode(MethodInsnNode min) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(min.getOpcode())).append(" ").append(min.owner).append(".").append(min.name); + return sb.toString(); + } - String desc = min.desc; - try { - if (Type.getType(min.desc) != null) - desc = Type.getType(min.desc).getClassName(); - } catch (java.lang.AssertionError e) { - //e.printStackTrace(); - } catch (java.lang.Exception e) { - e.printStackTrace(); - } - - if (desc == null || desc.equals("null")) - desc = min.desc; - - sb.append(desc); - - return sb.toString(); + private String printFrameObject(Object obj) { + if (obj instanceof LabelNode) return "label [L" + resolveLabel((LabelNode) obj) + "]"; + if (obj instanceof Integer) { + switch ((int) obj) { + case 0: + return "top"; + case 1: + return "int"; + case 2: + return "float"; + case 3: + return "double"; + case 4: + return "long"; + case 5: + return "null"; + case 6: + return "uninitialized this"; + default: + return "unknown"; + } } + if (obj instanceof String) return "reference [" + obj + "]"; + return "unknown [" + obj.toString() + "]"; + } - protected String printLdcInsnNode(LdcInsnNode ldc) { - if (ldc.cst instanceof String) - return nameOpcode(ldc.getOpcode()) + " \"" - + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" - + ldc.cst.getClass().getCanonicalName() + ")"; - - return nameOpcode(ldc.getOpcode()) + " " - + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" - + ldc.cst.getClass().getCanonicalName() + ")"; + private String nameFrameType(int type) { + switch (type) { + case F_NEW: + return " f_new"; + case F_FULL: + return " f_full"; + case F_APPEND: + return " f_append"; + case F_CHOP: + return " f_chop"; + case F_SAME: + return " f_same"; + case F_SAME1: + return " f_same1"; + default: + return " f_unknown" + type; } + } - protected String printInsnNode(InsnNode in) { - return nameOpcode(in.getOpcode()); - } + protected String nameOpcode(int opcode) { + return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase(); + } - protected String printJumpInsnNode(JumpInsnNode jin) { - return nameOpcode(jin.getOpcode()) + " L" - + resolveLabel(jin.label); - } - - protected String printLineNumberNode(LineNumberNode lnn) { - return "// line " + lnn.line; - } - - protected String printLabelnode(LabelNode label) { - return "L" + resolveLabel(label); - } - - protected String printTypeInsnNode(TypeInsnNode tin) { - try { - String desc = tin.desc; - try { - if (Type.getType(tin.desc) != null) - desc = Type.getType(tin.desc).getClassName(); - - if (desc.equals("null")) - desc = tin.desc; - } catch (java.lang.ArrayIndexOutOfBoundsException ignored) { - - } - return nameOpcode(tin.getOpcode()) + " " + desc; - } catch (Exception e) { - return nameOpcode(tin.getOpcode()) + " " + tin.desc; - } - } - - protected String printIincInsnNode(IincInsnNode iin) { - return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr; - } - - protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) { - StringBuilder line = new StringBuilder(nameOpcode(tin.getOpcode()) + " \n"); - List labels = tin.labels; - int count = 0; - for (int i = tin.min; i < tin.max + 1; i++) { - line.append(" val: ").append(i).append(" -> ").append("L") - .append(resolveLabel((LabelNode) labels.get(count++))).append("\n"); - } - line.append(" default" + " -> L").append(resolveLabel(tin.dflt)); - return line.toString(); - } - - protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) { - StringBuilder line = new StringBuilder(nameOpcode(lin.getOpcode()) + ": \n"); - List keys = lin.keys; - List labels = lin.labels; - - for (int i = 0; i < keys.size(); i++) { - int key = (Integer) keys.get(i); - LabelNode label = (LabelNode) labels.get(i); - line.append(" val: ").append(key).append(" -> ").append("L") - .append(resolveLabel(label)).append("\n"); - } - - line.append(" default" + " -> L").append(resolveLabel(lin.dflt)); - return line.toString(); - } - - protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(idin.getOpcode())).append(" ").append(idin.bsm.getOwner()).append('.') - .append(idin.bsm.getName()).append(idin.bsm.getDesc()).append(" : ") - .append(idin.name).append(idin.desc); - - if (idin.bsmArgs != null) { - for (Object o : idin.bsmArgs) { - sb.append(" "); - sb.append(o.toString()); - } - } - - return sb.toString(); - } - - protected String printMultiANewArrayInsNode(MultiANewArrayInsnNode mana) { - return nameOpcode(mana.getOpcode()) + " " + mana.dims + " : " + mana.desc; - } - - private String printFrameNode(FrameNode frame) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(frame.getOpcode())).append(" "); - - sb.append("(Locals"); - if (frame.local != null - && frame.local.size() > 0) { - sb.append("[").append(frame.local.size()).append("]:"); - sb.append(" "); - sb.append(frame.local.get(0).toString()); - if (frame.local.size() > 1) { - for (int i = 1; i < frame.local.size(); i++) { - sb.append(", "); - sb.append(frame.local.get(i).toString()); - } - } - } else { - sb.append("[0]: null"); - } - sb.append(") "); - - sb.append("(Stack"); - if (frame.stack != null - && frame.stack.size() > 0) { - sb.append("[").append(frame.stack.size()).append("]:"); - sb.append(" "); - sb.append(frame.stack.get(0).toString()); - if (frame.stack.size() > 1) { - for (int i = 1; i < frame.stack.size(); i++) { - sb.append(", "); - sb.append(frame.stack.get(i).toString()); - } - } - } else { - sb.append("[0]: null"); - } - sb.append(")"); - - return sb.toString(); - } - - protected String nameOpcode(int opcode) { - return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase(); - } - - protected int resolveLabel(LabelNode label) { - if (labels.containsKey(label)) { - return labels.get(label); - } else { - int newLabelIndex = labels.size() + 1; + protected int resolveLabel(LabelNode label) { + if (labels.containsKey(label)) { + return labels.get(label); + } else { + /*int newLabelIndex = labels.size() + 1; labels.put(label, newLabelIndex); - return newLabelIndex; - } + return newLabelIndex;*/ + throw new IllegalStateException("LabelNode index not found. (Label not in InsnList?)"); } + } - public static void saveTo(File file, InstructionPrinter printer) { - try (FileWriter fw = new FileWriter(file); - BufferedWriter bw = new BufferedWriter(fw)) { - for (String s : printer.createPrint()) { - bw.write(s); - bw.newLine(); - } - } catch (IOException e) { - BytecodeViewer.handleException(e); - } + public static void saveTo(File file, InstructionPrinter printer) { + try (FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw)) { + for (String s : printer.createPrint()) { + bw.write(s); + bw.newLine(); + } + } catch (IOException e) { + BytecodeViewer.handleException(e); } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java index 982943a0..92e0ec4c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java @@ -57,6 +57,9 @@ public class MethodNodeDecompiler { if (m.name.equals("")) { sb.append(class_); } else if (!m.name.equals("")) { + Type returnType = Type.getReturnType(m.desc); + sb.append(returnType.getClassName()); + sb.append(" "); sb.append(m.name); }