Merge pull request #403 from GraxCode/bytecode

Various bytecode disassembler fixes / additions.
This commit is contained in:
Konloch 2022-03-19 15:25:34 -07:00 committed by GitHub
commit b5664b2949
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 332 additions and 326 deletions

View file

@ -1,37 +1,19 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode; package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import eu.bibl.banalysis.asm.desc.OpcodeInfo; 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.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.*;
import java.util.Collections; import java.util.stream.Collectors;
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;
/*************************************************************************** /***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -54,340 +36,361 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/** /**
* @author Konloch * @author Konloch
* @author Bibl * @author Bibl
* @author GraxCode
*/ */
public class InstructionPrinter { public class InstructionPrinter implements Opcodes {
/** /**
* The MethodNode to print * The MethodNode to print
**/ **/
private final MethodNode mNode; private final MethodNode mNode;
private final TypeAndName[] args; private final TypeAndName[] args;
protected int[] pattern; protected int[] pattern;
protected boolean match; protected boolean match;
protected List<AbstractInsnNode> matchedInsns; protected List<AbstractInsnNode> matchedInsns;
protected Map<LabelNode, Integer> labels; protected Map<LabelNode, Integer> labels;
private boolean firstLabel = false; private boolean firstLabel = false;
private final List<String> info = new ArrayList<>(); private final List<String> info = new ArrayList<>();
public InstructionPrinter(MethodNode m, TypeAndName[] args) { public InstructionPrinter(MethodNode m, TypeAndName[] args) {
this.args = args; this.args = args;
mNode = m; mNode = m;
labels = new HashMap<>(); labels = new HashMap<>();
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because precalculateLabelIndexes(m);
// match = false // matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because
match = false; // 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<String> 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<TryCatchBlockNode> 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, return line;
TypeAndName[] args) { }
this.args = args;
mNode = m; protected String printVarInsnNode(VarInsnNode vin) {
labels = new HashMap<>(); StringBuilder sb = new StringBuilder();
InstructionSearcher searcher = new InstructionSearcher(m.instructions, pattern); sb.append(nameOpcode(vin.getOpcode()));
match = searcher.search(); sb.append(" ");
if (match) { sb.append(vin.var);
for (AbstractInsnNode[] ains : searcher.getMatches()) { if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
Collections.addAll(matchedInsns, ains); 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);
} }
}
} }
/** return sb.toString();
* Creates the print }
*
* @return The print as an ArrayList
*/
public List<String> 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); protected String printIntInsnNode(IntInsnNode iin) {
} return nameOpcode(iin.getOpcode()) + " " + iin.operand;
} }
if (firstLabel
&& BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) protected String printFieldInsnNode(FieldInsnNode fin) {
info.add("}"); String desc = Type.getType(fin.desc).getClassName();
return info; 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) if (desc == null || desc.equals("null")) desc = min.desc;
{
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("}");
line = printLabelnode((LabelNode) ain); sb.append(desc);
if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) { return sb.toString();
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 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) { line.append(" default" + " -> L").append(resolveLabel(lin.dflt));
StringBuilder sb = new StringBuilder(); return line.toString();
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);
}
}
}
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 sb.toString();
return nameOpcode(iin.getOpcode()) + " " + iin.operand; }
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) { sb.append("(Stack");
String desc = Type.getType(fin.desc).getClassName(); if (frame.stack != null && !frame.stack.isEmpty()) {
if (desc.equals("null")) sb.append("[").append(frame.stack.size()).append("]: ");
desc = fin.desc; sb.append(frame.stack.stream().map(this::printFrameObject).collect(Collectors.joining(", ")));
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name } else {
+ ":" + desc; sb.append("[0]");
} }
sb.append(") ");
protected String printMethodInsnNode(MethodInsnNode min) { return sb.toString();
StringBuilder sb = new StringBuilder(); }
sb.append(nameOpcode(min.getOpcode())).append(" ").append(min.owner).append(".").append(min.name);
String desc = min.desc; private String printFrameObject(Object obj) {
try { if (obj instanceof LabelNode) return "label [L" + resolveLabel((LabelNode) obj) + "]";
if (Type.getType(min.desc) != null) if (obj instanceof Integer) {
desc = Type.getType(min.desc).getClassName(); switch ((int) obj) {
} catch (java.lang.AssertionError e) { case 0:
//e.printStackTrace(); return "top";
} catch (java.lang.Exception e) { case 1:
e.printStackTrace(); return "int";
} case 2:
return "float";
if (desc == null || desc.equals("null")) case 3:
desc = min.desc; return "double";
case 4:
sb.append(desc); return "long";
case 5:
return sb.toString(); 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) { private String nameFrameType(int type) {
if (ldc.cst instanceof String) switch (type) {
return nameOpcode(ldc.getOpcode()) + " \"" case F_NEW:
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" return " f_new";
+ ldc.cst.getClass().getCanonicalName() + ")"; case F_FULL:
return " f_full";
return nameOpcode(ldc.getOpcode()) + " " case F_APPEND:
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" return " f_append";
+ ldc.cst.getClass().getCanonicalName() + ")"; 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) { protected String nameOpcode(int opcode) {
return nameOpcode(in.getOpcode()); return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();
} }
protected String printJumpInsnNode(JumpInsnNode jin) { protected int resolveLabel(LabelNode label) {
return nameOpcode(jin.getOpcode()) + " L" if (labels.containsKey(label)) {
+ resolveLabel(jin.label); return labels.get(label);
} } else {
/*int newLabelIndex = labels.size() + 1;
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;
labels.put(label, newLabelIndex); 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) { public static void saveTo(File file, InstructionPrinter printer) {
try (FileWriter fw = new FileWriter(file); try (FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw)) {
BufferedWriter bw = new BufferedWriter(fw)) { for (String s : printer.createPrint()) {
for (String s : printer.createPrint()) { bw.write(s);
bw.write(s); bw.newLine();
bw.newLine(); }
} } catch (IOException e) {
} catch (IOException e) { BytecodeViewer.handleException(e);
BytecodeViewer.handleException(e);
}
} }
}
} }

View file

@ -57,6 +57,9 @@ public class MethodNodeDecompiler {
if (m.name.equals("<init>")) { if (m.name.equals("<init>")) {
sb.append(class_); sb.append(class_);
} else if (!m.name.equals("<clinit>")) { } else if (!m.name.equals("<clinit>")) {
Type returnType = Type.getReturnType(m.desc);
sb.append(returnType.getClassName());
sb.append(" ");
sb.append(m.name); sb.append(m.name);
} }