12 Commits
Author SHA1 Message Date
SuspiciousActivity 1a73814a81 update ASM 9.2 2021-12-03 23:04:55 +01:00
SuspiciousActivity 08af91a3f7 added deobfuscation: noop remover 2021-11-25 22:02:43 +01:00
SuspiciousActivity ad975e67db Merge pull request #2 from EvilCodeZ/master
Fixed POP2 instruction in StackBasedCalculator.
2021-09-05 15:51:11 +02:00
EvilCodeZ 4beaab1283 Fixed POP2 instruction in StackBasedCalculator. 2021-09-05 15:02:55 +02:00
SuspiciousActivity cfa278cd3b Annotations fix 2021-05-02 23:22:43 +02:00
SuspiciousActivity 46c0596768 Fix global search 2021-04-20 20:59:16 +02:00
SuspiciousActivity 74e9491fcf Easier Types 2021-04-20 20:56:00 +02:00
SuspiciousActivity 198c76823b Fixed delete 2021-04-19 11:04:16 +02:00
SuspiciousActivity 1c6a72d951 Bug fix 2021-03-28 22:55:09 +02:00
SuspiciousActivity ed9b6a177b Removed Fernflower 2021-03-12 23:57:42 +01:00
SuspiciousActivity a9612c058c Removed ".class" from internal classNodes map 2021-03-12 23:29:47 +01:00
SuspiciousActivity b86e8658e2 Fixed subclasses in decompilers 2021-03-12 23:04:10 +01:00
15 changed files with 157 additions and 276 deletions

No files matched your search

