This commit is contained in:
SuspiciousActivity committed 2021-03-09 18:24:07 +01:00
1 parent b2267947c8
commit bc0ec73071
20 files changed
+277 -437

No files matched your search

+7 -10
View File
@@ -15,7 +15,6 @@ import java.io.StringWriter;
import java.net.URI; import java.net.URI;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -27,14 +26,14 @@ import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider; import javax.tools.ToolProvider;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane; import org.fife.ui.rtextarea.RTextScrollPane;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import me.ByteEdit.edit.Disassembler; import me.ByteEdit.decompiler.EnumDecompiler;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
import me.ByteEdit.main.ThemeManager; import me.ByteEdit.main.ThemeManager;
@@ -107,9 +106,7 @@ public class CompilationBox extends JFrame {
null, Arrays.asList(new JavaSourceFromString("Compiled", source))).call(); null, Arrays.asList(new JavaSourceFromString("Compiled", source))).call();
String res = out.toString(); String res = out.toString();
if (res.isEmpty()) { if (res.isEmpty()) {
SingleThreadedExecutor.execute(() -> {
SingleThreadedExecutor.execute( () -> {
try { try {
File clazz = new File(tmpFolder, "Compiled.class"); File clazz = new File(tmpFolder, "Compiled.class");
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -121,11 +118,11 @@ public class CompilationBox extends JFrame {
} }
is.close(); is.close();
ClassReader read = new ClassReader(baos.toByteArray()); ClassReader read = new ClassReader(baos.toByteArray());
ClassNode node = new ClassNode(); ClassNode node = new ClassNode();
read.accept(node, 0); read.accept(node, 0);
String dis = Disassembler.disassemble(node); EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT;
String dis = decompiler.getDecompiler().decompile(node);
File[] files = tmpFolder.listFiles(); File[] files = tmpFolder.listFiles();
if (files != null) if (files != null)
for (File f : files) { for (File f : files) {
@@ -140,11 +137,11 @@ public class CompilationBox extends JFrame {
read = new ClassReader(baos.toByteArray()); read = new ClassReader(baos.toByteArray());
node = new ClassNode(); node = new ClassNode();
read.accept(node, 0); read.accept(node, 0);
dis += "\n" + Disassembler.disassemble(node); dis += "\n" + decompiler.getDecompiler().decompile(node);
} }
compSuccess.textArea.setText(dis); compSuccess.textArea.setText(dis);
compSuccess.setVisible(true); compSuccess.setVisible(true);
}catch (IOException e2){ } catch (IOException e2) {
e2.printStackTrace(); e2.printStackTrace();
} }
}); });
+3 -15
View File
@@ -1,7 +1,6 @@
package me.ByteEdit.boxes; package me.ByteEdit.boxes;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -12,11 +11,10 @@ import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionListener;
import javax.swing.text.BadLocationException;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
public class GlobalSearchOpenBox extends JFrame { public class GlobalSearchOpenBox extends JFrame {
@@ -38,23 +36,13 @@ public class GlobalSearchOpenBox extends JFrame {
model = new DefaultListModel<>(); model = new DefaultListModel<>();
JList<Info> list = new JList(model); JList<Info> list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() { list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
SingleThreadedExecutor.execute(() -> {
SingleThreadedExecutor.execute( () -> {
Info val = list.getSelectedValue(); Info val = list.getSelectedValue();
if (val != null && !val.owner.equals(Main.currentNodeName)) { if (val != null && !val.owner.equals(Main.currentNodeName)) {
int lineFound = Main.selectFileWithSearch(val.nodePath, val.mn); Main.selectFile(val.nodePath);
if (lineFound != -1) {
try {
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
} catch (BadLocationException e1) {
//e1.printStackTrace();
}
}
} }
}); });
} }
}); });
+4 -23
View File
@@ -4,7 +4,6 @@ import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -14,7 +13,6 @@ import javax.swing.JPanel;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.FieldInsnNode;
@@ -22,7 +20,7 @@ import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import me.ByteEdit.edit.Disassembler; import me.ByteEdit.decompiler.SingleThreadedExecutor;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.UnicodeUtils; import me.ByteEdit.utils.UnicodeUtils;
@@ -213,30 +211,13 @@ public class RenameBox extends JFrame {
} }
} }
SingleThreadedExecutor.execute( () -> { SingleThreadedExecutor.execute(() -> {
try { // refresh // refresh
ClassNode classNode = Main.classNodes.get(Main.currentNodeName); Main.decompileCurrentNode();
int prev = Main.txtByteEditView.getCaretPosition();
String dis = Disassembler.disassemble(classNode);
String substr = Main.currentNodeName.substring(0, Main.currentNodeName.length() - 6);
for (String key : Main.classNodes.keySet()) {
if (key.contains("$")) {
String[] split = key.split("\\$");
if (split[0].equals(substr)) {
dis += "\n" + Disassembler.disassemble(Main.classNodes.get(key));
}
}
}
Main.txtByteEditView.setText(dis);
Main.txtByteEditView.setCaretPosition(prev);
} catch (Exception e2) {
e2.printStackTrace();
}
name = newName; name = newName;
desc = newDesc; desc = newDesc;
RenameBox.this.setVisible(false); RenameBox.this.setVisible(false);
}); });
} }
}); });
btnRename.setBounds(345, 237, 89, 23); btnRename.setBounds(345, 237, 89, 23);
+1 -2
View File
@@ -3,7 +3,6 @@ package me.ByteEdit.boxes;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -46,7 +45,7 @@ public class TypeOpenBox extends JFrame {
String val = list.getSelectedValue(); String val = list.getSelectedValue();
if (val != null && !val.equals(Main.currentNodeName)) { if (val != null && !val.equals(Main.currentNodeName)) {
SingleThreadedExecutor.execute( () -> Main.selectFile(val)); SingleThreadedExecutor.execute(() -> Main.selectFile(val));
} }
} }
}); });
+8 -20
View File
@@ -1,8 +1,6 @@
package me.ByteEdit.decompiler; package me.ByteEdit.decompiler;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -24,8 +22,7 @@ import org.benf.cfr.reader.util.output.ToStringDumper;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
@SuppressWarnings("deprecation") public class CFRDecompiler implements IDecompiler {
public class CFRDecompiler {
public static final HashMap<String, String> options = new HashMap<>(); public static final HashMap<String, String> options = new HashMap<>();
@@ -84,7 +81,12 @@ public class CFRDecompiler {
options.put("usenametable", "true"); options.put("usenametable", "true");
} }
public static String decompile(ClassNode cn, byte[] b, MethodNode mn) { @Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn), null);
}
private static String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) {
try { try {
HashMap<String, String> ops = options; HashMap<String, String> ops = options;
ClassFileSource cfs = new ClassFileSource() { ClassFileSource cfs = new ClassFileSource() {
@@ -131,7 +133,7 @@ public class CFRDecompiler {
} }
String decompilation = runner.getDecompilationFor(cn.name); String decompilation = runner.getDecompilationFor(cn.name);
System.gc(); // cfr has a performance bug System.gc(); // cfr has a performance bug
return decompilation.substring(37); // small hack to remove watermark return decompilation;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
@@ -148,18 +150,4 @@ public class CFRDecompiler {
DCCommonState dcCommonState = new DCCommonState(options, classFileSource); DCCommonState dcCommonState = new DCCommonState(options, classFileSource);
return dcCommonState; return dcCommonState;
} }
protected Pair<byte[], String> getSystemClass(String name, String path) throws IOException {
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(path);
if (is != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n;
while ((n = is.read(buffer)) > 0) {
baos.write(buffer, 0, n);
}
return Pair.make(baos.toByteArray(), name);
}
return null;
}
} }
+39 -9
View File
@@ -1,15 +1,45 @@
package me.ByteEdit.decompiler; package me.ByteEdit.decompiler;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import me.ByteEdit.edit.Disassembler;
public enum EnumDecompiler { public enum EnumDecompiler {
BYTEEDIT("ByteEdit"), PROCYON("Procyon"), FERNFLOWER("FernFlower"), JD_GUI("JD-GUI"), CFR("CFR"); BYTEEDIT("ByteEdit", new Disassembler(), false), PROCYON("Procyon", new ProcyonDecompiler()),
FERNFLOWER("FernFlower", new FernflowerDecompiler()), JD_GUI("JD-GUI", new JDDecompiler()),
CFR("CFR", new CFRDecompiler());
final String name; private final String name;
private final IDecompiler decompiler;
private final String syntaxStyle;
private final boolean isEditable;
EnumDecompiler(String name){ private EnumDecompiler(String name, IDecompiler decompiler) {
this.name = name; this(name, decompiler, true);
} }
@Override
public String toString() { private EnumDecompiler(String name, IDecompiler decompiler, boolean isDecompiler) {
return name; this.name = name;
} this.decompiler = decompiler;
this.syntaxStyle = isDecompiler ? SyntaxConstants.SYNTAX_STYLE_JAVA
: SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE;
this.isEditable = !isDecompiler;
}
public IDecompiler getDecompiler() {
return decompiler;
}
public String getSyntaxStyle() {
return syntaxStyle;
}
public boolean isEditable() {
return isEditable;
}
@Override
public String toString() {
return name;
}
} }
@@ -18,7 +18,7 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver { public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver, IDecompiler {
private byte[] bytes; private byte[] bytes;
private String returned; private String returned;
@@ -50,7 +50,12 @@ public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver {
options.put("lac", false); options.put("lac", false);
} }
public String decompile(ClassNode cn, byte[] b, MethodNode mn) { @Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn), null);
}
public String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) {
try { try {
// TODO decompile method only // TODO decompile method only
this.bytes = b; this.bytes = b;
@@ -66,6 +71,11 @@ public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver {
@Override @Override
public void writeMessage(String message, Severity severity) { public void writeMessage(String message, Severity severity) {
} }
@Override
public boolean accepts(Severity severity) {
return false;
}
}); });
StructContext sc = f.getStructContext(); StructContext sc = f.getStructContext();
StructClass cl = new StructClass(b, true, sc.getLoader()); StructClass cl = new StructClass(b, true, sc.getLoader());
@@ -0,0 +1,16 @@
package me.ByteEdit.decompiler;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
public interface IDecompiler {
String decompile(ClassNode cn);
default byte[] getBytes(ClassNode cn) {
ClassWriter classWriter = new ClassWriter(0);
cn.accept(classWriter);
return classWriter.toByteArray();
}
}
+12 -8
View File
@@ -1,6 +1,5 @@
package me.ByteEdit.decompiler; package me.ByteEdit.decompiler;
import me.ByteEdit.main.Main;
import org.jd.core.v1.ClassFileToJavaSourceDecompiler; import org.jd.core.v1.ClassFileToJavaSourceDecompiler;
import org.jd.core.v1.api.loader.Loader; import org.jd.core.v1.api.loader.Loader;
import org.jd.core.v1.api.loader.LoaderException; import org.jd.core.v1.api.loader.LoaderException;
@@ -8,24 +7,29 @@ import org.jd.core.v1.api.printer.Printer;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import me.ByteEdit.main.Main;
public class JDDecompiler implements Loader, Printer { public class JDDecompiler implements Loader, Printer, IDecompiler {
public String decompile(ClassNode cl) { @Override
public String decompile(ClassNode cn) {
ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler(); ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler();
try { try {
decompiler.decompile(this, this, cl.name); decompiler.decompile(this, this, cn.name);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
String str = e.getClass().getName() + " - " + e.getMessage() + System.lineSeparator(); String str = e.getClass().getName() + " - " + e.getMessage() + System.lineSeparator();
for(int i = 0; i < e.getStackTrace().length; i++) { for (int i = 0; i < e.getStackTrace().length; i++) {
str += e.getStackTrace()[i].toString() + System.lineSeparator(); str += e.getStackTrace()[i].toString() + System.lineSeparator();
} }
return str; return str;
} }
return toString(); String decomp = toString();
indentationCount = 0;
sb = new StringBuilder();
return decomp;
} }
@Override @Override
public boolean canLoad(String internalName) { public boolean canLoad(String internalName) {
return Main.classNodes.containsKey(internalName + ".class"); return Main.classNodes.containsKey(internalName + ".class");
@@ -17,9 +17,14 @@ import com.strobel.decompiler.DecompilationOptions;
import com.strobel.decompiler.DecompilerSettings; import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput; import com.strobel.decompiler.PlainTextOutput;
public class ProcyonDecompiler { public class ProcyonDecompiler implements IDecompiler {
public static String decompile(ClassNode cn, byte[] b, MethodNode mn) { @Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn), null);
}
private static String doDecompilation(ClassNode cn, byte[] b, MethodNode mn) {
try { try {
// TODO decompile method only // TODO decompile method only
DecompilerSettings settings = new DecompilerSettings(); DecompilerSettings settings = new DecompilerSettings();
@@ -4,24 +4,23 @@ import java.util.concurrent.LinkedBlockingQueue;
public class SingleThreadedExecutor { public class SingleThreadedExecutor {
private static final LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
private static LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(); private static final Thread thread = new Thread(() -> {
while (true) {
try {
queue.take().run();
} catch (Throwable e) {
e.printStackTrace();
}
}
}, "SingleThreadedExecutor");
private static final Thread thread = new Thread(() -> { static {
while(true){ thread.start();
try { }
queue.take().run();
} catch (Throwable e) {
e.printStackTrace();
}
}
}, "Single");
static {
thread.start();
}
public static void execute(Runnable r) {
public static void execute(Runnable r){ queue.add(r);
queue.add(r); }
}
} }
+19 -77
View File
@@ -27,14 +27,11 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
import com.strobel.decompiler.Decompiler; import org.objectweb.asm.Handle;
import me.ByteEdit.decompiler.CFRDecompiler; import org.objectweb.asm.Label;
import me.ByteEdit.decompiler.FernflowerDecompiler; import org.objectweb.asm.Opcodes;
import me.ByteEdit.decompiler.JDDecompiler; import org.objectweb.asm.Type;
import me.ByteEdit.decompiler.ProcyonDecompiler;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.AnnotationNode; import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
@@ -60,76 +57,29 @@ import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode; import org.objectweb.asm.tree.VarInsnNode;
import me.ByteEdit.decompiler.IDecompiler;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.OpcodesReverse; import me.ByteEdit.utils.OpcodesReverse;
import me.ByteEdit.utils.UnicodeUtils; import me.ByteEdit.utils.UnicodeUtils;
public class Disassembler { public class Disassembler implements IDecompiler {
private static final ExecutorService exec = Executors private static final ExecutorService exec = Executors
.newFixedThreadPool((Runtime.getRuntime().availableProcessors() + 1) / 2); .newFixedThreadPool((Runtime.getRuntime().availableProcessors() + 1) / 2);
public static String disassemble(ClassNode classNode) { @Override
return disassemble(classNode, null).getDisassembly(); public String decompile(ClassNode cn) {
return disassemble(cn);
} }
public static class DisassembleTuple { private static String disassemble(ClassNode classNode) {
private final String dis;
private final int line;
public DisassembleTuple(String dis) {
this.dis = dis;
this.line = -1;
}
public DisassembleTuple(String dis, int line) {
this.dis = dis;
this.line = line;
}
public String getDisassembly() {
return dis;
}
public int getLine() {
return line;
}
}
public static DisassembleTuple disassemble(ClassNode classNode, Object nodeToFind) {
if (classNode == null) { if (classNode == null) {
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!"); return "ClassNode is null! This is not a valid java class file!";
} }
try { try {
System.out.println(Main.decompiler);
ClassWriter classWriter = new ClassWriter(0);
switch (Main.decompiler){
case PROCYON:
classNode.accept(classWriter);
return new DisassembleTuple(ProcyonDecompiler.decompile(classNode, classWriter.toByteArray(), null));
case FERNFLOWER:
classNode.accept(classWriter);
return new DisassembleTuple(new FernflowerDecompiler().decompile(classNode, classWriter.toByteArray(), null));
case JD_GUI:
classNode.accept(classWriter);
return new DisassembleTuple(new JDDecompiler().decompile(classNode));
case CFR:
classNode.accept(classWriter);
return new DisassembleTuple(CFRDecompiler.decompile(classNode, classWriter.toByteArray(), null));
default:
break;
}
HugeStrings hs = new HugeStrings(); HugeStrings hs = new HugeStrings();
AtomicInteger lineFound = new AtomicInteger(-1);
StringContext ctx = new StringContext(18); StringContext ctx = new StringContext(18);
ctx.next("// #Annotations:\n"); ctx.next("// #Annotations:\n");
ctx.next(doAnnotations(classNode.visibleAnnotations, hs, "")); ctx.next(doAnnotations(classNode.visibleAnnotations, hs, ""));
@@ -175,19 +125,18 @@ public class Disassembler {
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(hs, classNode.sourceFile)) + "\n"); + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(hs, classNode.sourceFile)) + "\n");
int hugeIdx = ctx.next(""); int hugeIdx = ctx.next("");
ctx.next("\n// #Fields\n"); ctx.next("\n// #Fields\n");
ctx.next(doFields(classNode.fields, nodeToFind, lineFound, hs)); ctx.next(doFields(classNode.fields, hs));
ctx.next("\n// #Methods\n"); ctx.next("\n// #Methods\n");
ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound, hs)); ctx.next(doMethods(classNode.methods, classNode.name, hs));
ctx.next("}\n"); ctx.next("}\n");
if (!hs.isEmpty()) if (!hs.isEmpty())
ctx.set(hugeIdx, hs.makeStringsList()); ctx.set(hugeIdx, hs.makeStringsList());
return new DisassembleTuple(ctx.finish(), lineFound.get()); return ctx.finish();
} catch (Throwable e) { } catch (Throwable e) {
return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": " return "Class couldn't be decompiled:\n" + e.getClass().getName() + ": " + e.getMessage() + "\n"
+ e.getMessage() + "\n"
+ Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "") + Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "")
+ "\n"); + "\n";
} }
} }
@@ -258,8 +207,8 @@ public class Disassembler {
return ctx.finish(); return ctx.finish();
} }
private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind, private static String doMethods(List<MethodNode> methods, String className, HugeStrings hs)
AtomicInteger lineFound, HugeStrings hs) throws InterruptedException, ExecutionException { throws InterruptedException, ExecutionException {
boolean multithreaded = Main.INSTANCE.mntmMultithreaded.isSelected(); boolean multithreaded = Main.INSTANCE.mntmMultithreaded.isSelected();
Future<String>[] futures = new Future[methods.size()]; Future<String>[] futures = new Future[methods.size()];
for (int i = 0; i < futures.length; i++) { for (int i = 0; i < futures.length; i++) {
@@ -277,9 +226,6 @@ public class Disassembler {
ms += dis[1]; ms += dis[1];
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty())
ms += doAnnotations(mn.visibleAnnotations, hs, "\t"); ms += doAnnotations(mn.visibleAnnotations, hs, "\t");
if (mn.equals(nodeToFind)) {
lineFound.set(ms.split("\\n").length);
}
ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access) ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access)
+ UnicodeUtils.escapeWithSpaces(hs, mn.name) + " " + UnicodeUtils.escapeWithSpaces(hs, mn.name) + " "
+ UnicodeUtils.escapeWithSpaces(hs, mn.desc) + " "; + UnicodeUtils.escapeWithSpaces(hs, mn.desc) + " ";
@@ -321,7 +267,7 @@ public class Disassembler {
return s; return s;
} }
private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound, HugeStrings hs) { private static String doFields(List<FieldNode> fields, HugeStrings hs) {
StringContext ctx = new StringContext(fields.size()); StringContext ctx = new StringContext(fields.size());
for (FieldNode fn : fields) { for (FieldNode fn : fields) {
String s = ""; String s = "";
@@ -329,9 +275,6 @@ public class Disassembler {
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, fn.signature) + "\n"; s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(hs, fn.signature) + "\n";
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty())
s += doAnnotations(fn.visibleAnnotations, hs, "\t"); s += doAnnotations(fn.visibleAnnotations, hs, "\t");
if (fn.equals(nodeToFind)) {
lineFound.set(s.split("\\n").length);
}
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient")
+ UnicodeUtils.escapeWithSpaces(hs, fn.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, fn.name); + UnicodeUtils.escapeWithSpaces(hs, fn.desc) + " " + UnicodeUtils.escapeWithSpaces(hs, fn.name);
if (fn.value != null) { if (fn.value != null) {
@@ -604,5 +547,4 @@ public class Disassembler {
} }
return "null"; return "null";
} }
} }
+4 -4
View File
@@ -10,17 +10,17 @@ import javax.swing.UIManager;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
public class OptionBox extends JFrame { public class OptionBox extends JFrame {
private JPanel contentPane; private JPanel contentPane;
public JCheckBox chckbxComputeFrames; public JCheckBox chckbxComputeFrames;
public JCheckBox chckbxComputeMax; public JCheckBox chckbxComputeMax;
/** /**
* Launch the application. * Launch the application.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
try { try {
OptionBox frame = new OptionBox(); OptionBox frame = new OptionBox();
@@ -31,7 +31,7 @@ public class OptionBox extends JFrame {
} }
}); });
} }
/** /**
* Create the frame. * Create the frame.
*/ */
+15 -13
View File
@@ -20,12 +20,12 @@ import javax.swing.border.EmptyBorder;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
public class SearchBox extends JFrame { public class SearchBox extends JFrame {
public JPanel contentPane; public JPanel contentPane;
public JTextField txtFind; public JTextField txtFind;
public JTextField txtReplace; public JTextField txtReplace;
public JCheckBox chckbxCaseSensitive; public JCheckBox chckbxCaseSensitive;
/** /**
* Create the frame. * Create the frame.
*/ */
@@ -50,7 +50,7 @@ public class SearchBox extends JFrame {
txtFind = new JTextField(); txtFind = new JTextField();
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
txtFind.registerKeyboardAction(new ActionListener() { txtFind.registerKeyboardAction(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
find(); find();
@@ -71,7 +71,7 @@ public class SearchBox extends JFrame {
contentPane.add(chckbxCaseSensitive); contentPane.add(chckbxCaseSensitive);
JButton btnFind = new JButton("Find"); JButton btnFind = new JButton("Find");
btnFind.addActionListener(new ActionListener() { btnFind.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
find(); find();
} }
@@ -80,7 +80,7 @@ public class SearchBox extends JFrame {
contentPane.add(btnFind); contentPane.add(btnFind);
JButton btnReplacefind = new JButton("Replace/Find"); JButton btnReplacefind = new JButton("Replace/Find");
btnReplacefind.addActionListener(new ActionListener() { btnReplacefind.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
replaceFind(); replaceFind();
} }
@@ -89,7 +89,7 @@ public class SearchBox extends JFrame {
contentPane.add(btnReplacefind); contentPane.add(btnReplacefind);
JButton btnReplace = new JButton("Replace"); JButton btnReplace = new JButton("Replace");
btnReplace.addActionListener(new ActionListener() { btnReplace.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
replace(); replace();
} }
@@ -98,7 +98,7 @@ public class SearchBox extends JFrame {
contentPane.add(btnReplace); contentPane.add(btnReplace);
JButton btnReplaceAll = new JButton("Replace All"); JButton btnReplaceAll = new JButton("Replace All");
btnReplaceAll.addActionListener(new ActionListener() { btnReplaceAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
replaceAll(); replaceAll();
} }
@@ -106,7 +106,7 @@ public class SearchBox extends JFrame {
btnReplaceAll.setBounds(130, 184, 110, 23); btnReplaceAll.setBounds(130, 184, 110, 23);
contentPane.add(btnReplaceAll); contentPane.add(btnReplaceAll);
} }
public void find() { public void find() {
int startPos = Main.txtByteEditView.getCaretPosition(); int startPos = Main.txtByteEditView.getCaretPosition();
String toFind = txtFind.getText(); String toFind = txtFind.getText();
@@ -114,7 +114,8 @@ public class SearchBox extends JFrame {
: Main.txtByteEditView.getText().substring(startPos).toLowerCase(); : Main.txtByteEditView.getText().substring(startPos).toLowerCase();
int index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase()); int index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase());
if (index == -1) { if (index == -1) {
txt = chckbxCaseSensitive.isSelected() ? Main.txtByteEditView.getText() : Main.txtByteEditView.getText().toLowerCase(); txt = chckbxCaseSensitive.isSelected() ? Main.txtByteEditView.getText()
: Main.txtByteEditView.getText().toLowerCase();
index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase()); index = txt.indexOf(chckbxCaseSensitive.isSelected() ? toFind : toFind.toLowerCase());
startPos = 0; startPos = 0;
if (index == -1) { if (index == -1) {
@@ -123,19 +124,19 @@ public class SearchBox extends JFrame {
} }
Main.txtByteEditView.select(startPos + index, startPos + index + toFind.length()); Main.txtByteEditView.select(startPos + index, startPos + index + toFind.length());
} }
public void replaceFind() { public void replaceFind() {
replace(); replace();
find(); find();
} }
public void replace() { public void replace() {
String txt = Main.txtByteEditView.getText(); String txt = Main.txtByteEditView.getText();
int startPos = Main.txtByteEditView.getSelectionStart(); int startPos = Main.txtByteEditView.getSelectionStart();
Main.txtByteEditView.replaceSelection(txtReplace.getText()); Main.txtByteEditView.replaceSelection(txtReplace.getText());
Main.txtByteEditView.select(startPos, startPos + txtReplace.getText().length()); Main.txtByteEditView.select(startPos, startPos + txtReplace.getText().length());
} }
public void replaceAll() { public void replaceAll() {
String toFind = txtFind.getText(); String toFind = txtFind.getText();
String toReplace = txtReplace.getText(); String toReplace = txtReplace.getText();
@@ -144,7 +145,8 @@ public class SearchBox extends JFrame {
if (chckbxCaseSensitive.isSelected()) { if (chckbxCaseSensitive.isSelected()) {
Main.txtByteEditView.replaceRange(txt.replace(toFind, toReplace), 0, txt.length()); Main.txtByteEditView.replaceRange(txt.replace(toFind, toReplace), 0, txt.length());
} else { } else {
Main.txtByteEditView.replaceRange(txt.replaceAll("(?i)" + Pattern.quote(toFind), toReplace), 0, txt.length()); Main.txtByteEditView.replaceRange(txt.replaceAll("(?i)" + Pattern.quote(toFind), toReplace), 0,
txt.length());
} }
Main.txtByteEditView.setCaretPosition(prev); Main.txtByteEditView.setCaretPosition(prev);
} }
+14 -15
View File
@@ -3,7 +3,6 @@ package me.ByteEdit.edit;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JFrame; import javax.swing.JFrame;
@@ -23,10 +22,10 @@ import me.ByteEdit.decompiler.SingleThreadedExecutor;
import me.ByteEdit.main.Main; import me.ByteEdit.main.Main;
public class TypeOpenBox extends JFrame { public class TypeOpenBox extends JFrame {
public JPanel contentPane; public JPanel contentPane;
public JTextField txtSearch; public JTextField txtSearch;
/** /**
* Create the frame. * Create the frame.
*/ */
@@ -45,23 +44,23 @@ public class TypeOpenBox extends JFrame {
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane); setContentPane(contentPane);
contentPane.setLayout(null); contentPane.setLayout(null);
DefaultListModel<String> model = new DefaultListModel<>(); DefaultListModel<String> model = new DefaultListModel<>();
JList<String> list = new JList(model); JList<String> list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() { list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) { public void valueChanged(ListSelectionEvent e) {
String val = list.getSelectedValue(); String val = list.getSelectedValue();
if (val != null && !val.equals(Main.currentNodeName)) { if (val != null && !val.equals(Main.currentNodeName)) {
SingleThreadedExecutor.execute( () -> Main.selectFile(val)); SingleThreadedExecutor.execute(() -> Main.selectFile(val));
} }
} }
}); });
txtSearch = new JTextField(); txtSearch = new JTextField();
txtSearch.addActionListener(new ActionListener() { txtSearch.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (model.size() == 1) { if (model.size() == 1) {
list.setSelectedIndex(0); list.setSelectedIndex(0);
@@ -69,19 +68,19 @@ public class TypeOpenBox extends JFrame {
} }
}); });
txtSearch.getDocument().addDocumentListener(new DocumentListener() { txtSearch.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) { public void changedUpdate(DocumentEvent e) {
updateList(); updateList();
} }
public void removeUpdate(DocumentEvent e) { public void removeUpdate(DocumentEvent e) {
updateList(); updateList();
} }
public void insertUpdate(DocumentEvent e) { public void insertUpdate(DocumentEvent e) {
updateList(); updateList();
} }
public void updateList() { public void updateList() {
model.clear(); model.clear();
if (txtSearch.getText().isEmpty()) { if (txtSearch.getText().isEmpty()) {
@@ -110,13 +109,13 @@ public class TypeOpenBox extends JFrame {
txtSearch.setBounds(10, 11, 374, 20); txtSearch.setBounds(10, 11, 374, 20);
contentPane.add(txtSearch); contentPane.add(txtSearch);
txtSearch.setColumns(10); txtSearch.setColumns(10);
JScrollPane scrollPane = new JScrollPane(); JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 46, 374, 194); scrollPane.setBounds(10, 46, 374, 194);
contentPane.add(scrollPane); contentPane.add(scrollPane);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
scrollPane.setViewportView(list); scrollPane.setViewportView(list);
} }
} }
+94 -215
View File
@@ -1,6 +1,12 @@
package me.ByteEdit.main; package me.ByteEdit.main;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
import java.awt.dnd.DropTarget; import java.awt.dnd.DropTarget;
@@ -8,7 +14,13 @@ import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener; import java.awt.dnd.DropTargetListener;
import java.awt.event.*; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@@ -16,13 +28,15 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -30,7 +44,24 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import javax.swing.*; import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener; import javax.swing.event.TreeExpansionListener;
@@ -44,8 +75,6 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
import me.ByteEdit.decompiler.EnumDecompiler;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.autocomplete.AutoCompletion;
import org.fife.ui.autocomplete.BasicCompletion; import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.CompletionProvider; import org.fife.ui.autocomplete.CompletionProvider;
@@ -61,7 +90,6 @@ import org.fife.ui.rtextarea.ToolTipSupplier;
import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import me.ByteEdit.boxes.CompilationBox; import me.ByteEdit.boxes.CompilationBox;
@@ -71,9 +99,9 @@ import me.ByteEdit.boxes.SearchBox;
import me.ByteEdit.boxes.ThemeBox; import me.ByteEdit.boxes.ThemeBox;
import me.ByteEdit.boxes.TypeOpenBox; import me.ByteEdit.boxes.TypeOpenBox;
import me.ByteEdit.boxes.UnicodeBox; import me.ByteEdit.boxes.UnicodeBox;
import me.ByteEdit.decompiler.EnumDecompiler;
import me.ByteEdit.decompiler.SingleThreadedExecutor;
import me.ByteEdit.edit.Assembler; import me.ByteEdit.edit.Assembler;
import me.ByteEdit.edit.Disassembler;
import me.ByteEdit.edit.Disassembler.DisassembleTuple;
import me.ByteEdit.edit.HugeStrings; import me.ByteEdit.edit.HugeStrings;
import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.OpcodesReverse; import me.ByteEdit.utils.OpcodesReverse;
@@ -81,8 +109,6 @@ import me.ByteEdit.utils.UnicodeUtils;
public class Main extends JFrame { public class Main extends JFrame {
public static Main INSTANCE; public static Main INSTANCE;
private JPanel contentPane; private JPanel contentPane;
private volatile boolean isChangingFile; private volatile boolean isChangingFile;
@@ -136,19 +162,15 @@ public class Main extends JFrame {
* Launch the application. * Launch the application.
*/ */
public static void main(String[] args) { public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() { EventQueue.invokeLater(() -> {
try {
public void run() { Main frame = new Main();
try { frame.setVisible(true);
Main frame = new Main(); ThemeManager.applyRSTATheme();
frame.setVisible(true); } catch (Exception e) {
ThemeManager.applyRSTATheme(); e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} }
}); });
} }
/** /**
@@ -431,7 +453,6 @@ public class Main extends JFrame {
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
tree.addTreeExpansionListener(new FurtherExpandingTreeExpansionListener()); tree.addTreeExpansionListener(new FurtherExpandingTreeExpansionListener());
tree.addKeyListener(new KeyAdapter() { tree.addKeyListener(new KeyAdapter() {
@Override @Override
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 116 && jarFile != null) { // F5 if (e.getKeyCode() == 116 && jarFile != null) { // F5
@@ -505,8 +526,8 @@ public class Main extends JFrame {
public void valueChanged(TreeSelectionEvent e) { public void valueChanged(TreeSelectionEvent e) {
synchronized (treeLock) { synchronized (treeLock) {
if (!isChangingFile) { if (!isChangingFile) {
SingleThreadedExecutor.execute(
SingleThreadedExecutor.execute( () -> selectFile(((ByteEditTreeNode) e.getPath().getLastPathComponent()).path)); () -> selectFile(((ByteEditTreeNode) e.getPath().getLastPathComponent()).path));
} }
} }
} }
@@ -526,7 +547,7 @@ public class Main extends JFrame {
for (int i = 0; i < flavors.length; i++) { for (int i = 0; i < flavors.length; i++) {
if (flavors[i].isFlavorJavaFileListType()) { if (flavors[i].isFlavorJavaFileListType()) {
dtde.acceptDrop(dtde.getDropAction()); dtde.acceptDrop(dtde.getDropAction());
java.util.List<File> files = (java.util.List<File>) tr.getTransferData(flavors[i]); List<File> files = (List<File>) tr.getTransferData(flavors[i]);
final File file = files.get(0); final File file = files.get(0);
if (file.getName().endsWith(".jar")) { if (file.getName().endsWith(".jar")) {
jarFile = file; jarFile = file;
@@ -676,34 +697,10 @@ public class Main extends JFrame {
} }
}); });
txtByteEditView.addKeyListener(new KeyAdapter() { txtByteEditView.addKeyListener(new KeyAdapter() {
@Override @Override
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 116 && currentNodeName != null) { // F5 if (e.getKeyCode() == 116 && currentNodeName != null) { // F5
SingleThreadedExecutor.execute(Main::decompileCurrentNode);
SingleThreadedExecutor.execute( () -> {
try {
ClassNode classNode = classNodes.get(currentNodeName);
int prev = txtByteEditView.getCaretPosition();
String dis = Disassembler.disassemble(classNode);
String substr = currentNodeName.substring(0, currentNodeName.length() - 6);
synchronized (Main.classNodes){
for (String key : Main.classNodes.keySet()) {
if (key.contains("$")) {
String[] split = key.split("\\$");
if (split[0].equals(substr)) {
dis += "\n" + Disassembler.disassemble(classNodes.get(key));
}
}
}
}
txtByteEditView.setText(dis);
if (dis.length() > prev)
txtByteEditView.setCaretPosition(prev);
} catch (Exception e2) {
e2.printStackTrace();
}
});
} }
} }
}); });
@@ -740,13 +737,6 @@ public class Main extends JFrame {
// specific // specific
tree.registerKeyboardAction(e -> save(), ctrlS, JComponent.WHEN_FOCUSED); tree.registerKeyboardAction(e -> save(), ctrlS, JComponent.WHEN_FOCUSED);
txtByteEditView.registerKeyboardAction(e -> saveCurrentClassNode(), ctrlS, JComponent.WHEN_FOCUSED); txtByteEditView.registerKeyboardAction(e -> saveCurrentClassNode(), ctrlS, JComponent.WHEN_FOCUSED);
txtByteEditView.registerKeyboardAction(e -> {
try {
goToSelected();
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}, ctrlG, JComponent.WHEN_FOCUSED);
txtByteEditView.registerKeyboardAction(e -> { txtByteEditView.registerKeyboardAction(e -> {
try { try {
renameSelected(); renameSelected();
@@ -769,147 +759,39 @@ public class Main extends JFrame {
decompilerMode.addItemListener(new ItemListener() { decompilerMode.addItemListener(new ItemListener() {
@Override @Override
public void itemStateChanged(ItemEvent e) { public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
SingleThreadedExecutor.execute( () -> { EnumDecompiler selected = (EnumDecompiler) e.getItem();
decompiler = (EnumDecompiler) e.getItem(); SingleThreadedExecutor.execute(() -> {
try { decompiler = selected;
txtByteEditView.setSyntaxEditingStyle(decompiler == EnumDecompiler.BYTEEDIT ? SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE : SyntaxConstants.SYNTAX_STYLE_JAVA); if (currentNodeName != null) {
} catch (Throwable t){} decompileCurrentNode();
txtByteEditView.setEditable(decompiler == EnumDecompiler.BYTEEDIT); try {
if (currentNodeName != null) { EventQueue.invokeAndWait(() -> {
txtByteEditView.setCaretPosition(0);
try {
try { txtByteEditView.setSyntaxEditingStyle(decompiler.getSyntaxStyle());
ClassNode classNode = classNodes.get(currentNodeName); } catch (Throwable t) {
int prev = txtByteEditView.getCaretPosition();
String dis = Disassembler.disassemble(classNode);
String substr = currentNodeName.substring(0, currentNodeName.length() - 6);
for (String key : Main.classNodes.keySet()) {
if (key.contains("$")) {
String[] split = key.split("\\$");
if (split[0].equals(substr)) {
dis += "\n" + Disassembler.disassemble(classNodes.get(key));
} }
} txtByteEditView.setEditable(decompiler.isEditable());
});
} catch (Exception e1) {
e1.printStackTrace();
} }
txtByteEditView.setText(dis);
if (dis.length() > prev)
txtByteEditView.setCaretPosition(prev);
} catch (Exception e2) {
e2.printStackTrace();
} }
});
}
}
});
} }
}); });
panel.add(decompilerMode, BorderLayout.NORTH); panel.add(decompilerMode, BorderLayout.NORTH);
splitPane.setRightComponent(panel); splitPane.setRightComponent(panel);
scrollPane_ByteEdit.setViewportView(txtByteEditView); scrollPane_ByteEdit.setViewportView(txtByteEditView);
scrollPane_ByteEdit.setLineNumbersEnabled(true); scrollPane_ByteEdit.setLineNumbersEnabled(true);
scrollPane_ByteEdit.setFoldIndicatorEnabled(true); scrollPane_ByteEdit.setFoldIndicatorEnabled(true);
} }
public static EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT; public static EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT;
private final Pattern jumpableInstructionPattern = Pattern.compile("^\t\t(?!//|\t+).+ .+");
public void goToSelected() throws BadLocationException {
int lineStart = txtByteEditView.getLineStartOffsetOfCurrentLine();
int lineEnd = txtByteEditView.getLineEndOffsetOfCurrentLine() - 1;
if (lineEnd < lineStart)
return;
String line = txtByteEditView.getText(lineStart, lineEnd - lineStart);
if (!jumpableInstructionPattern.matcher(line).matches()) {
return;
}
line = line.substring(2);
if (line.startsWith("invoke")) {
String[] split = line.split(" ");
String desc = UnicodeUtils.unescape(null, split[1], true);
String target = split[2];
int index = target.lastIndexOf("/");
String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
String methodName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) {
return;
}
for (MethodNode mn : classNode.methods) {
if (mn.name.equals(methodName) && mn.desc.equals(desc)) {
while (classNode.outerClass != null) {
classNode = classNodes.get(getFullName(classNode.outerClass));
}
ClassNode finalClassNode = classNode;
SingleThreadedExecutor.execute( () -> {
int lineFound = selectFileWithSearch(getFullName(finalClassNode.name), mn);
if (lineFound != -1) {
try {
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
});
break;
}
}
} else if (line.startsWith("new ")) {
String[] split = line.split(" ");
String className = UnicodeUtils.unescape(null, split[1], true);
ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) {
return;
}
SingleThreadedExecutor.execute( () -> selectFile(getFullName(className)));
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ")
|| line.startsWith("putfield ")) {
String[] split = line.split(" ");
String desc = UnicodeUtils.unescape(null, split[1], true);
String target = split[2];
int index = target.lastIndexOf("/");
String className = UnicodeUtils.unescape(null, target.substring(0, index), true);
String fieldName = UnicodeUtils.unescape(null, target.substring(index + 1), true);
ClassNode classNode = classNodes.get(getFullName(className));
if (classNode == null) {
return;
}
for (FieldNode fn : classNode.fields) {
if (fn.name.equals(fieldName) && fn.desc.equals(desc)) {
while (classNode.outerClass != null) {
classNode = classNodes.get(getFullName(classNode.outerClass));
}
ClassNode finalClassNode = classNode;
ClassNode finalClassNode1 = classNode;
SingleThreadedExecutor.execute( () -> {
int lineFound = selectFileWithSearch(getFullName(finalClassNode1.name), fn);
if (lineFound != -1) {
try {
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
} catch (BadLocationException e) {
e.printStackTrace();
}
}
});
break;
}
}
}
}
private final Pattern renameableFieldPattern = Pattern private final Pattern renameableFieldPattern = Pattern
.compile("^\t(?:[a-z]+ |0x[0-9a-fA-F]+ )*?(\\[*(?:V|Z|C|B|S|I|F|J|D|L.+?;)) ([^ ]+) ?.*"); .compile("^\t(?:[a-z]+ |0x[0-9a-fA-F]+ )*?(\\[*(?:V|Z|C|B|S|I|F|J|D|L.+?;)) ([^ ]+) ?.*");
private final Pattern renameableMethodPattern = Pattern private final Pattern renameableMethodPattern = Pattern
@@ -999,41 +881,38 @@ public class Main extends JFrame {
} }
} }
public static int selectFileWithSearch(String s, Object nodeToFind) { public static void decompileCurrentNode() {
if (s != null && s.endsWith(".class")) { try {
currentNodeName = s; EnumDecompiler decompiler = Main.decompiler;
int lineFound = -1; String current = currentNodeName;
ClassNode classNode = classNodes.get(s); ClassNode classNode = classNodes.get(current);
if (classNode == null) int prev = txtByteEditView.getCaretPosition();
return -1; String dis = decompiler.getDecompiler().decompile(classNode);
String dis = ""; String substr = current.substring(0, current.length() - 6);
DisassembleTuple tuple = Disassembler.disassemble(classNode, nodeToFind); synchronized (Main.classNodes) {
if (tuple.getLine() != -1) { for (String key : Main.classNodes.keySet()) {
lineFound = dis.split("\\n").length + tuple.getLine() - 1; if (key.contains("$")) {
} String[] split = key.split("\\$");
dis += tuple.getDisassembly(); if (split[0].equals(substr)) {
String substr = s.substring(0, s.length() - 6); dis += "\n" + decompiler.getDecompiler().decompile(classNodes.get(key));
for (String key : Main.classNodes.keySet()) {
if (key.contains("$")) {
String[] split = key.split("\\$");
if (split[0].equals(substr)) {
tuple = Disassembler.disassemble(classNodes.get(key), nodeToFind);
if (tuple.getLine() != -1) {
lineFound = dis.split("\\n").length + tuple.getLine() + 1;
} }
dis += "\n" + tuple.getDisassembly();
} }
} }
} }
txtByteEditView.setText(dis); txtByteEditView.setText(dis);
txtByteEditView.setCaretPosition(0); if (dis.length() > prev)
return lineFound; txtByteEditView.setCaretPosition(prev);
} catch (Exception e2) {
e2.printStackTrace();
} }
return -1;
} }
public static int selectFile(String s) { public static void selectFile(String s) {
return selectFileWithSearch(s, null); if (s != null && s.endsWith(".class")) {
currentNodeName = s;
decompileCurrentNode();
txtByteEditView.setCaretPosition(0);
}
} }
public void save() { public void save() {
+1 -1
View File
@@ -14,7 +14,7 @@
<!-- General editor colors. --> <!-- General editor colors. -->
<background color="2f2f2f"/> <background color="2f2f2f"/>
<caret color="eeeeee"/> <caret color="eeeeee"/>
<selection bg="111111" fg="eeeeee"/> <selection bg="555555" fg="eeeeee"/>
<currentLineHighlight color="111111" fade="false"/> <currentLineHighlight color="111111" fade="false"/>
<marginLine fg="4f4b46"/> <marginLine fg="4f4b46"/>
<markAllHighlight color="947e76"/> <!-- TODO: Fix me --> <markAllHighlight color="947e76"/> <!-- TODO: Fix me -->
@@ -102,7 +102,8 @@ class DefaultTokenFactory implements TokenFactory {
@Override @Override
public TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset, public TokenImpl createToken(final char[] line, final int beg, final int end, final int startOffset,
final int type) { final int type) {
// if(tokenList.length - 1 > currentFreeToken) return null; // if (tokenList.length - 1 > currentFreeToken)
// return null;
TokenImpl token = tokenList[currentFreeToken]; TokenImpl token = tokenList[currentFreeToken];
token.set(line, beg, end, startOffset, type); token.set(line, beg, end, startOffset, type);
currentFreeToken++; currentFreeToken++;
@@ -108,7 +108,8 @@ public abstract class TokenMakerBase implements TokenMaker {
currentToken = firstToken; // previous token is still null. currentToken = firstToken; // previous token is still null.
} else { } else {
TokenImpl next = tokenFactory.createToken(array, start, end, startOffset, tokenType); TokenImpl next = tokenFactory.createToken(array, start, end, startOffset, tokenType);
if(currentToken == null || next == null ) return; if (currentToken == null || next == null)
return;
currentToken.setNextToken(next); currentToken.setNextToken(next);
previousToken = currentToken; previousToken = currentToken;
currentToken = next; currentToken = next;
@@ -3184,9 +3184,8 @@ public class JavaTokenMaker extends AbstractJFlexCTokenMaker {
return null; return null;
} }
} else { } else {
//zzScanError(ZZ_NO_MATCH); // zzScanError(ZZ_NO_MATCH);
return null; return null;
} }
} }
} }