Added full Unicode support (Java style)

This commit is contained in:
SuspiciousActivity committed 2018-09-24 20:41:22 +02:00
1 parent 49337245f0
commit 8400d6eab9
5 files changed
+275 -102

No files matched your search

+61 -48
View File
@@ -13,7 +13,6 @@ import java.util.function.BiFunction;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import org.apache.commons.lang3.StringEscapeUtils;
import org.objectweb.asm.Handle; import org.objectweb.asm.Handle;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -47,6 +46,7 @@ import me.ByteEdit.main.Main;
import me.ByteEdit.utils.ClassUtil; import me.ByteEdit.utils.ClassUtil;
import me.ByteEdit.utils.CustomBufferedReader; import me.ByteEdit.utils.CustomBufferedReader;
import me.ByteEdit.utils.SwitchIntContainer; import me.ByteEdit.utils.SwitchIntContainer;
import me.ByteEdit.utils.UnicodeUtils;
public class Assembler { public class Assembler {
@@ -66,21 +66,22 @@ public class Assembler {
clazz.version = Integer.parseInt(s.substring(12)); clazz.version = Integer.parseInt(s.substring(12));
while ((s = read.readLine()).startsWith("// ")) { while ((s = read.readLine()).startsWith("// ")) {
if (s.startsWith("// #Signature: ")) { if (s.startsWith("// #Signature: ")) {
clazz.signature = s.substring(15).equals("null") ? null : s.substring(15); clazz.signature = s.substring(15).equals("null") ? null : UnicodeUtils.unescape(s.substring(15));
} else if (s.startsWith("// #OuterClass: ")) { } else if (s.startsWith("// #OuterClass: ")) {
clazz.outerClass = s.substring(16).equals("null") ? null : s.substring(16); clazz.outerClass = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16));
} else if (s.startsWith("// #OuterMethod: ")) { } else if (s.startsWith("// #OuterMethod: ")) {
String[] split = s.split(" "); String[] split = s.split(" ");
if (split.length > 3) { if (split.length > 3) {
clazz.outerMethod = split[2]; clazz.outerMethod = UnicodeUtils.unescape(split[2]);
clazz.outerMethodDesc = split[3]; clazz.outerMethodDesc = UnicodeUtils.unescape(split[3]);
} }
} else if (s.equals("// #InnerClasses:")) { } else if (s.equals("// #InnerClasses:")) {
clazz.innerClasses = new ArrayList<>(); clazz.innerClasses = new ArrayList<>();
} else { } else {
String split[] = s.split(" "); String split[] = s.split(" ");
clazz.innerClasses.add(new InnerClassNode(split[1], split[2].equals("null") ? null : split[2], clazz.innerClasses.add(new InnerClassNode(UnicodeUtils.unescape(split[1]),
split[3].equals("null") ? null : split[3], Integer.parseInt(split[4].substring(2), 16))); split[2].equals("null") ? null : UnicodeUtils.unescape(split[2]),
split[3].equals("null") ? null : UnicodeUtils.unescape(split[3]), Integer.parseInt(split[4].substring(2), 16)));
} }
} }
{ {
@@ -89,14 +90,14 @@ public class Assembler {
String interfaces = s.substring(s.lastIndexOf(" implements ") + 12); String interfaces = s.substring(s.lastIndexOf(" implements ") + 12);
clazz.interfaces = new ArrayList<>(); clazz.interfaces = new ArrayList<>();
for (String interf : interfaces.split(", ")) { for (String interf : interfaces.split(", ")) {
clazz.interfaces.add(interf); clazz.interfaces.add(UnicodeUtils.unescape(interf));
} }
s = s.substring(0, s.lastIndexOf(" implements ")); s = s.substring(0, s.lastIndexOf(" implements "));
} }
clazz.superName = s.substring(s.lastIndexOf(" extends ") + 9); clazz.superName = UnicodeUtils.unescape(s.substring(s.lastIndexOf(" extends ") + 9));
s = s.substring(0, s.lastIndexOf(" extends ")); s = s.substring(0, s.lastIndexOf(" extends "));
String[] split = s.split(" "); String[] split = s.split(" ");
clazz.name = split[split.length - 1]; clazz.name = UnicodeUtils.unescape(split[split.length - 1]);
clazz.access = ClassUtil.ACC_SUPER; clazz.access = ClassUtil.ACC_SUPER;
switch (split[split.length - 2]) { switch (split[split.length - 2]) {
case "class": case "class":
@@ -133,7 +134,7 @@ public class Assembler {
} }
} }
s = read.readLine(); s = read.readLine();
clazz.sourceFile = s.substring(16).equals("null") ? null : s.substring(16); clazz.sourceFile = s.substring(16).equals("null") ? null : UnicodeUtils.unescape(s.substring(16));
while (!(s = read.readLine()).equals("// #Fields")) {} while (!(s = read.readLine()).equals("// #Fields")) {}
clazz.fields = new ArrayList<>(); clazz.fields = new ArrayList<>();
clazz.methods = new ArrayList<>(); clazz.methods = new ArrayList<>();
@@ -147,7 +148,7 @@ public class Assembler {
annotationsForNext.add(s); annotationsForNext.add(s);
} else { } else {
if (s.startsWith("// #Signature: ")) { if (s.startsWith("// #Signature: ")) {
signature = s.substring(15); signature = UnicodeUtils.unescape(s.substring(15));
} else { } else {
String[] split = s.split(" "); String[] split = s.split(" ");
boolean hasValue = false; boolean hasValue = false;
@@ -158,8 +159,8 @@ public class Assembler {
if (hasValue) { if (hasValue) {
split = s.substring(0, s.indexOf(" = ")).split(" "); split = s.substring(0, s.indexOf(" = ")).split(" ");
} }
String name = split[split.length - 1]; String name = UnicodeUtils.unescape(split[split.length - 1]);
String desc = split[split.length - 2]; String desc = UnicodeUtils.unescape(split[split.length - 2]);
value = getValue((String) value, desc); value = getValue((String) value, desc);
int access = 0; int access = 0;
if (split.length > 2) { if (split.length > 2) {
@@ -259,7 +260,7 @@ public class Assembler {
tryCatchBlocksToParse.clear(); tryCatchBlocksToParse.clear();
stage = 0; stage = 0;
} else if (s.startsWith("// #Signature: ")) { } else if (s.startsWith("// #Signature: ")) {
node.signature = s.substring(15); node.signature = UnicodeUtils.unescape(s.substring(15));
} else if (s.equals("// #TryCatch:")) { } else if (s.equals("// #TryCatch:")) {
stage = 1; stage = 1;
} else if (s.equals("// #LocalVars:")) { } else if (s.equals("// #LocalVars:")) {
@@ -285,7 +286,7 @@ public class Assembler {
String[] sp = st.split(":"); String[] sp = st.split(":");
int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2)); int start = Integer.parseInt(sp[3].substring(0, sp[3].length() - 2));
int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4)); int end = Integer.parseInt(sp[4].substring(0, sp[4].length() - 4));
String signat = sp[5].equals("null") ? null : sp[5]; String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(sp[5]);
LabelNode _start = null; LabelNode _start = null;
LabelNode _end = null; LabelNode _end = null;
for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) { for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) {
@@ -296,8 +297,9 @@ public class Assembler {
_end = new LabelNode(entry.getKey()); _end = new LabelNode(entry.getKey());
} }
} }
node.localVariables.add(new LocalVariableNode(sp[0], sp[1].substring(1, sp[1].length() - 2), signat, _start, node.localVariables
_end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2)))); .add(new LocalVariableNode(sp[0], UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat,
_start, _end, Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
} }
for (String st : tryCatchBlocksToParse) { for (String st : tryCatchBlocksToParse) {
String[] sp = st.split(" "); String[] sp = st.split(" ");
@@ -318,7 +320,8 @@ public class Assembler {
_handler = new LabelNode(entry.getKey()); _handler = new LabelNode(entry.getKey());
} }
} }
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler, sp[0].equals("null") ? null : sp[0])); node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
sp[0].equals("null") ? null : UnicodeUtils.unescape(sp[0])));
} }
clazz.methods.add(node); clazz.methods.add(node);
// signature = null; // signature = null;
@@ -327,13 +330,13 @@ public class Assembler {
if (s.contains(" throws ")) { if (s.contains(" throws ")) {
String exceptions = s.substring(s.lastIndexOf(" throws ") + 8); String exceptions = s.substring(s.lastIndexOf(" throws ") + 8);
for (String excp : exceptions.split(", ")) { for (String excp : exceptions.split(", ")) {
node.exceptions.add(excp); node.exceptions.add(UnicodeUtils.unescape(excp));
} }
s = s.substring(0, s.lastIndexOf(" throws ")); s = s.substring(0, s.lastIndexOf(" throws "));
} }
String[] split = s.split(" "); String[] split = s.split(" ");
node.desc = split[split.length - 1]; node.desc = UnicodeUtils.unescape(split[split.length - 1]);
node.name = split[split.length - 2]; node.name = UnicodeUtils.unescape(split[split.length - 2]);
int access = 0; int access = 0;
if (split.length > 2) { if (split.length > 2) {
String cons = consolidateStrings(split, 0, split.length - 2); String cons = consolidateStrings(split, 0, split.length - 2);
@@ -433,7 +436,7 @@ public class Assembler {
private static AnnotationNode parseAnnotation(String s) { private static AnnotationNode parseAnnotation(String s) {
s = s.substring(1); s = s.substring(1);
String[] split = s.split(" "); String[] split = s.split(" ");
AnnotationNode node = new AnnotationNode(split[0]); AnnotationNode node = new AnnotationNode(UnicodeUtils.unescape(split[0]));
if (split.length > 1) { if (split.length > 1) {
if (node.values == null) { if (node.values == null) {
node.values = new ArrayList<>(); node.values = new ArrayList<>();
@@ -451,25 +454,27 @@ public class Assembler {
String split3[] = value.substring(2, value.length() - 2).split(", "); String split3[] = value.substring(2, value.length() - 2).split(", ");
List<Object> list = new ArrayList<>(); List<Object> list = new ArrayList<>();
for (String rofl : split3) { for (String rofl : split3) {
rofl = UnicodeUtils.unescape(rofl);
if (rofl.startsWith("\"")) { if (rofl.startsWith("\"")) {
int index = rofl.lastIndexOf("\""); int index = rofl.lastIndexOf("\"");
list.add(rofl.substring(1, index)); list.add(rofl.substring(1, index));
} else if (!rofl.startsWith("(")) { } else if (!rofl.startsWith("(")) {
int index = rofl.indexOf(";"); int index = rofl.indexOf(";");
list.add(new String[] { rofl.substring(0, index) + ";", rofl.substring(index).substring(2) }); list.add(new String[] { rofl.substring(0, index) + ";", rofl.substring(index).substring(2) });
} else { // anderer typ mit casten } else { // other type with casting
list.add(ClassUtil.getCastedValue(rofl.split(" ")[1], rofl.split("\\) ")[0].substring(1))); list.add(ClassUtil.getCastedValue(rofl.split(" ")[1], rofl.split("\\) ")[0].substring(1)));
} }
} }
node.values.add(list); node.values.add(list);
} else { } else {
value = UnicodeUtils.unescape(value);
if (value.startsWith("\"")) { if (value.startsWith("\"")) {
int index = value.lastIndexOf("\""); int index = value.lastIndexOf("\"");
node.values.add(value.substring(1, index)); node.values.add(value.substring(1, index));
} else if (!value.startsWith("(")) { } else if (!value.startsWith("(")) {
int index = value.indexOf(";"); int index = value.indexOf(";");
node.values.add(new String[] { value.substring(0, index) + ";", value.substring(index).substring(2) }); node.values.add(new String[] { value.substring(0, index) + ";", value.substring(index).substring(2) });
} else { // anderer typ mit casten } else { // other type with casting
node.values.add(ClassUtil.getCastedValue(value.split(" ")[1], value.split("\\) ")[0].substring(1))); node.values.add(ClassUtil.getCastedValue(value.split(" ")[1], value.split("\\) ")[0].substring(1)));
} }
} }
@@ -526,7 +531,7 @@ public class Assembler {
case "S": case "S":
return Short.parseShort(s); return Short.parseShort(s);
case "Ljava/lang/String;": case "Ljava/lang/String;":
return StringEscapeUtils.unescapeJava(s.substring(1, s.length() - 1)).replace("\\n", "\n").replace("\\r", "\r"); return UnicodeUtils.unescape(s.substring(1, s.length() - 1));
default: { default: {
return null; return null;
} }
@@ -570,8 +575,8 @@ public class Assembler {
} else { } else {
for (String asd : l.split(", ")) { for (String asd : l.split(", ")) {
if (!asd.startsWith("(")) { if (!asd.startsWith("(")) {
arr.add(asd); arr.add(UnicodeUtils.unescape(asd));
} else { // anderer typ mit casten } else { // other type with casting
if (asd.startsWith("(label) ")) { if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]); int labelNr = Integer.parseInt(asd.split(" ")[1]);
boolean found = false; boolean found = false;
@@ -609,8 +614,8 @@ public class Assembler {
} else { } else {
for (String asd : st.split(", ")) { for (String asd : st.split(", ")) {
if (!asd.startsWith("(")) { if (!asd.startsWith("(")) {
arr.add(asd); arr.add(UnicodeUtils.unescape(asd));
} else { // anderer typ mit casten } else { // other type with casting
if (asd.startsWith("(label) ")) { if (asd.startsWith("(label) ")) {
int labelNr = Integer.parseInt(asd.split(" ")[1]); int labelNr = Integer.parseInt(asd.split(" ")[1]);
boolean found = false; boolean found = false;
@@ -696,8 +701,7 @@ public class Assembler {
split2[3].substring(6, split2[3].length() - 1).toCharArray(), Integer.parseInt(split2[1].substring(5)), split2[3].substring(6, split2[3].length() - 1).toCharArray(), Integer.parseInt(split2[1].substring(5)),
Integer.parseInt(split2[2].substring(5)) }); Integer.parseInt(split2[2].substring(5)) });
} else if (str.startsWith("\"") && str.endsWith("\"")) { } else if (str.startsWith("\"") && str.endsWith("\"")) {
val = StringEscapeUtils.unescapeJava(str.substring(1, str.length() - 1)).replace("\\n", "\n").replace("\\r", val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
"\r");
} else if (str.endsWith("l")) { } else if (str.endsWith("l")) {
val = Long.parseLong(str.substring(0, str.length() - 1)); val = Long.parseLong(str.substring(0, str.length() - 1));
} else if (str.endsWith("f")) { } else if (str.endsWith("f")) {
@@ -1315,42 +1319,50 @@ public class Assembler {
case "getstatic": { case "getstatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(178, target.substring(0, index), target.substring(index + 1), split[1]); return new FieldInsnNode(178, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
} }
case "putstatic": { case "putstatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(179, target.substring(0, index), target.substring(index + 1), split[1]); return new FieldInsnNode(179, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
} }
case "getfield": { case "getfield": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(180, target.substring(0, index), target.substring(index + 1), split[1]); return new FieldInsnNode(180, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
} }
case "putfield": { case "putfield": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new FieldInsnNode(181, target.substring(0, index), target.substring(index + 1), split[1]); return new FieldInsnNode(181, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]));
} }
case "invokevirtual": { case "invokevirtual": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(182, target.substring(0, index), target.substring(index + 1), split[1], false); return new MethodInsnNode(182, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
} }
case "invokespecial": { case "invokespecial": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(183, target.substring(0, index), target.substring(index + 1), split[1], false); return new MethodInsnNode(183, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
} }
case "invokestatic": { case "invokestatic": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(184, target.substring(0, index), target.substring(index + 1), split[1], false); return new MethodInsnNode(184, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), false);
} }
case "invokeinterface": { case "invokeinterface": {
String target = split[2]; String target = split[2];
int index = target.lastIndexOf("/"); int index = target.lastIndexOf("/");
return new MethodInsnNode(185, target.substring(0, index), target.substring(index + 1), split[1], true); return new MethodInsnNode(185, UnicodeUtils.unescape(target.substring(0, index)),
UnicodeUtils.unescape(target.substring(index + 1)), UnicodeUtils.unescape(split[1]), true);
} }
case "invokedynamic": { case "invokedynamic": {
String str = s.substring(16, s.length() - 2).replace("", ""); String str = s.substring(16, s.length() - 2).replace("", "");
@@ -1367,15 +1379,15 @@ public class Assembler {
int.class); int.class);
constr.setAccessible(true); constr.setAccessible(true);
args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)), args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)),
vals.get(3).substring(6, vals.get(3).length() - 1).toCharArray(), UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)).toCharArray(),
Integer.parseInt(vals.get(1).substring(5)), Integer.parseInt(vals.get(2).substring(5)) })); Integer.parseInt(vals.get(1).substring(5)), Integer.parseInt(vals.get(2).substring(5)) }));
} catch (Exception e) { } catch (Exception e) {
throw e; throw e;
} }
} else if (stage == 2) { } else if (stage == 2) {
args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)), vals.get(1).substring(7), args.add(new Handle(Integer.parseInt(vals.get(4).substring(5)),
vals.get(0).substring(6), vals.get(2).substring(6), UnicodeUtils.unescape(vals.get(1).substring(7)), UnicodeUtils.unescape(vals.get(0).substring(6)),
Boolean.parseBoolean(vals.get(3).substring(13)))); UnicodeUtils.unescape(vals.get(2).substring(6)), Boolean.parseBoolean(vals.get(3).substring(13))));
vals.clear(); vals.clear();
} }
stage = 0; stage = 0;
@@ -1398,13 +1410,14 @@ public class Assembler {
_args[stage] = o; _args[stage] = o;
stage++; stage++;
} }
return new InvokeDynamicInsnNode(sp[0].substring(7), sp[1].substring(6), return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)), UnicodeUtils.unescape(sp[1].substring(6)),
new Handle(Integer.parseInt(sp[7].substring(6)), sp[4].substring(8), sp[3].substring(7), sp[5].substring(7), new Handle(Integer.parseInt(sp[7].substring(6)), UnicodeUtils.unescape(sp[4].substring(8)),
UnicodeUtils.unescape(sp[3].substring(7)), UnicodeUtils.unescape(sp[5].substring(7)),
Boolean.parseBoolean(sp[6].substring(14))), Boolean.parseBoolean(sp[6].substring(14))),
_args); _args);
} }
case "new": { case "new": {
return new TypeInsnNode(187, split[1]); return new TypeInsnNode(187, UnicodeUtils.unescape(split[1]));
} }
case "newarray": { case "newarray": {
return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1])); return new IntInsnNode(188, ClassUtil.getArrayIDByType(split[1]));
@@ -1431,7 +1444,7 @@ public class Assembler {
return new InsnNode(195); return new InsnNode(195);
} }
case "multianewarray": { case "multianewarray": {
return new MultiANewArrayInsnNode(split[1], Integer.parseInt(split[2])); return new MultiANewArrayInsnNode(UnicodeUtils.unescape(split[1]), Integer.parseInt(split[2]));
} }
case "ifnull": { case "ifnull": {
int labelNr = Integer.parseInt(s.split(" ")[1]); int labelNr = Integer.parseInt(s.split(" ")[1]);
+57 -50
View File
@@ -37,6 +37,7 @@ import org.objectweb.asm.tree.VarInsnNode;
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;
public class Disassembler { public class Disassembler {
@@ -79,7 +80,7 @@ public class Disassembler {
s += "// #Annotations\n"; s += "// #Annotations\n";
if (classNode.visibleAnnotations != null && !classNode.visibleAnnotations.isEmpty()) { if (classNode.visibleAnnotations != null && !classNode.visibleAnnotations.isEmpty()) {
for (AnnotationNode annotationNode : classNode.visibleAnnotations) { for (AnnotationNode annotationNode : classNode.visibleAnnotations) {
s += "@" + annotationNode.desc; s += "@" + UnicodeUtils.escape(annotationNode.desc);
if (annotationNode.values != null && !annotationNode.values.isEmpty()) { if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
s += " ("; s += " (";
boolean valBefore = true; boolean valBefore = true;
@@ -94,10 +95,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl + "]"; s += UnicodeUtils.escape(rofl) + "]";
} }
} }
s += ", "; s += ", ";
@@ -110,10 +111,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl; s += UnicodeUtils.escape(rofl);
} }
} }
} else { } else {
@@ -137,37 +138,39 @@ public class Disassembler {
} }
} }
s += "// #Class v:" + classNode.version + "\n"; s += "// #Class v:" + classNode.version + "\n";
s += "// #Signature: " + classNode.signature + "\n"; s += "// #Signature: " + UnicodeUtils.escape(classNode.signature) + "\n";
s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null" : (classNode.outerMethod + " " + classNode.outerMethodDesc)) s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null"
+ "\n"; : (UnicodeUtils.escape(classNode.outerMethod) + " " + UnicodeUtils.escape(classNode.outerMethodDesc))) + "\n";
s += "// #OuterClass: " + classNode.outerClass + "\n"; s += "// #OuterClass: " + UnicodeUtils.escape(classNode.outerClass) + "\n";
s += "// #InnerClasses:\n"; s += "// #InnerClasses:\n";
if (classNode.innerClasses != null) { if (classNode.innerClasses != null) {
for (InnerClassNode icn : classNode.innerClasses) { for (InnerClassNode icn : classNode.innerClasses) {
s += "// " + icn.name + " " + icn.outerName + " " + icn.innerName + " 0x" + Integer.toHexString(icn.access) + "\n"; s += "// " + UnicodeUtils.escape(icn.name) + " " + UnicodeUtils.escape(icn.outerName) + " "
+ UnicodeUtils.escape(icn.innerName) + " 0x" + Integer.toHexString(icn.access) + "\n";
} }
} }
s += ClassUtil.getAccessFlagsClass(classNode.access) + classNode.name + " "; s += ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escape(classNode.name) + " ";
s += "extends " + classNode.superName + " "; s += "extends " + UnicodeUtils.escape(classNode.superName) + " ";
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) { if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
String interfaceStr = ""; String interfaceStr = "";
for (String interfc : classNode.interfaces) { for (String interfc : classNode.interfaces) {
if (interfaceStr.isEmpty()) { if (interfaceStr.isEmpty()) {
interfaceStr += interfc; interfaceStr += UnicodeUtils.escape(interfc);
} else { } else {
interfaceStr += ", " + interfc; interfaceStr += ", " + UnicodeUtils.escape(interfc);
} }
} }
if (!interfaceStr.isEmpty()) if (!interfaceStr.isEmpty())
s += "implements " + interfaceStr + " "; s += "implements " + interfaceStr + " ";
} }
s += "{\n// #SourceFile: " + (classNode.sourceFile == null ? "null" : classNode.sourceFile) + "\n\n// #Fields\n"; s += "{\n// #SourceFile: " + (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile))
+ "\n\n// #Fields\n";
for (FieldNode fn : classNode.fields) { for (FieldNode fn : classNode.fields) {
if (fn.signature != null) if (fn.signature != null)
s += "\t// #Signature: " + fn.signature + "\n"; s += "\t// #Signature: " + UnicodeUtils.escape(fn.signature) + "\n";
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) { if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) {
for (AnnotationNode annotationNode : fn.visibleAnnotations) { for (AnnotationNode annotationNode : fn.visibleAnnotations) {
s += "\t@" + annotationNode.desc; s += "\t@" + UnicodeUtils.escape(annotationNode.desc);
if (annotationNode.values != null && !annotationNode.values.isEmpty()) { if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
s += " ("; s += " (";
boolean valBefore = true; boolean valBefore = true;
@@ -182,10 +185,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl + "]"; s += UnicodeUtils.escape(rofl) + "]";
} }
} }
s += ", "; s += ", ";
@@ -198,10 +201,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl; s += UnicodeUtils.escape(rofl);
} }
} }
} else { } else {
@@ -224,7 +227,8 @@ public class Disassembler {
s += "\n"; s += "\n";
} }
} }
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + fn.desc + " " + fn.name; s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient") + UnicodeUtils.escape(fn.desc) + " "
+ UnicodeUtils.escape(fn.name);
if (fn.value != null) { if (fn.value != null) {
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc); s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc);
} }
@@ -235,7 +239,7 @@ public class Disassembler {
try { try {
s += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n"; s += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
if (mn.signature != null) if (mn.signature != null)
s += "\t// #Signature: " + mn.signature + "\n"; s += "\t// #Signature: " + UnicodeUtils.escape(mn.signature) + "\n";
String[] dis = disassembleMethod(classNode.name, mn); String[] dis = disassembleMethod(classNode.name, mn);
s += dis[2]; s += dis[2];
s += dis[1]; s += dis[1];
@@ -256,10 +260,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl + "]"; s += UnicodeUtils.escape(rofl) + "]";
} }
} }
s += ", "; s += ", ";
@@ -272,10 +276,10 @@ public class Disassembler {
boolean w8ing = false; boolean w8ing = false;
for (String rofl : arr) { for (String rofl : arr) {
if (!w8ing) { if (!w8ing) {
s += rofl + "/"; s += UnicodeUtils.escape(rofl) + "/";
w8ing = true; w8ing = true;
} else { } else {
s += rofl; s += UnicodeUtils.escape(rofl);
} }
} }
} else { } else {
@@ -301,14 +305,15 @@ public class Disassembler {
if (mn.equals(methodToFind)) { if (mn.equals(methodToFind)) {
lineFound = s.split("\\n").length; lineFound = s.split("\\n").length;
} }
s += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + mn.name + " " + mn.desc + " "; s += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escape(mn.name) + " " + UnicodeUtils.escape(mn.desc)
+ " ";
if (mn.exceptions != null && !mn.exceptions.isEmpty()) { if (mn.exceptions != null && !mn.exceptions.isEmpty()) {
String exceptionStr = ""; String exceptionStr = "";
for (String exc : mn.exceptions) { for (String exc : mn.exceptions) {
if (exceptionStr.isEmpty()) { if (exceptionStr.isEmpty()) {
exceptionStr += exc; exceptionStr += UnicodeUtils.escape(exc);
} else { } else {
exceptionStr += ", " + exc; exceptionStr += ", " + UnicodeUtils.escape(exc);
} }
} }
if (!exceptionStr.isEmpty()) if (!exceptionStr.isEmpty())
@@ -343,14 +348,15 @@ public class Disassembler {
} }
if (mn.localVariables != null) { if (mn.localVariables != null) {
for (LocalVariableNode lvn : mn.localVariables) { for (LocalVariableNode lvn : mn.localVariables) {
localVarTable += "\t// " + lvn.name + ": " + lvn.desc + " i:" + lvn.index + " s:" + labels.get(lvn.start.getLabel()) + " e:" localVarTable += "\t// " + UnicodeUtils.escape(lvn.name) + ": " + UnicodeUtils.escape(lvn.desc) + " i:" + lvn.index + " s:"
+ labels.get(lvn.end.getLabel()) + " sig:" + lvn.signature + "\n"; + labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:"
+ UnicodeUtils.escape(lvn.signature) + "\n";
} }
} }
if (mn.tryCatchBlocks != null) { if (mn.tryCatchBlocks != null) {
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) { for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
tryCatchTable += "\t// " + tcbn.type + " s:" + labels.get(tcbn.start.getLabel()) + " e:" + labels.get(tcbn.end.getLabel()) tryCatchTable += "\t// " + UnicodeUtils.escape(tcbn.type) + " s:" + labels.get(tcbn.start.getLabel()) + " e:"
+ " h:" + labels.get(tcbn.handler.getLabel()) + "\n"; + labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n";
} }
} }
for (AbstractInsnNode n : mn.instructions.toArray()) { for (AbstractInsnNode n : mn.instructions.toArray()) {
@@ -363,8 +369,8 @@ public class Disassembler {
switch (n.getClass().getSimpleName()) { switch (n.getClass().getSimpleName()) {
case "FieldInsnNode": { case "FieldInsnNode": {
FieldInsnNode node = (FieldInsnNode) n; FieldInsnNode node = (FieldInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + node.desc + " " + node.owner + "/" + node.name return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escape(node.desc) + " "
+ "\n"; + UnicodeUtils.escape(node.owner) + "/" + UnicodeUtils.escape(node.name) + "\n";
} }
case "LabelNode": { case "LabelNode": {
LabelNode node = (LabelNode) n; LabelNode node = (LabelNode) n;
@@ -380,7 +386,7 @@ public class Disassembler {
arr.add(null); arr.add(null);
} else { } else {
if (o instanceof String) { if (o instanceof String) {
arr.add((String) o); arr.add(UnicodeUtils.escape((String) o));
} else if (o instanceof LabelNode) { } else if (o instanceof LabelNode) {
arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
} else { } else {
@@ -400,7 +406,7 @@ public class Disassembler {
arr.add(null); arr.add(null);
} else { } else {
if (o instanceof String) { if (o instanceof String) {
arr.add((String) o); arr.add(UnicodeUtils.escape((String) o));
} else if (o instanceof LabelNode) { } else if (o instanceof LabelNode) {
arr.add("(label) " + labels.get(((LabelNode) o).getLabel())); arr.add("(label) " + labels.get(((LabelNode) o).getLabel()));
} else { } else {
@@ -421,10 +427,11 @@ public class Disassembler {
} }
case "InvokeDynamicInsnNode": { case "InvokeDynamicInsnNode": {
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n; InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " + node.name + "\n\t\t\tdesc: " String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: " + UnicodeUtils.escape(node.name)
+ node.desc + "\n\t\t\tHandle: [\n\t\t\t\tname: " + node.bsm.getName() + "\n\t\t\t\towner: " + node.bsm.getOwner() + "\n\t\t\tdesc: " + UnicodeUtils.escape(node.desc) + "\n\t\t\tHandle: [\n\t\t\t\tname: "
+ "\n\t\t\t\tdesc: " + node.bsm.getDesc() + "\n\t\t\t\tisInterface: " + node.bsm.isInterface() + "\n\t\t\t\ttag: " + UnicodeUtils.escape(node.bsm.getName()) + "\n\t\t\t\towner: " + UnicodeUtils.escape(node.bsm.getOwner())
+ node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n"; + "\n\t\t\t\tdesc: " + UnicodeUtils.escape(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: " + node.bsm.isInterface()
+ "\n\t\t\t\ttag: " + node.bsm.getTag() + "\n\t\t\t]\n\t\t\targs: [\n";
for (Object l : node.bsmArgs) { for (Object l : node.bsmArgs) {
if (l.getClass().getName().equals("org.objectweb.asm.Type")) { if (l.getClass().getName().equals("org.objectweb.asm.Type")) {
Type type = (Type) l; Type type = (Type) l;
@@ -447,9 +454,9 @@ public class Disassembler {
s += "\n\t\t\t\t]\n"; s += "\n\t\t\t\t]\n";
} else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) { } else if (l.getClass().getName().equals("org.objectweb.asm.Handle")) {
Handle h = (Handle) l; Handle h = (Handle) l;
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + h.getName() + "\n\t\t\t\t\towner: " + h.getOwner() s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: " + UnicodeUtils.escape(h.getName()) + "\n\t\t\t\t\towner: "
+ "\n\t\t\t\t\tdesc: " + h.getDesc() + "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: " + UnicodeUtils.escape(h.getOwner()) + "\n\t\t\t\t\tdesc: " + UnicodeUtils.escape(h.getDesc())
+ h.getTag(); + "\n\t\t\t\t\tisInterface: " + h.isInterface() + "\n\t\t\t\t\ttag: " + h.getTag();
s += "\n\t\t\t\t]\n"; s += "\n\t\t\t\t]\n";
} else { } else {
s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n"; s += "\t\t\t\t" + ClassUtil.getDecompiledValue(l, "") + "\n";
@@ -460,16 +467,17 @@ public class Disassembler {
} }
case "MethodInsnNode": { case "MethodInsnNode": {
MethodInsnNode node = (MethodInsnNode) n; MethodInsnNode node = (MethodInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + node.desc + " " + node.owner + "/" + node.name return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escape(node.desc) + " "
+ "\n"; + UnicodeUtils.escape(node.owner) + "/" + UnicodeUtils.escape(node.name) + "\n";
} }
case "TypeInsnNode": { case "TypeInsnNode": {
TypeInsnNode node = (TypeInsnNode) n; TypeInsnNode node = (TypeInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.desc + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escape(node.desc) + "\n";
} }
case "MultiANewArrayInsnNode": { case "MultiANewArrayInsnNode": {
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n; MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + node.desc + " " + node.dims + "\n"; return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " " + UnicodeUtils.escape(node.desc) + " " + node.dims
+ "\n";
} }
case "LdcInsnNode": { case "LdcInsnNode": {
LdcInsnNode node = (LdcInsnNode) n; LdcInsnNode node = (LdcInsnNode) n;
@@ -535,7 +543,6 @@ public class Disassembler {
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min + "\n\t\t\tmax: " + node.max String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min + "\n\t\t\tmax: " + node.max
+ "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) + "\n\t\t\tlabels: [\n"; + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel()) + "\n\t\t\tlabels: [\n";
for (LabelNode l : node.labels) { for (LabelNode l : node.labels) {
// System.out.println(l + ", " + l.getLabel());
s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n"; s += "\t\t\t\t" + labels.get(l.getLabel()) + "\n";
} }
s += "\t\t\t]\n\t\t]\n"; s += "\t\t\t]\n\t\t]\n";
+11 -2
View File
@@ -77,6 +77,7 @@ import me.ByteEdit.edit.SearchBox;
import me.ByteEdit.edit.TypeOpenBox; import me.ByteEdit.edit.TypeOpenBox;
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;
public class Main extends JFrame { public class Main extends JFrame {
@@ -404,8 +405,8 @@ public class Main extends JFrame {
line = line.substring(2); line = line.substring(2);
if (line.startsWith("invoke")) { if (line.startsWith("invoke")) {
String[] split = line.split(" "); String[] split = line.split(" ");
String desc = split[1]; String desc = UnicodeUtils.unescape(split[1]);
String className = split[2]; String className = UnicodeUtils.unescape(split[2]);
String[] nameSplit = className.split("/"); String[] nameSplit = className.split("/");
String methodName = nameSplit[nameSplit.length - 1]; String methodName = nameSplit[nameSplit.length - 1];
className = className.substring(0, className.length() - methodName.length() - 1); className = className.substring(0, className.length() - methodName.length() - 1);
@@ -425,6 +426,14 @@ public class Main extends JFrame {
break; break;
} }
} }
} else if (line.startsWith("new ")) {
String[] split = line.split(" ");
String className = UnicodeUtils.unescape(split[1]);
ClassNode classNode = classNodes.get(className + ".class");
if (classNode == null) {
return;
}
selectFile(className + ".class");
} }
} }
+1 -2
View File
@@ -4,7 +4,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.apache.commons.lang3.StringEscapeUtils;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
public class ClassUtil { public class ClassUtil {
@@ -451,7 +450,7 @@ public class ClassUtil {
public static String getDecompiledValue(Object o, String desc) { public static String getDecompiledValue(Object o, String desc) {
switch (o.getClass().getName()) { switch (o.getClass().getName()) {
case "java.lang.String": { case "java.lang.String": {
return "\"" + StringEscapeUtils.escapeJava((String) o).replace("\n", "\\n").replace("\r", "\\r") + "\""; return "\"" + UnicodeUtils.escape((String) o) + "\"";
} }
case "java.lang.Integer": { case "java.lang.Integer": {
if (desc.equals("Z")) { if (desc.equals("Z")) {
+145
View File
@@ -0,0 +1,145 @@
package me.ByteEdit.utils;
public class UnicodeUtils {
public static String unescape(String s) {
if (s == null) {
return null;
}
StringBuilder sb = new StringBuilder();
char unicodeBuffer = 0;
int stage = 0;
for (char c : s.toCharArray()) {
if (c == '\\' && stage == 0) {
stage = 1;
continue;
}
if (stage == 1) {
switch (c) {
case 'b':
sb.append('\b');
stage = 0;
break;
case 't':
sb.append('\t');
stage = 0;
break;
case 'n':
sb.append('\n');
stage = 0;
break;
case 'r':
sb.append('\r');
stage = 0;
break;
case 'f':
sb.append('\f');
stage = 0;
break;
case '"':
sb.append('"');
stage = 0;
break;
case '\\':
sb.append('\\');
stage = 0;
break;
case 'u':
stage++;
break;
default:
throw new IllegalArgumentException("'\\" + c + "' is invalid.");
}
continue;
} else if (stage > 1 && stage < 6) { // \u1234 => up to 6
try {
int i = Integer.parseInt(Character.toString(c), 16);
unicodeBuffer += i << (4 * (5 - stage++)); // 4 bytes each, shift left byte * 4..3..2..1 and add to unicodeBuffer
if (stage == 6) {
sb.append(unicodeBuffer);
stage = 0;
unicodeBuffer = 0;
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("'" + c + "' is not a valid hex value.");
}
continue;
}
sb.append(c);
}
if (stage != 0) {
if (unicodeBuffer != 0) {
throw new IllegalArgumentException("The unicode at the end is incomplete.");
} else {
throw new IllegalArgumentException("'\\' at the end is invalid.");
}
}
return sb.toString();
}
public static String escape(String s) {
if (s == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (char c : s.toCharArray()) {
if (isPrintable(c)) {
sb.append(c);
} else {
switch (c) {
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\f':
sb.append("\\f");
break;
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
default:
sb.append(String.format("\\u%04X", (int) c));
}
}
}
return sb.toString();
}
private static boolean isPrintable(char c) {
switch (c) {
case 'Ä':
case 'ä':
case 'Ö':
case 'ö':
case 'Ü':
case 'ü':
case 'ß':
case '€':
case '©':
case '®':
case '«':
case '»':
case '§':
case '£':
case '¥':
return true;
case '"':
case '\\':
return false;
default:
return c >= ' ' && c <= '~';
}
}
}