+20 -7
View File
@@ -15,6 +15,8 @@ import java.io.StringWriter;
import java.net.URI;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JFrame;
@@ -122,7 +124,13 @@ public class CompilationBox extends JFrame {
ClassNode node = new ClassNode();
read.accept(node, 0);
EnumDecompiler decompiler = EnumDecompiler.BYTEEDIT;
String dis = decompiler.getDecompiler().decompile(node);
ClassNode mainNode = node;
Map<String, ClassNode> classNodes;
synchronized (Main.classNodes) {
classNodes = new HashMap<>(Main.classNodes);
}
classNodes.put("Compiled", node);
File[] files = tmpFolder.listFiles();
if (files != null)
for (File f : files) {
@@ -137,21 +145,26 @@ public class CompilationBox extends JFrame {
read = new ClassReader(baos.toByteArray());
node = new ClassNode();
read.accept(node, 0);
dis += "\n" + decompiler.getDecompiler().decompile(node);
classNodes.put(node.name, node);
}
compSuccess.textArea.setText(dis);
compSuccess.textArea
.setText(decompiler.getDecompiler().decompile(mainNode, classNodes));
compSuccess.setVisible(true);
} catch (IOException e2) {
e2.printStackTrace();
}
try {
for (File f : tmpFolder.listFiles()) {
Files.delete(f.toPath());
}
Files.delete(tmpFolder.toPath());
} catch (IOException e2) {
e2.printStackTrace();
}
});
} else {
JOptionPane.showMessageDialog(CompilationBox.this, res, "Error!", JOptionPane.ERROR_MESSAGE);
}
for (File f : tmpFolder.listFiles()) {
Files.delete(f.toPath());
}
Files.delete(tmpFolder.toPath());
} catch (IOException e1) {
e1.printStackTrace();
}
@@ -37,12 +37,10 @@ public class GlobalSearchOpenBox extends JFrame {
JList<Info> list = new JList(model);
list.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
SingleThreadedExecutor.submit(() -> {
Info val = list.getSelectedValue();
if (val != null && !val.owner.equals(Main.currentNodeName)) {
Main.selectFile(val.nodePath);
if (!e.getValueIsAdjusting() && val != null && !val.owner.equals(Main.currentNodeName)) {
SingleThreadedExecutor.submit(() -> Main.selectFile(val.owner + ".class"));
}
});
}
});
@@ -59,14 +57,12 @@ public class GlobalSearchOpenBox extends JFrame {
String name;
String desc;
MethodNode mn;
String nodePath;
public Info(String owner, String name, String desc, MethodNode mn) {
this.owner = owner;
this.name = name;
this.desc = desc;
this.mn = mn;
nodePath = Main.getFullName(owner);
}
@Override
+3 -3
View File
@@ -79,7 +79,7 @@ public class RenameBox extends JFrame {
JOptionPane.showMessageDialog(null, "Desc not set!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
}
ClassNode clazz = Main.classNodes.get(Main.getFullName(className));
ClassNode clazz = Main.classNodes.get(className);
if (clazz == null) {
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
return;
@@ -94,7 +94,7 @@ public class RenameBox extends JFrame {
if (newDesc.startsWith("(")) { // method
ClassNode lastHit = clazz;
while (clazz != null && clazz.superName != null) {
ClassNode tmp = Main.classNodes.get(Main.getFullName(clazz.superName));
ClassNode tmp = Main.classNodes.get(clazz.superName);
if (tmp != null) {
boolean found = false;
for (MethodNode mn : clazz.methods) {
@@ -127,7 +127,7 @@ public class RenameBox extends JFrame {
extendsMyClass = true;
break;
}
ClassNode tmp = Main.classNodes.get(Main.getFullName(checkCN.superName));
ClassNode tmp = Main.classNodes.get(checkCN.superName);
if (tmp != null) {
checkCN = tmp;
} else {
+8 -10
View File
@@ -43,8 +43,8 @@ public class TypeOpenBox extends JFrame {
@Override
public void valueChanged(ListSelectionEvent e) {
String val = list.getSelectedValue();
if (val != null && !val.equals(Main.currentNodeName)) {
SingleThreadedExecutor.submit(() -> Main.selectFile(val));
if (!e.getValueIsAdjusting() && val != null && !val.equals(Main.currentNodeName)) {
SingleThreadedExecutor.submit(() -> Main.selectFile(val + ".class"));
}
}
});
@@ -79,19 +79,17 @@ public class TypeOpenBox extends JFrame {
}
String search = UnicodeUtils.unescape(null, txtSearch.getText(), true).toLowerCase();
if (search.contains("/")) {
for (String s : Main.classNodes.keySet()) {
String className = s.substring(0, s.length() - 6);
if (!className.contains("$") && className.toLowerCase().startsWith(search)) {
model.addElement(s);
for (String fullName : Main.classNodes.keySet()) {
if (!fullName.contains("$") && fullName.toLowerCase().startsWith(search)) {
model.addElement(fullName);
}
}
} else {
for (String s : Main.classNodes.keySet()) {
String[] split = s.split("/");
for (String fullName : Main.classNodes.keySet()) {
String[] split = fullName.split("/");
String className = split[split.length - 1];
className = className.substring(0, className.length() - 6);
if (!className.contains("$") && className.toLowerCase().startsWith(search)) {
model.addElement(s);
model.addElement(fullName);
}
}
}
+25 -6
View File
@@ -3,12 +3,18 @@ package me.ByteEdit.decompiler;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.benf.cfr.reader.PluginRunner;
import org.benf.cfr.reader.api.ClassFileSource;
import org.benf.cfr.reader.bytecode.analysis.parse.utils.Pair;
import org.benf.cfr.reader.state.ClassFileSourceImpl;
import org.benf.cfr.reader.util.MiscConstants.Version;
import org.benf.cfr.reader.util.getopt.OptionsImpl;
import org.objectweb.asm.tree.ClassNode;
public class CFRDecompiler implements IDecompiler {
@@ -68,17 +74,24 @@ public class CFRDecompiler implements IDecompiler {
options.put("sugarenums", "true");
options.put("tidymonitors", "true");
options.put("usenametable", "true");
try {
Field f = Version.class.getDeclaredField("version");
f.setAccessible(true);
f.set(null, "ByteEdit");
} catch (Exception ex) {
}
}
@Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn));
public String decompile(ClassNode cn, Map<String, ClassNode> classNodes) {
return doDecompilation(cn, IDecompiler.getBytes(cn), classNodes);
}
private static String doDecompilation(ClassNode cn, byte[] b) {
private static String doDecompilation(ClassNode cn, byte[] b, Map<String, ClassNode> classNodes) {
try {
HashMap<String, String> ops = options;
ClassFileSource cfs = new ClassFileSource() {
ClassFileSource cfs = new ClassFileSourceImpl(new OptionsImpl(Collections.EMPTY_MAP)) {
@Override
public void informAnalysisRelativePathDetail(String a, String b) {
@@ -92,10 +105,16 @@ public class CFRDecompiler implements IDecompiler {
@Override
public Pair<byte[], String> getClassFileContent(String path) throws IOException {
String name = path.substring(0, path.length() - 6);
if (name.equals(cn.name)) {
if (name.equals(cn.name))
return Pair.make(b, name);
// try loading other classes from jar
ClassNode node;
synchronized (classNodes) {
node = classNodes.get(name);
}
return null; // cfr loads unnecessary classes
if (node != null)
return Pair.make(IDecompiler.getBytes(node), name);
return super.getClassFileContent(path);
}
@Override
@@ -6,8 +6,7 @@ import me.ByteEdit.edit.Disassembler;
public enum EnumDecompiler {
BYTEEDIT("ByteEdit", new Disassembler(), false), PROCYON("Procyon", new ProcyonDecompiler()),
FERNFLOWER("FernFlower", new FernflowerDecompiler()), JD_GUI("JD-GUI", new JDDecompiler()),
CFR("CFR", new CFRDecompiler());
JD_GUI("JD-GUI", new JDDecompiler()), CFR("CFR", new CFRDecompiler());
private final String name;
private final IDecompiler decompiler;
@@ -1,143 +0,0 @@
package me.ByteEdit.decompiler;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.jar.Manifest;
import org.jetbrains.java.decompiler.main.Fernflower;
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import org.jetbrains.java.decompiler.struct.ContextUnit;
import org.jetbrains.java.decompiler.struct.StructClass;
import org.jetbrains.java.decompiler.struct.StructContext;
import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import org.objectweb.asm.tree.ClassNode;
public class FernflowerDecompiler implements IBytecodeProvider, IResultSaver, IDecompiler {
private byte[] bytes;
private String returned;
public static final HashMap<String, Boolean> options = new HashMap<>();
static {
options.put("rbr", true);
options.put("rsy", false);
options.put("din", true);
options.put("dc4", true);
options.put("das", true);
options.put("hes", true);
options.put("hdc", true);
options.put("dgs", false);
options.put("ner", true);
options.put("den", true);
options.put("rgn", true);
options.put("lit", false);
options.put("asc", true);
options.put("bto", true);
options.put("nns", false);
options.put("uto", true);
options.put("udv", true);
options.put("rer", true);
options.put("fdi", true);
options.put("ren", false);
options.put("inn", true);
options.put("lac", false);
}
@Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn));
}
public String doDecompilation(ClassNode cn, byte[] b) {
try {
// TODO decompile method only
this.bytes = b;
HashMap<String, Object> map = new HashMap<>();
for (Entry<String, Boolean> entry : options.entrySet()) {
map.put(entry.getKey(), entry.getValue() ? "1" : "0");
}
map.put("ind", " ");
Fernflower f = new Fernflower(this, this, map, new IFernflowerLogger() {
@Override
public void writeMessage(String message, Throwable t) {
}
@Override
public void writeMessage(String message, Severity severity) {
}
@Override
public boolean accepts(Severity severity) {
return false;
}
});
StructContext sc = f.getStructContext();
StructClass cl = new StructClass(b, true, sc.getLoader());
sc.getClasses().put(cn.name, cl);
// instead of loading a file use custom bridge, created a few getters
String fakePath = new File("none.class").getAbsolutePath();
ContextUnit unit = new ContextUnit(ContextUnit.TYPE_FOLDER, null, fakePath, true, sc.getSaver(),
sc.getDecompiledData());
sc.getUnits().put(fakePath, unit);
unit.addClass(cl, "none.class");
sc.getLoader().addClassLink(cn.name, new LazyLoader.Link(LazyLoader.Link.CLASS, fakePath, null));
f.decompileContext();
return returned;
} catch (Exception e) {
e.printStackTrace();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
return sw.toString();
}
}
@Override
public byte[] getBytecode(String externalPath, String internalPath) throws IOException {
return bytes;
}
// we can ignore most of those methods because we do not want to save the output
// as a file
@Override
public void saveFolder(String path) {
}
@Override
public void copyFile(String source, String path, String entryName) {
}
@Override
public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) {
this.returned = content;
}
@Override
public void createArchive(String path, String archiveName, Manifest manifest) {
}
@Override
public void saveDirEntry(String path, String archiveName, String entryName) {
}
@Override
public void copyEntry(String source, String path, String archiveName, String entry) {
}
@Override
public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName,
String content) {
}
@Override
public void closeArchive(String path, String archiveName) {
}
}
+4 -2
View File
@@ -1,13 +1,15 @@
package me.ByteEdit.decompiler;
import java.util.Map;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
public interface IDecompiler {
String decompile(ClassNode cn);
String decompile(ClassNode cn, Map<String, ClassNode> classNodes);
default byte[] getBytes(ClassNode cn) {
static byte[] getBytes(ClassNode cn) {
ClassWriter classWriter = new ClassWriter(0);
cn.accept(classWriter);
return classWriter.toByteArray();
+22 -15
View File
@@ -1,18 +1,26 @@
package me.ByteEdit.decompiler;
import java.util.Map;
import org.jd.core.v1.ClassFileToJavaSourceDecompiler;
import org.jd.core.v1.api.loader.Loader;
import org.jd.core.v1.api.loader.LoaderException;
import org.jd.core.v1.api.printer.Printer;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import me.ByteEdit.main.Main;
public class JDDecompiler implements Loader, Printer, IDecompiler {
protected static final String TAB = " ";
protected static final String NEWLINE = "\n";
protected int indentationCount = 0;
protected StringBuilder sb = new StringBuilder();
private Map<String, ClassNode> classNodes;
@Override
public String decompile(ClassNode cn) {
public String decompile(ClassNode cn, Map<String, ClassNode> classNodes) {
this.classNodes = classNodes;
ClassFileToJavaSourceDecompiler decompiler = new ClassFileToJavaSourceDecompiler();
try {
decompiler.decompile(this, this, cn.name);
@@ -32,22 +40,21 @@ public class JDDecompiler implements Loader, Printer, IDecompiler {
@Override
public boolean canLoad(String internalName) {
return Main.classNodes.containsKey(internalName + ".class");
synchronized (classNodes) {
return classNodes.containsKey(internalName);
}
}
@Override
public byte[] load(String internalName) throws LoaderException {
ClassNode cl = Main.classNodes.get(internalName + ".class");
ClassWriter cw = new ClassWriter(0);
cl.accept(cw);
return cw.toByteArray();
ClassNode node;
synchronized (classNodes) {
node = classNodes.get(internalName);
}
if (node != null)
return IDecompiler.getBytes(node);
throw new LoaderException("Failed to load '" + internalName + "'");
}
protected static final String TAB = " ";
protected static final String NEWLINE = "\n";
protected int indentationCount = 0;
protected StringBuilder sb = new StringBuilder();
@Override
public String toString() {
@@ -3,6 +3,7 @@ package me.ByteEdit.decompiler;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.Map;
import org.objectweb.asm.tree.ClassNode;
@@ -19,11 +20,11 @@ import com.strobel.decompiler.PlainTextOutput;
public class ProcyonDecompiler implements IDecompiler {
@Override
public String decompile(ClassNode cn) {
return doDecompilation(cn, getBytes(cn));
public String decompile(ClassNode cn, Map<String, ClassNode> classNodes) {
return doDecompilation(cn, IDecompiler.getBytes(cn), classNodes);
}
private static String doDecompilation(ClassNode cn, byte[] b) {
private static String doDecompilation(ClassNode cn, byte[] b, Map<String, ClassNode> classNodes) {
try {
// TODO decompile method only
DecompilerSettings settings = new DecompilerSettings();
@@ -48,6 +49,16 @@ public class ProcyonDecompiler implements IDecompiler {
buffer.position(0);
return true;
}
ClassNode node;
synchronized (classNodes) {
node = classNodes.get(s);
}
if (node != null) {
byte[] data = IDecompiler.getBytes(node);
buffer.putByteArray(data, 0, data.length);
buffer.position(0);
return true;
}
return backLoader.tryLoadType(s, buffer);
}
});
+9 -25
View File
@@ -4,6 +4,7 @@ import java.io.BufferedReader;
import java.io.StringReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
@@ -573,7 +574,9 @@ public class Assembler {
String value = split2[1];
if (value.endsWith("]"))
value = value.substring(0, value.length() - 1);
if (value.startsWith("{ ")) {
if (value.equals("{ }")) {
node.values.add(Collections.EMPTY_LIST);
} else if (value.startsWith("{ ")) {
String split3[] = splitWithStrings(value.substring(2, value.length() - 2));
List<Object> list = new ArrayList<>();
for (String rofl : split3) {
@@ -771,14 +774,8 @@ public class Assembler {
String str = consolidateStrings(split, 1);
Object val;
try {
if (str.startsWith("Type: ")) {
str = str.substring(8, str.length() - 2);
String[] split2 = str.split("\n\t");
String type = split2[0].substring(7);
// Reflection
val = new Type(ClassUtil.getIDFromClassNameForType(type),
UnicodeUtils.unescape(hsr, split2[3].substring(6, split2[3].length() - 1)),
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)));
if (str.startsWith("Type ")) {
val = Type.getType(UnicodeUtils.unescape(hsr, str.substring(6, str.length() - 1), true));
} else if (str.startsWith("\"") && str.endsWith("\"")) {
val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1), true);
} else if (str.startsWith("#")) {
@@ -1456,17 +1453,7 @@ public class Assembler {
for (int i = 10; i < sp.length - 1; i++) {
String st = sp[i].substring(1);
if (st.equals("]")) {
if (stage == 1) {
try {
// Reflection
args.add(new Type(ClassUtil.getIDFromClassNameForType(vals.get(0).substring(6)),
UnicodeUtils.unescape(hsr, vals.get(3).substring(6, vals.get(3).length() - 1)),
Integer.parseInt(vals.get(1).substring(7)),
Integer.parseInt(vals.get(2).substring(5))));
} catch (Exception e) {
throw e;
}
} else if (stage == 2) {
if (stage == 2) {
args.add(new Handle(OpcodesReverse.getHandleOpcode(vals.get(4).substring(5)),
UnicodeUtils.unescape(hsr, vals.get(1).substring(7)),
UnicodeUtils.unescape(hsr, vals.get(0).substring(6)),
@@ -1475,11 +1462,8 @@ public class Assembler {
vals.clear();
}
stage = 0;
} else if (st.equals("Type: [")) {
stage = 1;
} else if (stage == 1) {
st = st.substring(1);
vals.add(st);
} else if (st.startsWith("Type ")) {
args.add(Type.getType(UnicodeUtils.unescape(hsr, st.substring(6, st.length() - 1), true)));
} else if (st.equals("Handle: [")) {
vals.clear();
stage = 2;
+27 -21
View File
@@ -21,6 +21,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -69,8 +71,21 @@ public class Disassembler implements IDecompiler {
.newFixedThreadPool((Runtime.getRuntime().availableProcessors() + 1) / 2);
@Override
public String decompile(ClassNode cn) {
return disassemble(cn);
public String decompile(ClassNode cn, Map<String, ClassNode> classNodes) {
String name = cn.name;
StringBuilder dis = new StringBuilder(disassemble(cn));
synchronized (classNodes) {
for (Entry<String, ClassNode> entry : classNodes.entrySet()) {
if (entry.getKey().contains("$")) {
String[] split = entry.getKey().split("\\$");
if (split[0].equals(name)) {
dis.append('\n');
dis.append(disassemble(entry.getValue()));
}
}
}
}
return dis.toString();
}
private static String disassemble(ClassNode classNode) {
@@ -187,8 +202,12 @@ public class Disassembler implements IDecompiler {
}
s += ", ";
}
if (s.endsWith(", ")) {
s = s.substring(0, s.length() - 2);
s += " }], ";
} else {
s += "}], ";
}
} else if (o instanceof String) {
s += "\"" + UnicodeUtils.escapeWithSpaces(hs, (String) o) + "\"], ";
} else {
@@ -292,6 +311,7 @@ public class Disassembler implements IDecompiler {
InsnList insnList = mn.instructions;
boolean deobfNumbers = Main.INSTANCE.mntmNumbers.isSelected();
boolean deobfNops = Main.INSTANCE.mntmNops.isSelected();
ArrayList<Label> labelsReversed = deobfNumbers ? new ArrayList<>() : null;
@@ -343,6 +363,8 @@ public class Disassembler implements IDecompiler {
StringContext ctx = new StringContext(insnList.size());
for (AbstractInsnNode n = insnList.getFirst(); n != null; n = n.getNext()) {
if (deobfNops && n.getOpcode() == Opcodes.NOP)
continue;
ctx.next(disassembleInstruction(n, labels, hs));
}
return new String[] { ctx.finish(), localVarTable, tryCatchTable };
@@ -394,15 +416,7 @@ public class Disassembler implements IDecompiler {
+ "\n\t\t\t]\n\t\t\targs: [\n";
for (Object l : node.bsmArgs) {
if (l instanceof Type) {
Type type = (Type) l;
int valueBegin = type.valueBegin;
int valueEnd = type.valueEnd;
String buf = type.valueBuffer;
// Reflection
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type)
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
+ ClassUtil.getDecompiledValue(buf, "", hs);
s += "\n\t\t\t\t]\n";
s += "\t\t\t\tType " + ClassUtil.getDecompiledValue(((Type) l).getDescriptor(), "", hs) + "\n";
} else if (l instanceof Handle) {
Handle h = (Handle) l;
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: "
@@ -431,16 +445,8 @@ public class Disassembler implements IDecompiler {
case LDC_INSN: {
LdcInsnNode node = (LdcInsnNode) n;
if (node.cst instanceof Type) {
Type type = (Type) node.cst;
int valueBegin = type.valueBegin;
int valueEnd = type.valueEnd;
String buf = type.valueBuffer;
// Reflection
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: "
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "", hs);
s += "\n\t\t]\n";
return s;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type "
+ ClassUtil.getDecompiledValue(((Type) node.cst).getDescriptor(), "", hs) + "\n";
}
String decomp = ClassUtil.getDecompiledValue(node.cst, "", hs);
if (node.cst instanceof String) {
@@ -580,8 +580,10 @@ public class StackBasedCalculator implements Opcodes, Runnable {
change(node);
return false;
case POP2:
Number val = stack.pop();
if (!(val instanceof Long) && !(val instanceof Double)) {
stack.pop();
stack.pop();
}
change(node);
return false;
case SWAP: {
+3 -3
View File
@@ -40,7 +40,7 @@ public class ArchiveTreeModel extends DefaultTreeModel {
super(new ByteEditTreeNode(jar.getName().split(File.separator.equals("\\") ? "\\\\"
: File.separator)[jar.getName().split(File.separator.equals("\\") ? "\\\\" : File.separator).length
- 1]));
this.newCreated = true;
this.newCreated = false;
this.jar = jar;
this.classNodes = classNodes;
this.otherFiles = otherFiles;
@@ -61,7 +61,7 @@ public class ArchiveTreeModel extends DefaultTreeModel {
ClassReader reader = new ClassReader(data);
ClassNode node = new ClassNode();
reader.accept(node, 0);
classNodes.put(Main.getFullName(node.name), node);
classNodes.put(node.name, node);
if ((next.getName().contains("/")
? (!Main.patternSlash
@@ -70,7 +70,7 @@ public class ArchiveTreeModel extends DefaultTreeModel {
: (!next.getName().contains("$")))
|| (next.getName().startsWith("$") || next.getName().contains("$$")
|| next.getName().endsWith("$"))) {
paths.add(Main.getFullName(node.name));
paths.add(node.name + ".class");
}
} catch (Exception e) {
otherFiles.put(next.getName(), data);
+16 -29
View File
@@ -89,6 +89,7 @@ import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.OpcodesReverse;
import me.ByteEdit.utils.UnicodeUtils;
// ASM 9.2
public class Main extends JFrame {
public static Main INSTANCE;
@@ -142,7 +143,7 @@ public class Main extends JFrame {
private JMenuItem rdbtnmntm10000;
public JCheckBoxMenuItem mntmMultithreaded;
private JMenu mnDeobfuscation;
public JCheckBoxMenuItem mntmNumbers;
public JCheckBoxMenuItem mntmNumbers, mntmNops;
public static final Object treeLock = new Object();
@@ -425,6 +426,9 @@ public class Main extends JFrame {
mntmNumbers = new JCheckBoxMenuItem("Numbers");
mnDeobfuscation.add(mntmNumbers);
mntmNops = new JCheckBoxMenuItem("Nops");
mnDeobfuscation.add(mntmNops);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
@@ -483,19 +487,19 @@ public class Main extends JFrame {
String s = ((ByteEditTreeNode) tree.getSelectionPath().getLastPathComponent()).path;
if (JOptionPane.showConfirmDialog(INSTANCE, "Do you want to delete\n\"" + s + "\"?", "Delete",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
String substr = s.substring(0, s.length() - 6);
s = s.substring(0, s.length() - 6);
ArrayList<String> toRemove = new ArrayList<>();
for (String key : Main.classNodes.keySet()) {
if (key.contains("$")) {
String[] split = key.split("\\$");
if (split[0].equals(substr)) {
if (split[0].equals(s)) {
toRemove.add(key);
}
}
}
ArchiveTreeModel model = (ArchiveTreeModel) tree.getModel();
classNodes.remove(s);
model.paths.remove(s);
model.paths.remove(s + ".class");
for (String rem : toRemove) {
classNodes.remove(rem);
}
@@ -757,15 +761,15 @@ public class Main extends JFrame {
if (node == null) {
continue;
}
if (classNodes.replace(getFullName(node.name), node) == null) {
classNodes.put(getFullName(node.name), node);
if (classNodes.replace(node.name, node) == null) {
classNodes.put(node.name, node);
ArchiveTreeModel model;
if (tree.getModel().getClass().equals(DefaultTreeModel.class)) {
tree.setModel(model = new ArchiveTreeModel(classNodes, otherFiles));
} else {
model = (ArchiveTreeModel) tree.getModel();
}
String name = getFullName(node.name);
String name = node.name + ".class";
if (name.contains("/") ? (!name.split("/")[name.split("/").length - 1].contains("$"))
: (!name.contains("$"))) {
model.paths.add(name);
@@ -786,23 +790,11 @@ public class Main extends JFrame {
String current = currentNodeName;
ClassNode classNode = classNodes.get(current);
int prev = txtByteEditView.getCaretPosition();
String dis = decompiler.getDecompiler().decompile(classNode);
String substr = current.substring(0, current.length() - 6);
synchronized (Main.classNodes) {
for (Entry<String, ClassNode> entry : Main.classNodes.entrySet()) {
if (entry.getKey().contains("$")) {
String[] split = entry.getKey().split("\\$");
if (split[0].equals(substr)) {
dis += "\n" + decompiler.getDecompiler().decompile(entry.getValue());
}
}
}
}
String fdis = dis;
String dis = decompiler.getDecompiler().decompile(classNode, Main.classNodes);
EventQueue.invokeAndWait(() -> {
synchronized (treeLock) {
txtByteEditView.setText(fdis);
if (fdis.length() > prev)
txtByteEditView.setText(dis);
if (dis.length() > prev)
txtByteEditView.setCaretPosition(prev);
}
});
@@ -813,6 +805,7 @@ public class Main extends JFrame {
public static void selectFile(String s) {
if (s != null && s.endsWith(".class")) {
s = s.substring(0, s.length() - 6);
currentNodeName = s;
decompileCurrentNode();
txtByteEditView.setCaretPosition(0);
@@ -867,11 +860,9 @@ public class Main extends JFrame {
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
synchronized (treeLock) {
isChangingFile = false;
Main.this.setTitle("ByteEdit");
}
}
});
} catch (Exception e) {
e.printStackTrace();
@@ -929,7 +920,7 @@ public class Main extends JFrame {
for (ClassNode node : classes) {
ClassWriter writer = new ClassWriter(computeFlags);
node.accept(writer);
output.putNextEntry(new ZipEntry(getFullName(node.name)));
output.putNextEntry(new ZipEntry(node.name + ".class"));
output.write(writer.toByteArray());
output.closeEntry();
}
@@ -955,8 +946,4 @@ public class Main extends JFrame {
public static void showError(String s) {
JOptionPane.showMessageDialog(INSTANCE, s, "Error!", JOptionPane.ERROR_MESSAGE);
}
public static String getFullName(String s) {
return s + ".class";
}
}