5 Commits
Author SHA1 Message Date
SuspiciousActivity ac247a89ca Fixed number deobfuscator 2020-11-27 01:01:30 +01:00
SuspiciousActivity b5e4847be5 Added number deobfuscator 2020-11-27 00:07:03 +01:00
SuspiciousActivity 30c9c81d38 Fixed crash 2020-11-26 17:07:36 +01:00
SuspiciousActivity 65235c6b5b ToolTips for #... 2020-11-26 15:52:35 +01:00
SuspiciousActivity d8096a4ec5 Fixes and improvements 2020-11-25 23:53:58 +01:00
6 changed files with 1756 additions and 876 deletions

No files matched your search

+8 -12
View File
@@ -53,7 +53,7 @@ import me.ByteEdit.utils.UnicodeUtils;
public class Assembler {
private static final Pattern SPACE = Pattern.compile(" ");
public static final Pattern SPACE = Pattern.compile(" ");
public static ClassNode assemble(String input) {
Main.txtByteEditView.removeAllLineHighlights();
@@ -691,11 +691,8 @@ public class Assembler {
int frameType = ClassUtil.getFrameTypeByName(asd);
if (frameType != -1)
arr.add(new Integer(frameType));
else {
String frame = UnicodeUtils.unescape(hsr, asd);
frame = frame.substring(1, frame.length() - 1);
arr.add(frame);
}
else
arr.add(UnicodeUtils.unescape(hsr, asd.substring(1, asd.length() - 1)));
} else {
if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]);
@@ -737,11 +734,8 @@ public class Assembler {
int frameType = ClassUtil.getFrameTypeByName(asd);
if (frameType != -1)
arr.add(new Integer(frameType));
else {
String frame = UnicodeUtils.unescape(hsr, asd);
frame = frame.substring(1, frame.length() - 1);
arr.add(frame);
}
else
arr.add(UnicodeUtils.unescape(hsr, asd.substring(1, asd.length() - 1)));
} else {
if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]);
@@ -847,7 +841,9 @@ public class Assembler {
UnicodeUtils.unescape(hsr, split2[3].substring(6, split2[3].length() - 1)),
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)));
} else if (str.startsWith("\"") && str.endsWith("\"")) {
val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1));
val = UnicodeUtils.unescape(hsr, str.substring(1, str.length() - 1), true);
} else if (str.startsWith("#")) {
val = UnicodeUtils.unescape(hsr, str);
} else if (str.endsWith("l")) {
val = Long.parseLong(str.substring(0, str.length() - 1));
} else if (str.endsWith("f")) {
+43 -9
View File
@@ -9,6 +9,7 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicInteger;
import org.objectweb.asm.Handle;
@@ -23,6 +24,7 @@ import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
@@ -40,6 +42,7 @@ import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import me.ByteEdit.main.Main;
import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.OpcodesReverse;
import me.ByteEdit.utils.UnicodeUtils;
@@ -215,10 +218,11 @@ public class Disassembler {
private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind,
AtomicInteger lineFound, HugeStrings hs) throws InterruptedException, ExecutionException {
boolean multithreaded = Main.INSTANCE.mntmMultithreaded.isSelected();
Future<String>[] futures = new Future[methods.size()];
for (int i = 0; i < futures.length; i++) {
MethodNode mn = methods.get(i);
futures[i] = exec.submit(new Callable<String>() {
Callable<String> callable = new Callable<String>() {
@Override
public String call() throws Exception {
String ms = "";
@@ -318,10 +322,13 @@ public class Disassembler {
}
return ms;
}
});
};
futures[i] = multithreaded ? exec.submit(callable) : new FutureTask<>(callable);
}
StringContext ctx = new StringContext(futures.length);
for (Future<String> f : futures) {
if (f instanceof FutureTask)
((FutureTask) f).run();
ctx.next(f.get());
}
String s = ctx.finish();
@@ -413,9 +420,18 @@ public class Disassembler {
HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
String localVarTable;
String tryCatchTable;
for (AbstractInsnNode n : mn.instructions.toArray()) {
InsnList insnList = mn.instructions;
boolean deobfNumbers = Main.INSTANCE.mntmNumbers.isSelected();
ArrayList<Label> labelsReversed = deobfNumbers ? new ArrayList<>() : null;
for (AbstractInsnNode n = insnList.getFirst(); n != null; n = n.getNext()) {
if (n instanceof LabelNode) {
labels.put(((LabelNode) n).getLabel(), labels.size() + 1);
int id = labels.size() + 1;
if (deobfNumbers)
labelsReversed.add(((LabelNode) n).getLabel());
labels.put(((LabelNode) n).getLabel(), id);
}
}
if (mn.localVariables != null && !mn.localVariables.isEmpty()) {
@@ -443,9 +459,21 @@ public class Disassembler {
tryCatchTable = ctx.finish();
} else
tryCatchTable = "";
AbstractInsnNode[] insns = mn.instructions.toArray();
StringContext ctx = new StringContext(insns.length);
for (AbstractInsnNode n : insns) {
if (deobfNumbers) {
StackBasedCalculator calc = new StackBasedCalculator(insnList);
calc.run();
insnList = calc.get();
int i = 0;
for (AbstractInsnNode n = insnList.getFirst(); n != null; n = n.getNext()) {
if (n instanceof LabelNode) {
((LabelNode) n).setLabel(labelsReversed.get(i++));
}
}
}
StringContext ctx = new StringContext(insnList.size());
for (AbstractInsnNode n = insnList.getFirst(); n != null; n = n.getNext()) {
ctx.next(disassembleInstruction(n, labels, hs));
}
return new String[] { ctx.finish(), localVarTable, tryCatchTable };
@@ -613,8 +641,14 @@ public class Disassembler {
s += "\n\t\t]\n";
return s;
} else {
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
+ ClassUtil.getDecompiledValue(node.cst, "", hs) + "\n";
String decomp = ClassUtil.getDecompiledValue(node.cst, "", hs);
if (node.cst instanceof String) {
if (decomp.startsWith("\"#") && decomp.endsWith("\""))
decomp = decomp.substring(1, decomp.length() - 1);
else if (decomp.startsWith("\"\\u0023"))
decomp = "\"#" + decomp.substring(7);
}
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + decomp + "\n";
}
});
iiMap.put(VarInsnNode.class, (n, labels, hs) -> {
+1 -1
View File
@@ -8,7 +8,7 @@ import me.ByteEdit.utils.UnicodeUtils;
public class HugeStrings {
public static final int THRESHOLD = 1000;
public static int THRESHOLD = 1000;
private final HashMap<String, HugeData> map = new HashMap<>();
public String onString(String s) {
@@ -0,0 +1,693 @@
package me.ByteEdit.edit;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Stack;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
public class StackBasedCalculator implements Opcodes, Runnable {
private final InsnList insns;
private final Stack<Number> stack = new Stack<>();
private AbstractInsnNode start;
private int startIdx = -1;
private boolean isAtEnd = false;
public StackBasedCalculator(InsnList insns) {
this.insns = new InsnList();
HashMap<LabelNode, LabelNode> labelMap = new HashMap<>();
for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext()) {
if (node.getType() == 8) {
labelMap.put((LabelNode) node, new LabelNode());
}
}
for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext()) {
this.insns.add(node.clone(labelMap));
}
}
public InsnList get() {
return insns;
}
@Override
public void run() {
while (!isAtEnd) {
out: {
AbstractInsnNode[] arr = insns.toArray();
for (int i = startIdx == -1 ? 0 : startIdx; i < arr.length; i++) {
if (!handle(arr[i]))
break out;
}
isAtEnd = true;
}
}
}
private boolean handle(AbstractInsnNode node) {
try {
switch (node.getOpcode()) {
case ICONST_0:
stack.push(Integer.valueOf(0));
if (start == null)
start = node;
break;
case ICONST_1:
stack.push(Integer.valueOf(1));
if (start == null)
start = node;
break;
case ICONST_2:
stack.push(Integer.valueOf(2));
if (start == null)
start = node;
break;
case ICONST_3:
stack.push(Integer.valueOf(3));
if (start == null)
start = node;
break;
case ICONST_4:
stack.push(Integer.valueOf(4));
if (start == null)
start = node;
break;
case ICONST_5:
stack.push(Integer.valueOf(5));
if (start == null)
start = node;
break;
case ICONST_M1:
stack.push(Integer.valueOf(-1));
if (start == null)
start = node;
break;
case DCONST_0:
stack.push(Double.valueOf(0));
if (start == null)
start = node;
break;
case DCONST_1:
stack.push(Double.valueOf(1));
if (start == null)
start = node;
break;
case FCONST_0:
stack.push(Float.valueOf(0));
if (start == null)
start = node;
break;
case FCONST_1:
stack.push(Float.valueOf(1));
if (start == null)
start = node;
break;
case FCONST_2:
stack.push(Float.valueOf(2));
if (start == null)
start = node;
break;
case LCONST_0:
stack.push(Long.valueOf(0));
if (start == null)
start = node;
break;
case LCONST_1:
stack.push(Long.valueOf(1));
if (start == null)
start = node;
break;
case BIPUSH:
case SIPUSH:
stack.push(((IntInsnNode) node).operand);
if (start == null)
start = node;
break;
case D2F:
stack.push(((Double) stack.pop()).floatValue());
change(node);
return false;
case D2I:
stack.push(((Double) stack.pop()).intValue());
change(node);
return false;
case D2L:
stack.push(((Double) stack.pop()).longValue());
change(node);
return false;
case F2D:
stack.push(((Float) stack.pop()).doubleValue());
change(node);
return false;
case F2I:
stack.push(((Float) stack.pop()).intValue());
change(node);
return false;
case F2L:
stack.push(((Float) stack.pop()).longValue());
change(node);
return false;
case L2D:
stack.push(((Long) stack.pop()).doubleValue());
change(node);
return false;
case L2F:
stack.push(((Long) stack.pop()).floatValue());
change(node);
return false;
case L2I:
stack.push(((Long) stack.pop()).intValue());
change(node);
return false;
case I2B:
error(node);
return true;
case I2C:
error(node);
return true;
case I2D:
stack.push(((Integer) stack.pop()).doubleValue());
change(node);
return false;
case I2F:
stack.push(((Integer) stack.pop()).floatValue());
change(node);
return false;
case I2L:
stack.push(((Integer) stack.pop()).longValue());
change(node);
return false;
case I2S:
error(node);
return true;
case NOP:
break;
case LDC:
LdcInsnNode ldc = (LdcInsnNode) node;
if (ldc.cst instanceof Number) {
stack.push((Number) ldc.cst);
if (start == null)
start = node;
} else {
error(node);
return true;
}
break;
// long
case LADD: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom + top);
change(node);
return false;
}
case LSUB: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom - top);
change(node);
return false;
}
case LMUL: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom * top);
change(node);
return false;
}
case LDIV: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom / top);
change(node);
return false;
}
case LREM: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom % top);
change(node);
return false;
}
case LNEG: {
long top = ((Long) stack.pop()).longValue();
stack.push(-top);
change(node);
return false;
}
case LAND: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom & top);
change(node);
return false;
}
case LOR: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom | top);
change(node);
return false;
}
case LXOR: {
long top = ((Long) stack.pop()).longValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom ^ top);
change(node);
return false;
}
case LSHR: {
int top = ((Integer) stack.pop()).intValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom >> top);
change(node);
return false;
}
case LSHL: {
int top = ((Integer) stack.pop()).intValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom << top);
change(node);
return false;
}
case LUSHR: {
int top = ((Integer) stack.pop()).intValue();
long bottom = ((Long) stack.pop()).longValue();
stack.push(bottom >>> top);
change(node);
return false;
}
// int
case IADD: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom + top);
change(node);
return false;
}
case ISUB: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom - top);
change(node);
return false;
}
case IMUL: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom * top);
change(node);
return false;
}
case IDIV: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom / top);
change(node);
return false;
}
case IREM: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom % top);
change(node);
return false;
}
case INEG: {
int top = ((Integer) stack.pop()).intValue();
stack.push(-top);
change(node);
return false;
}
case IAND: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom & top);
change(node);
return false;
}
case IOR: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom | top);
change(node);
return false;
}
case IXOR: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom ^ top);
change(node);
return false;
}
case ISHR: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom >> top);
change(node);
return false;
}
case ISHL: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom << top);
change(node);
return false;
}
case IUSHR: {
int top = ((Integer) stack.pop()).intValue();
int bottom = ((Integer) stack.pop()).intValue();
stack.push(bottom >>> top);
change(node);
return false;
}
// double
case DADD: {
double top = ((Double) stack.pop()).doubleValue();
double bottom = ((Double) stack.pop()).doubleValue();
stack.push(bottom + top);
change(node);
return false;
}
case DSUB: {
double top = ((Double) stack.pop()).doubleValue();
double bottom = ((Double) stack.pop()).doubleValue();
stack.push(bottom - top);
change(node);
return false;
}
case DMUL: {
double top = ((Double) stack.pop()).doubleValue();
double bottom = ((Double) stack.pop()).doubleValue();
stack.push(bottom * top);
change(node);
return false;
}
case DDIV: {
double top = ((Double) stack.pop()).doubleValue();
double bottom = ((Double) stack.pop()).doubleValue();
stack.push(bottom / top);
change(node);
return false;
}
case DREM: {
double top = ((Double) stack.pop()).doubleValue();
double bottom = ((Double) stack.pop()).doubleValue();
stack.push(bottom % top);
change(node);
return false;
}
case DNEG: {
double top = ((Double) stack.pop()).doubleValue();
stack.push(-top);
change(node);
return false;
}
// float
case FADD: {
float top = ((Float) stack.pop()).floatValue();
float bottom = ((Float) stack.pop()).floatValue();
stack.push(bottom + top);
change(node);
return false;
}
case FSUB: {
float top = ((Float) stack.pop()).floatValue();
float bottom = ((Float) stack.pop()).floatValue();
stack.push(bottom - top);
change(node);
return false;
}
case FMUL: {
float top = ((Float) stack.pop()).floatValue();
float bottom = ((Float) stack.pop()).floatValue();
stack.push(bottom * top);
change(node);
return false;
}
case FDIV: {
float top = ((Float) stack.pop()).floatValue();
float bottom = ((Float) stack.pop()).floatValue();
stack.push(bottom / top);
change(node);
return false;
}
case FREM: {
float top = ((Float) stack.pop()).floatValue();
float bottom = ((Float) stack.pop()).floatValue();
stack.push(bottom % top);
change(node);
return false;
}
case FNEG: {
float top = ((Float) stack.pop()).floatValue();
stack.push(-top);
change(node);
return false;
}
// dup
case DUP: {
Number num = stack.pop();
if (num instanceof Double || num instanceof Long) {
error(node);
return true;
}
stack.push(num);
stack.push(num);
change(node);
return false;
}
case DUP_X1: {
Number top = stack.pop();
Number bottom = stack.pop();
if (bottom instanceof Double || bottom instanceof Long || top instanceof Double
|| top instanceof Long) {
error(node);
return true;
}
stack.push(top);
stack.push(bottom);
stack.push(top);
change(node);
return false;
}
case DUP_X2: {
Number top = stack.pop();
Number bottom = stack.pop();
if (top instanceof Double || top instanceof Long) {
error(node);
return true;
}
Number bottom2 = null;
if (!(bottom instanceof Double || bottom instanceof Long)) {
bottom2 = stack.pop();
if (bottom instanceof Double || bottom instanceof Long) {
error(node);
return true;
}
}
stack.push(top);
if (bottom2 != null)
stack.push(bottom2);
stack.push(bottom);
stack.push(top);
change(node);
return false;
}
case DUP2: {
Number top = stack.pop();
Number bottom = null;
if (!(top instanceof Double || top instanceof Long)) {
bottom = stack.pop();
if (bottom instanceof Double || bottom instanceof Long) {
error(node);
return true;
}
}
if (bottom != null)
stack.push(bottom);
stack.push(top);
if (bottom != null)
stack.push(bottom);
stack.push(top);
change(node);
return false;
}
case DUP2_X1: {
Number top = stack.pop();
Number bottom = null;
if (!(top instanceof Double || top instanceof Long)) {
bottom = stack.pop();
if (bottom instanceof Double || bottom instanceof Long) {
error(node);
return true;
}
}
Number bottom2 = stack.pop();
if (bottom != null)
stack.push(bottom);
stack.push(top);
stack.push(bottom2);
if (bottom != null)
stack.push(bottom);
stack.push(top);
change(node);
return false;
}
case DUP2_X2: {
Number top = stack.pop();
Number bottom = null;
if (!(top instanceof Double || top instanceof Long)) {
bottom = stack.pop();
if (bottom instanceof Double || bottom instanceof Long) {
error(node);
return true;
}
}
Number top2 = stack.pop();
Number bottom2 = null;
if (!(top2 instanceof Double || top2 instanceof Long)) {
bottom2 = stack.pop();
if (bottom2 instanceof Double || bottom2 instanceof Long) {
error(node);
return true;
}
}
if (bottom != null)
stack.push(bottom);
stack.push(top);
if (bottom2 != null)
stack.push(bottom2);
stack.push(top2);
if (bottom != null)
stack.push(bottom);
stack.push(top);
change(node);
return false;
}
// stack
case POP:
stack.pop();
change(node);
return false;
case POP2:
stack.pop();
stack.pop();
change(node);
return false;
case SWAP: {
Number top = stack.pop();
Number bottom = stack.pop();
if (bottom instanceof Double || bottom instanceof Long || top instanceof Double
|| top instanceof Long) {
error(node);
return true;
}
stack.push(top);
stack.push(bottom);
change(node);
return false;
}
default:
error(node);
return true;
}
} catch (ClassCastException | EmptyStackException ex) {
error(node);
return true;
}
return true;
}
private void error(AbstractInsnNode node) {
change(node.getPrevious());
stack.clear();
start = null;
}
private void change(AbstractInsnNode node) {
if (start == null)
return;
int idx = insns.indexOf(start);
startIdx = idx;
int idx2 = insns.indexOf(node);
if (idx != idx2) {
for (int i = 0; i <= idx2 - idx; i++) {
insns.remove(insns.get(idx));
}
while (!stack.isEmpty()) {
addNode(idx, stack.pop());
}
}
stack.clear();
start = null;
}
private void addNode(int idx, Number n) {
if (n instanceof Double) {
double val = n.doubleValue();
if (val == 0.0)
insns.insertBefore(insns.get(idx), new InsnNode(DCONST_0));
else if (val == 1.0)
insns.insertBefore(insns.get(idx), new InsnNode(DCONST_1));
else
insns.insertBefore(insns.get(idx), new LdcInsnNode(val));
} else if (n instanceof Float) {
float val = n.floatValue();
if (val == 0.0f)
insns.insertBefore(insns.get(idx), new InsnNode(FCONST_0));
else if (val == 1.0f)
insns.insertBefore(insns.get(idx), new InsnNode(FCONST_1));
else if (val == 2.0f)
insns.insertBefore(insns.get(idx), new InsnNode(FCONST_2));
else
insns.insertBefore(insns.get(idx), new LdcInsnNode(val));
} else if (n instanceof Long) {
long val = n.longValue();
if (val == 0l)
insns.insertBefore(insns.get(idx), new InsnNode(LCONST_0));
else if (val == 1l)
insns.insertBefore(insns.get(idx), new InsnNode(LCONST_1));
else
insns.insertBefore(insns.get(idx), new LdcInsnNode(val));
} else if (n instanceof Integer) {
int val = n.intValue();
if (val == 0)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_0));
else if (val == 1)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_1));
else if (val == 2)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_2));
else if (val == 3)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_3));
else if (val == 4)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_4));
else if (val == 5)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_5));
else if (val == -1)
insns.insertBefore(insns.get(idx), new InsnNode(ICONST_M1));
else
insns.insertBefore(insns.get(idx), new LdcInsnNode(val));
} else if (n instanceof Long) {
long val = n.longValue();
if (val == 0l)
insns.insertBefore(insns.get(idx), new InsnNode(LCONST_0));
else if (val == 1l)
insns.insertBefore(insns.get(idx), new InsnNode(LCONST_1));
else
insns.insertBefore(insns.get(idx), new LdcInsnNode(val));
} else {
throw new RuntimeException("Unexpected number: " + n);
}
}
}
+173 -26
View File
@@ -17,11 +17,14 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -37,6 +40,8 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
@@ -46,6 +51,7 @@ 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;
@@ -72,7 +78,9 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.folding.CurlyFoldParser;
import org.fife.ui.rsyntaxtextarea.folding.FoldParserManager;
import org.fife.ui.rtextarea.RTextArea;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextarea.ToolTipSupplier;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@@ -81,7 +89,6 @@ import org.objectweb.asm.tree.MethodNode;
import me.ByteEdit.boxes.CompilationBox;
import me.ByteEdit.boxes.GlobalSearchBox;
import me.ByteEdit.boxes.OptionBox;
import me.ByteEdit.boxes.RenameBox;
import me.ByteEdit.boxes.SearchBox;
import me.ByteEdit.boxes.ThemeBox;
@@ -90,6 +97,7 @@ import me.ByteEdit.boxes.UnicodeBox;
import me.ByteEdit.edit.Assembler;
import me.ByteEdit.edit.Disassembler;
import me.ByteEdit.edit.Disassembler.DisassembleTuple;
import me.ByteEdit.edit.HugeStrings;
import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.OpcodesReverse;
import me.ByteEdit.utils.UnicodeUtils;
@@ -107,7 +115,6 @@ public class Main extends JFrame {
public static GlobalSearchBox globalSearchBox;
public static SearchBox searchBox;
public static TypeOpenBox typeOpenBox;
public static OptionBox optionBox;
public static UnicodeBox unicodeBox;
public static RenameBox renameBox;
public static CompilationBox compilationBox;
@@ -116,6 +123,34 @@ public class Main extends JFrame {
public static RTextScrollPane scrollPane_ByteEdit;
public static File saveFolder;
private static final Pattern SLASH = Pattern.compile("/");
private JMenuBar menuBar;
private JMenu mnFile;
private JMenuItem mntmOpenJar;
private JMenuItem mntmSaveBytecode;
private JMenuItem mntmSaveJar;
private JMenu mnWindow;
private JMenuItem mntmThemes;
private JMenuItem mntmSearchMembers;
private JMenuItem mntmSearch;
private JMenuItem mntmOpenType;
private JMenuItem mntmUnicode;
private JMenuItem mntmCompiler;
private JMenu mnSearch;
private JMenu mnOptions;
private JCheckBoxMenuItem mntmComputeFrames;
private JCheckBoxMenuItem mntmComputeMax;
private JMenu mnStringLimit;
private JRadioButtonMenuItem rdbtnmntm0;
private JMenuItem rdbtnmntm100;
private JMenuItem rdbtnmntm1000;
private JMenuItem rdbtnmntm500;
private JMenuItem rdbtnmntm5000;
private JMenuItem rdbtnmntm10000;
public JCheckBoxMenuItem mntmMultithreaded;
private JMenu mnDeobfuscation;
public JCheckBoxMenuItem mntmNumbers;
public static final Object treeLock = new Object();
/**
@@ -209,7 +244,6 @@ public class Main extends JFrame {
globalSearchBox = new GlobalSearchBox();
searchBox = new SearchBox();
typeOpenBox = new TypeOpenBox();
optionBox = new OptionBox();
unicodeBox = new UnicodeBox();
renameBox = new RenameBox();
compilationBox = new CompilationBox();
@@ -217,7 +251,6 @@ public class Main extends JFrame {
ThemeManager.registerFrames(globalSearchBox);
ThemeManager.registerFrames(searchBox);
ThemeManager.registerFrames(typeOpenBox);
ThemeManager.registerFrames(optionBox);
ThemeManager.registerFrames(unicodeBox);
ThemeManager.registerFrames(renameBox);
ThemeManager.registerFrames(compilationBox);
@@ -278,7 +311,6 @@ public class Main extends JFrame {
globalSearchBox.setVisible(false);
searchBox.setVisible(false);
typeOpenBox.setVisible(false);
optionBox.setVisible(false);
unicodeBox.setVisible(false);
renameBox.setVisible(false);
compilationBox.setVisible(false);
@@ -336,6 +368,62 @@ public class Main extends JFrame {
mntmCompiler = new JMenuItem("Compiler");
mntmCompiler.addActionListener(e -> compilationBox.setVisible(true));
mnWindow.add(mntmCompiler);
mnOptions = new JMenu("Options");
menuBar.add(mnOptions);
mntmComputeFrames = new JCheckBoxMenuItem("Compute Frames");
mnOptions.add(mntmComputeFrames);
mntmComputeMax = new JCheckBoxMenuItem("Compute Max");
mnOptions.add(mntmComputeMax);
mntmMultithreaded = new JCheckBoxMenuItem("Multithreaded");
mntmMultithreaded.setSelected(true);
mnOptions.add(mntmMultithreaded);
mnStringLimit = new JMenu("Huge String Limit");
mnOptions.add(mnStringLimit);
rdbtnmntm0 = new JRadioButtonMenuItem("0");
rdbtnmntm0.addActionListener(e -> HugeStrings.THRESHOLD = 0);
mnStringLimit.add(rdbtnmntm0);
rdbtnmntm100 = new JRadioButtonMenuItem("100");
rdbtnmntm100.addActionListener(e -> HugeStrings.THRESHOLD = 100);
mnStringLimit.add(rdbtnmntm100);
rdbtnmntm500 = new JRadioButtonMenuItem("500");
rdbtnmntm500.addActionListener(e -> HugeStrings.THRESHOLD = 500);
mnStringLimit.add(rdbtnmntm500);
rdbtnmntm1000 = new JRadioButtonMenuItem("1000");
rdbtnmntm1000.addActionListener(e -> HugeStrings.THRESHOLD = 1000);
rdbtnmntm1000.setSelected(true);
mnStringLimit.add(rdbtnmntm1000);
rdbtnmntm5000 = new JRadioButtonMenuItem("5000");
rdbtnmntm5000.addActionListener(e -> HugeStrings.THRESHOLD = 5000);
mnStringLimit.add(rdbtnmntm5000);
rdbtnmntm10000 = new JRadioButtonMenuItem("10000");
rdbtnmntm10000.addActionListener(e -> HugeStrings.THRESHOLD = 10000);
mnStringLimit.add(rdbtnmntm10000);
ButtonGroup group = new ButtonGroup();
group.add(rdbtnmntm0);
group.add(rdbtnmntm100);
group.add(rdbtnmntm500);
group.add(rdbtnmntm1000);
group.add(rdbtnmntm5000);
group.add(rdbtnmntm10000);
mnDeobfuscation = new JMenu("Deobfuscation");
menuBar.add(mnDeobfuscation);
mntmNumbers = new JCheckBoxMenuItem("Numbers");
mnDeobfuscation.add(mntmNumbers);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
@@ -472,7 +560,6 @@ public class Main extends JFrame {
globalSearchBox.setVisible(false);
searchBox.setVisible(false);
typeOpenBox.setVisible(false);
optionBox.setVisible(false);
unicodeBox.setVisible(false);
renameBox.setVisible(false);
compilationBox.setVisible(false);
@@ -520,6 +607,84 @@ public class Main extends JFrame {
txtByteEditView = new RSyntaxTextArea();
ac.install(txtByteEditView);
txtByteEditView.setCodeFoldingEnabled(true);
// ToolTips for HugeStrings
txtByteEditView.setToolTipSupplier(new ToolTipSupplier() {
@Override
public String getToolTipText(RTextArea textArea, MouseEvent e) {
int idx = textArea.viewToModel(e.getPoint());
if (idx < 0)
return null;
int subIdx = Math.max(idx - 15, 0);
int subLen = Math.min(30, textArea.getDocument().getLength() - subIdx);
if (subLen <= 0)
return null;
try {
String cut = textArea.getText(subIdx, subLen);
int hashIdx = -1;
for (int off = idx - subIdx; off >= 0; off--) {
if (cut.charAt(off) == '#') {
hashIdx = off;
break;
}
}
if (hashIdx < 0) {
for (int off = idx - subIdx; off < cut.length(); off++) {
if (cut.charAt(off) == '#') {
hashIdx = off;
break;
}
}
}
if (hashIdx < 0)
return null;
if (hashIdx >= 5 && cut.substring(hashIdx - 5, hashIdx).equals("ldc \"")) // ldc "#..."
return null;
int numLen = 1;
for (int i = hashIdx + 1; i < cut.length(); i++) {
if (!(cut.charAt(i) - '0' >= 0 && cut.charAt(i) - '0' <= 9)) {
break;
}
numLen++;
}
if (numLen < 2 || hashIdx > idx - subIdx || idx - subIdx - numLen >= hashIdx)
return null;
String hashNum = cut.substring(hashIdx, hashIdx + numLen);
String txt = txtByteEditView.getText();
int len = 0;
for (String asm : txt.split("\\/\\/ #Annotations:\n")) {
len += 19; // "\\/\\/ #Annotations:\n".length()
if (asm.isEmpty())
continue;
if (idx >= len && idx < len + asm.length()) {
try (BufferedReader reader = new BufferedReader(new StringReader(asm))) {
String s;
while (!(s = reader.readLine()).startsWith("// #SourceFile: ")) {
}
while (!(s = reader.readLine()).equals("// #Fields")) {
if (s.startsWith("#")) {
String[] split = Assembler.SPACE.split(s, 2);
if (hashNum.equals(split[0].substring(0, split[0].length() - 1))) {
String toolTip = split[1];
if (toolTip.length() > 500)
toolTip = toolTip.substring(0, 500) + "...";
return toolTip;
}
}
}
} catch (IOException e1) {
}
break;
} else {
len += asm.length();
}
}
} catch (BadLocationException e1) {
}
return null;
}
});
txtByteEditView.addKeyListener(new KeyAdapter() {
@Override
@@ -551,7 +716,6 @@ public class Main extends JFrame {
KeyStroke ctrlT = KeyStroke.getKeyStroke(KeyEvent.VK_T, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlS = KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlG = KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlO = KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlU = KeyStroke.getKeyStroke(KeyEvent.VK_U, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlR = KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK);
KeyStroke ctrlE = KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK);
@@ -574,8 +738,6 @@ public class Main extends JFrame {
typeOpenBox.txtSearch.requestFocusInWindow();
typeOpenBox.txtSearch.select(0, typeOpenBox.txtSearch.getText().length());
}, ctrlT, JComponent.WHEN_IN_FOCUSED_WINDOW);
txtByteEditView.registerKeyboardAction(e -> optionBox.setVisible(true), ctrlO,
JComponent.WHEN_IN_FOCUSED_WINDOW);
txtByteEditView.registerKeyboardAction(e -> unicodeBox.setVisible(true), ctrlU,
JComponent.WHEN_IN_FOCUSED_WINDOW);
txtByteEditView.registerKeyboardAction(e -> compilationBox.setVisible(true), ctrlE,
@@ -901,10 +1063,10 @@ public class Main extends JFrame {
output.closeEntry();
}
int computeFlags = 0;
if (optionBox.chckbxComputeFrames.isSelected()) {
if (mntmComputeFrames.isSelected()) {
computeFlags |= ClassWriter.COMPUTE_FRAMES;
}
if (optionBox.chckbxComputeMax.isSelected()) {
if (mntmComputeMax.isSelected()) {
computeFlags |= ClassWriter.COMPUTE_MAXS;
}
for (ClassNode node : classes) {
@@ -941,21 +1103,6 @@ public class Main extends JFrame {
return s + ".class";
}
private static final Pattern SLASH = Pattern.compile("/");
private JMenuBar menuBar;
private JMenu mnFile;
private JMenuItem mntmOpenJar;
private JMenuItem mntmSaveBytecode;
private JMenuItem mntmSaveJar;
private JMenu mnWindow;
private JMenuItem mntmThemes;
private JMenuItem mntmSearchMembers;
private JMenuItem mntmSearch;
private JMenuItem mntmOpenType;
private JMenuItem mntmUnicode;
private JMenuItem mntmCompiler;
private JMenu mnSearch;
class ArchiveTreeModel extends DefaultTreeModel {
public ArrayList<String> paths = new ArrayList<>();
File diff suppressed because it is too large. Load diff