mirror of
https://github.com/SuspiciousActivity/ByteEdit.git
synced 2026-08-13 17:56:17 +00:00
Performance improvements
This commit is contained in:
1 parent
385c9ad9e3
commit
53f214b7b0
7 files changed
+660
-493
No files matched your search
+140
-142
@@ -292,7 +292,7 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HashMap<Label, Integer> methodLabelMap = new HashMap<Label, Integer>();
|
HashMap<LabelNode, Integer> methodLabelMap = new HashMap<LabelNode, Integer>();
|
||||||
annotationsForNext.clear();
|
annotationsForNext.clear();
|
||||||
MethodNode node = null;
|
MethodNode node = null;
|
||||||
String temp = "";
|
String temp = "";
|
||||||
@@ -348,12 +348,12 @@ public class Assembler {
|
|||||||
String signat = sp[5].equals("null") ? null : UnicodeUtils.unescape(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<LabelNode, Integer> entry : methodLabelMap.entrySet()) {
|
||||||
if (entry.getValue() == start) {
|
if (entry.getValue().intValue() == start) {
|
||||||
_start = new LabelNode(entry.getKey());
|
_start = entry.getKey();
|
||||||
}
|
}
|
||||||
if (entry.getValue() == end) {
|
if (entry.getValue().intValue() == end) {
|
||||||
_end = new LabelNode(entry.getKey());
|
_end = entry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(sp[0]),
|
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(sp[0]),
|
||||||
@@ -368,15 +368,15 @@ public class Assembler {
|
|||||||
LabelNode _start = null;
|
LabelNode _start = null;
|
||||||
LabelNode _end = null;
|
LabelNode _end = null;
|
||||||
LabelNode _handler = null;
|
LabelNode _handler = null;
|
||||||
for (Entry<Label, Integer> entry : methodLabelMap.entrySet()) {
|
for (Entry<LabelNode, Integer> entry : methodLabelMap.entrySet()) {
|
||||||
if (entry.getValue() == start) {
|
if (entry.getValue().intValue() == start) {
|
||||||
_start = new LabelNode(entry.getKey());
|
_start = entry.getKey();
|
||||||
}
|
}
|
||||||
if (entry.getValue() == end) {
|
if (entry.getValue().intValue() == end) {
|
||||||
_end = new LabelNode(entry.getKey());
|
_end = entry.getKey();
|
||||||
}
|
}
|
||||||
if (entry.getValue() == handler) {
|
if (entry.getValue().intValue() == handler) {
|
||||||
_handler = new LabelNode(entry.getKey());
|
_handler = entry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
|
node.tryCatchBlocks.add(new TryCatchBlockNode(_start, _end, _handler,
|
||||||
@@ -625,28 +625,28 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AbstractInsnNode getNode(String s, HashMap<Label, Integer> labels) throws Exception {
|
private static AbstractInsnNode getNode(String s, HashMap<LabelNode, Integer> labels) throws Exception {
|
||||||
if (s.startsWith("// label ")) {
|
if (s.startsWith("// label ")) {
|
||||||
int labelNr = Integer.parseInt(s.substring(9));
|
int labelNr = Integer.parseInt(s.substring(9));
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new LabelNode(entry.getKey());
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new LabelNode(l);
|
return ln;
|
||||||
} else if (s.startsWith("// line ")) {
|
} else if (s.startsWith("// line ")) {
|
||||||
s = s.substring(8);
|
s = s.substring(8);
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), new LabelNode(entry.getKey()));
|
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), new LabelNode(l));
|
return new LineNumberNode(Integer.parseInt(s.split(" ")[0]), ln);
|
||||||
} else if (s.startsWith("// frame ")) {
|
} else if (s.startsWith("// frame ")) {
|
||||||
String str1 = s.substring(7);
|
String str1 = s.substring(7);
|
||||||
String str = str1.substring(str1.indexOf(' ', 3) + 1);
|
String str = str1.substring(str1.indexOf(' ', 3) + 1);
|
||||||
@@ -674,16 +674,16 @@ public class Assembler {
|
|||||||
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;
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
arr.add(new LabelNode(entry.getKey()));
|
arr.add(entry.getKey());
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Label lb = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(lb, labelNr);
|
labels.put(ln, labelNr);
|
||||||
arr.add(new LabelNode(lb));
|
arr.add(ln);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
|
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
|
||||||
@@ -720,16 +720,16 @@ public class Assembler {
|
|||||||
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;
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
arr.add(new LabelNode(entry.getKey()));
|
arr.add(entry.getKey());
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
arr.add(new LabelNode(l));
|
arr.add(ln);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
|
arr.add(ClassUtil.getCastedValue(asd.split(" ")[1], asd.split("\\) ")[0].substring(1)));
|
||||||
@@ -1115,179 +1115,179 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
case "ifeq": {
|
case "ifeq": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(153, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(153, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(153, new LabelNode(l));
|
return new JumpInsnNode(153, ln);
|
||||||
}
|
}
|
||||||
case "ifne": {
|
case "ifne": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(154, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(154, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(154, new LabelNode(l));
|
return new JumpInsnNode(154, ln);
|
||||||
}
|
}
|
||||||
case "iflt": {
|
case "iflt": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(155, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(155, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(155, new LabelNode(l));
|
return new JumpInsnNode(155, ln);
|
||||||
}
|
}
|
||||||
case "ifge": {
|
case "ifge": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(156, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(156, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(156, new LabelNode(l));
|
return new JumpInsnNode(156, ln);
|
||||||
}
|
}
|
||||||
case "ifgt": {
|
case "ifgt": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(157, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(157, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(157, new LabelNode(l));
|
return new JumpInsnNode(157, ln);
|
||||||
}
|
}
|
||||||
case "ifle": {
|
case "ifle": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(158, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(158, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(158, new LabelNode(l));
|
return new JumpInsnNode(158, ln);
|
||||||
}
|
}
|
||||||
case "if_icmpeq": {
|
case "if_icmpeq": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(159, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(159, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(159, new LabelNode(l));
|
return new JumpInsnNode(159, ln);
|
||||||
}
|
}
|
||||||
case "if_icmpne": {
|
case "if_icmpne": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(160, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(160, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(160, new LabelNode(l));
|
return new JumpInsnNode(160, ln);
|
||||||
}
|
}
|
||||||
case "if_icmplt": {
|
case "if_icmplt": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(161, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(161, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(161, new LabelNode(l));
|
return new JumpInsnNode(161, ln);
|
||||||
}
|
}
|
||||||
case "if_icmpge": {
|
case "if_icmpge": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(162, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(162, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(162, new LabelNode(l));
|
return new JumpInsnNode(162, ln);
|
||||||
}
|
}
|
||||||
case "if_icmpgt": {
|
case "if_icmpgt": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(163, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(163, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(163, new LabelNode(l));
|
return new JumpInsnNode(163, ln);
|
||||||
}
|
}
|
||||||
case "if_icmple": {
|
case "if_icmple": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(164, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(164, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(164, new LabelNode(l));
|
return new JumpInsnNode(164, ln);
|
||||||
}
|
}
|
||||||
case "if_acmpeq": {
|
case "if_acmpeq": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(165, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(165, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(165, new LabelNode(l));
|
return new JumpInsnNode(165, ln);
|
||||||
}
|
}
|
||||||
case "if_acmpne": {
|
case "if_acmpne": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(166, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(166, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(166, new LabelNode(l));
|
return new JumpInsnNode(166, ln);
|
||||||
}
|
}
|
||||||
case "goto": {
|
case "goto": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(167, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(167, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(167, new LabelNode(l));
|
return new JumpInsnNode(167, ln);
|
||||||
}
|
}
|
||||||
case "jsr": {
|
case "jsr": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(168, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(168, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(168, new LabelNode(l));
|
return new JumpInsnNode(168, ln);
|
||||||
}
|
}
|
||||||
case "ret": {
|
case "ret": {
|
||||||
return new VarInsnNode(169, Integer.parseInt(s.split(" ")[1]));
|
return new VarInsnNode(169, Integer.parseInt(s.split(" ")[1]));
|
||||||
@@ -1307,9 +1307,9 @@ public class Assembler {
|
|||||||
LabelNode dflt = null;
|
LabelNode dflt = null;
|
||||||
if (!split2[2].substring(9).equals("null")) {
|
if (!split2[2].substring(9).equals("null")) {
|
||||||
int dfltLabelNr = Integer.parseInt(split2[2].substring(9));
|
int dfltLabelNr = Integer.parseInt(split2[2].substring(9));
|
||||||
for (Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == dfltLabelNr) {
|
if (entry.getValue() == dfltLabelNr) {
|
||||||
dflt = new LabelNode(entry.getKey());
|
dflt = entry.getKey();
|
||||||
labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt);
|
labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt);
|
||||||
}
|
}
|
||||||
labelMap.replaceAll(new BiFunction<SwitchIntContainer, LabelNode, LabelNode>() {
|
labelMap.replaceAll(new BiFunction<SwitchIntContainer, LabelNode, LabelNode>() {
|
||||||
@@ -1317,7 +1317,7 @@ public class Assembler {
|
|||||||
@Override
|
@Override
|
||||||
public LabelNode apply(SwitchIntContainer t, LabelNode u) {
|
public LabelNode apply(SwitchIntContainer t, LabelNode u) {
|
||||||
if (entry.getValue().intValue() == t.getId()) {
|
if (entry.getValue().intValue() == t.getId()) {
|
||||||
return new LabelNode(entry.getKey());
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
@@ -1325,9 +1325,9 @@ public class Assembler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (dflt == null) {
|
if (dflt == null) {
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, dfltLabelNr);
|
labels.put(ln, dfltLabelNr);
|
||||||
dflt = new LabelNode(l);
|
dflt = ln;
|
||||||
labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt);
|
labelIDs.put(BigInteger.valueOf(dfltLabelNr), dflt);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1338,9 +1338,8 @@ public class Assembler {
|
|||||||
for (Entry<SwitchIntContainer, LabelNode> entry : labelMap.entrySet()) {
|
for (Entry<SwitchIntContainer, LabelNode> entry : labelMap.entrySet()) {
|
||||||
LabelNode ln;
|
LabelNode ln;
|
||||||
if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) {
|
if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) {
|
||||||
Label l = new Label();
|
ln = new LabelNode(new Label());
|
||||||
labels.put(l, entry.getKey().getId());
|
labels.put(ln, entry.getKey().getId());
|
||||||
ln = new LabelNode(l);
|
|
||||||
labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln);
|
labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln);
|
||||||
}
|
}
|
||||||
arr[counter] = ln;
|
arr[counter] = ln;
|
||||||
@@ -1374,9 +1373,9 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
LabelNode dflt = null;
|
LabelNode dflt = null;
|
||||||
int labelNr = Integer.parseInt(split2[0].substring(9));
|
int labelNr = Integer.parseInt(split2[0].substring(9));
|
||||||
for (Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
dflt = new LabelNode(entry.getKey());
|
dflt = entry.getKey();
|
||||||
labelIDs.put(BigInteger.valueOf(labelNr), dflt);
|
labelIDs.put(BigInteger.valueOf(labelNr), dflt);
|
||||||
}
|
}
|
||||||
labelMap.replaceAll(new BiFunction<SwitchIntContainer, LabelNode, LabelNode>() {
|
labelMap.replaceAll(new BiFunction<SwitchIntContainer, LabelNode, LabelNode>() {
|
||||||
@@ -1384,7 +1383,7 @@ public class Assembler {
|
|||||||
@Override
|
@Override
|
||||||
public LabelNode apply(SwitchIntContainer t, LabelNode u) {
|
public LabelNode apply(SwitchIntContainer t, LabelNode u) {
|
||||||
if (entry.getValue().intValue() == t.getId()) {
|
if (entry.getValue().intValue() == t.getId()) {
|
||||||
return new LabelNode(entry.getKey());
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
@@ -1392,9 +1391,9 @@ public class Assembler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (dflt == null) {
|
if (dflt == null) {
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
dflt = new LabelNode(l);
|
dflt = ln;
|
||||||
labelIDs.put(BigInteger.valueOf(labelNr), dflt);
|
labelIDs.put(BigInteger.valueOf(labelNr), dflt);
|
||||||
}
|
}
|
||||||
LabelNode[] arr = new LabelNode[labelMap.size()];
|
LabelNode[] arr = new LabelNode[labelMap.size()];
|
||||||
@@ -1402,9 +1401,8 @@ public class Assembler {
|
|||||||
for (Entry<SwitchIntContainer, LabelNode> entry : labelMap.entrySet()) {
|
for (Entry<SwitchIntContainer, LabelNode> entry : labelMap.entrySet()) {
|
||||||
LabelNode ln;
|
LabelNode ln;
|
||||||
if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) {
|
if (((ln = labelIDs.get(BigInteger.valueOf(entry.getKey().getId()))) == null)) {
|
||||||
Label l = new Label();
|
ln = new LabelNode(new Label());
|
||||||
labels.put(l, entry.getKey().getId());
|
labels.put(ln, entry.getKey().getId());
|
||||||
ln = new LabelNode(l);
|
|
||||||
labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln);
|
labelIDs.put(BigInteger.valueOf(entry.getKey().getId()), ln);
|
||||||
}
|
}
|
||||||
arr[counter] = ln;
|
arr[counter] = ln;
|
||||||
@@ -1582,25 +1580,25 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
case "ifnull": {
|
case "ifnull": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(198, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(198, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(198, new LabelNode(l));
|
return new JumpInsnNode(198, ln);
|
||||||
}
|
}
|
||||||
case "ifnonnull": {
|
case "ifnonnull": {
|
||||||
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
int labelNr = Integer.parseInt(s.split(" ")[1]);
|
||||||
for (Map.Entry<Label, Integer> entry : labels.entrySet()) {
|
for (Map.Entry<LabelNode, Integer> entry : labels.entrySet()) {
|
||||||
if (entry.getValue() == labelNr) {
|
if (entry.getValue() == labelNr) {
|
||||||
return new JumpInsnNode(199, new LabelNode(entry.getKey()));
|
return new JumpInsnNode(199, entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Label l = new Label();
|
LabelNode ln = new LabelNode(new Label());
|
||||||
labels.put(l, labelNr);
|
labels.put(ln, labelNr);
|
||||||
return new JumpInsnNode(199, new LabelNode(l));
|
return new JumpInsnNode(199, ln);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Illegal Instruction: " + s);
|
throw new IllegalArgumentException("Illegal Instruction: " + s);
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.objectweb.asm.Handle;
|
import org.objectweb.asm.Handle;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
@@ -40,6 +46,9 @@ import me.ByteEdit.utils.UnicodeUtils;
|
|||||||
|
|
||||||
public class Disassembler {
|
public class Disassembler {
|
||||||
|
|
||||||
|
private static final ExecutorService exec = Executors
|
||||||
|
.newFixedThreadPool((Runtime.getRuntime().availableProcessors() + 1) / 2);
|
||||||
|
|
||||||
public static String disassemble(ClassNode classNode) {
|
public static String disassemble(ClassNode classNode) {
|
||||||
return disassemble(classNode, null).getDisassembly();
|
return disassemble(classNode, null).getDisassembly();
|
||||||
}
|
}
|
||||||
@@ -74,12 +83,250 @@ public class Disassembler {
|
|||||||
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!");
|
return new DisassembleTuple("ClassNode is null! This is not a valid java class file!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
int lineFound = -1;
|
AtomicInteger lineFound = new AtomicInteger(-1);
|
||||||
|
StringContext ctx = new StringContext(16);
|
||||||
|
ctx.next("// #Annotations:\n");
|
||||||
|
ctx.next(doAnnotations(classNode.visibleAnnotations));
|
||||||
|
ctx.next("// #Class v:" + classNode.version + "\n");
|
||||||
|
if (classNode.signature != null)
|
||||||
|
ctx.next("// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n");
|
||||||
|
if (classNode.outerMethod != null)
|
||||||
|
ctx.next("// #OuterMethod: " + (classNode.outerMethod == null ? "null"
|
||||||
|
: (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " "
|
||||||
|
+ UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc)))
|
||||||
|
+ "\n");
|
||||||
|
if (classNode.outerClass != null)
|
||||||
|
ctx.next("// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n");
|
||||||
|
ctx.next("// #InnerClasses:\n");
|
||||||
|
if (classNode.innerClasses != null) {
|
||||||
|
String ics = "";
|
||||||
|
for (InnerClassNode icn : classNode.innerClasses) {
|
||||||
|
ics += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " "
|
||||||
|
+ UnicodeUtils.escapeWithSpaces(icn.outerName) + " "
|
||||||
|
+ UnicodeUtils.escapeWithSpaces(icn.innerName)
|
||||||
|
+ (icn.access == 0 ? "" : " " + ClassUtil.getAccessFlagsFull(icn.access).trim()) + "\n";
|
||||||
|
}
|
||||||
|
ctx.next(ics);
|
||||||
|
}
|
||||||
|
ctx.next(ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(classNode.name)
|
||||||
|
+ " ");
|
||||||
|
ctx.next("extends " + UnicodeUtils.escapeWithSpaces(classNode.superName) + " ");
|
||||||
|
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
|
||||||
|
String interfaceStr = "";
|
||||||
|
for (String interfc : classNode.interfaces) {
|
||||||
|
if (interfaceStr.isEmpty()) {
|
||||||
|
interfaceStr += UnicodeUtils.escapeWithSpaces(interfc);
|
||||||
|
} else {
|
||||||
|
interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(interfc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!interfaceStr.isEmpty())
|
||||||
|
ctx.next("implements " + interfaceStr + " ");
|
||||||
|
}
|
||||||
|
ctx.next("{\n// #SourceFile: "
|
||||||
|
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile))
|
||||||
|
+ "\n\n// #Fields\n");
|
||||||
|
ctx.next(doFields(classNode.fields, nodeToFind, lineFound));
|
||||||
|
ctx.next("\n// #Methods\n");
|
||||||
|
ctx.next(doMethods(classNode.methods, classNode.name, nodeToFind, lineFound));
|
||||||
|
ctx.next("}\n");
|
||||||
|
return new DisassembleTuple(ctx.finish(), lineFound.get());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": "
|
||||||
|
+ e.getMessage() + "\n"
|
||||||
|
+ Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "")
|
||||||
|
+ "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doAnnotations(List<AnnotationNode> annotations) {
|
||||||
|
if (annotations == null)
|
||||||
|
return "";
|
||||||
|
StringContext ctx = new StringContext(annotations.size());
|
||||||
|
for (AnnotationNode annotationNode : annotations) {
|
||||||
|
String s = "@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
||||||
|
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
||||||
|
s += " (";
|
||||||
|
boolean valBefore = true;
|
||||||
|
for (Object o : annotationNode.values) {
|
||||||
|
if (valBefore) {
|
||||||
|
s += o + " = [";
|
||||||
|
valBefore = false;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (o instanceof String[]) {
|
||||||
|
String[] arr = (String[]) o;
|
||||||
|
boolean w8ing = false;
|
||||||
|
for (String rofl : arr) {
|
||||||
|
if (!w8ing) {
|
||||||
|
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||||
|
w8ing = true;
|
||||||
|
} else {
|
||||||
|
s += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s += ", ";
|
||||||
|
} else if (o instanceof List) {
|
||||||
|
List list = (List) o;
|
||||||
|
s += "{ ";
|
||||||
|
for (Object obj : list) {
|
||||||
|
if (obj instanceof String[]) {
|
||||||
|
String[] arr = (String[]) obj;
|
||||||
|
boolean w8ing = false;
|
||||||
|
for (String rofl : arr) {
|
||||||
|
if (!w8ing) {
|
||||||
|
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||||
|
w8ing = true;
|
||||||
|
} else {
|
||||||
|
s += UnicodeUtils.escapeWithSpaces(rofl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||||
|
}
|
||||||
|
s += ", ";
|
||||||
|
}
|
||||||
|
s = s.substring(0, s.length() - 2);
|
||||||
|
s += " }]";
|
||||||
|
} else if (o instanceof String) {
|
||||||
|
s += "\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"], ";
|
||||||
|
} else {
|
||||||
|
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
||||||
|
}
|
||||||
|
valBefore = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s.endsWith(", "))
|
||||||
|
s = s.substring(0, s.length() - 2);
|
||||||
|
s += ")";
|
||||||
|
}
|
||||||
|
s += "\n";
|
||||||
|
ctx.next(s);
|
||||||
|
}
|
||||||
|
return ctx.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doMethods(List<MethodNode> methods, String className, Object nodeToFind,
|
||||||
|
AtomicInteger lineFound) throws InterruptedException, ExecutionException {
|
||||||
|
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>() {
|
||||||
|
@Override
|
||||||
|
public String call() throws Exception {
|
||||||
|
String ms = "";
|
||||||
|
try {
|
||||||
|
ms += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
|
||||||
|
if (mn.signature != null)
|
||||||
|
ms += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(mn.signature) + "\n";
|
||||||
|
String[] dis = disassembleMethod(className, mn);
|
||||||
|
ms += dis[2];
|
||||||
|
ms += dis[1];
|
||||||
|
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) {
|
||||||
|
for (AnnotationNode annotationNode : mn.visibleAnnotations) {
|
||||||
|
ms += "\t@" + annotationNode.desc;
|
||||||
|
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
||||||
|
ms += " (";
|
||||||
|
boolean valBefore = true;
|
||||||
|
for (Object o : annotationNode.values) {
|
||||||
|
if (valBefore) {
|
||||||
|
ms += o + " = [";
|
||||||
|
valBefore = false;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (o instanceof String[]) {
|
||||||
|
String[] arr = (String[]) o;
|
||||||
|
boolean w8ing = false;
|
||||||
|
for (String rofl : arr) {
|
||||||
|
if (!w8ing) {
|
||||||
|
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||||
|
w8ing = true;
|
||||||
|
} else {
|
||||||
|
ms += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ms += ", ";
|
||||||
|
} else if (o instanceof List) {
|
||||||
|
List list = (List) o;
|
||||||
|
ms += "{ ";
|
||||||
|
for (Object obj : list) {
|
||||||
|
if (obj instanceof String[]) {
|
||||||
|
String[] arr = (String[]) obj;
|
||||||
|
boolean w8ing = false;
|
||||||
|
for (String rofl : arr) {
|
||||||
|
if (!w8ing) {
|
||||||
|
ms += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
||||||
|
w8ing = true;
|
||||||
|
} else {
|
||||||
|
ms += UnicodeUtils.escapeWithSpaces(rofl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ms += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||||
|
}
|
||||||
|
ms += ", ";
|
||||||
|
}
|
||||||
|
ms = ms.substring(0, ms.length() - 2);
|
||||||
|
ms += " }]";
|
||||||
|
} else {
|
||||||
|
ms += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
||||||
|
}
|
||||||
|
valBefore = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ms.endsWith(", "))
|
||||||
|
ms = ms.substring(0, ms.length() - 2);
|
||||||
|
ms += ")";
|
||||||
|
}
|
||||||
|
ms += "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mn.equals(nodeToFind)) {
|
||||||
|
lineFound.set(ms.split("\\n").length);
|
||||||
|
}
|
||||||
|
ms += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name)
|
||||||
|
+ " " + UnicodeUtils.escapeWithSpaces(mn.desc) + " ";
|
||||||
|
if (mn.exceptions != null && !mn.exceptions.isEmpty()) {
|
||||||
|
String exceptionStr = "";
|
||||||
|
for (String exc : mn.exceptions) {
|
||||||
|
if (exceptionStr.isEmpty()) {
|
||||||
|
exceptionStr += UnicodeUtils.escapeWithSpaces(exc);
|
||||||
|
} else {
|
||||||
|
exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exceptionStr.isEmpty())
|
||||||
|
ms += "throws " + exceptionStr + " ";
|
||||||
|
}
|
||||||
|
ms += "{\n";
|
||||||
|
ms += dis[0];
|
||||||
|
ms += "\t}\n\n";
|
||||||
|
} catch (Exception e) {
|
||||||
|
ms += "\t\t// Method couldn't be disassembled:\n\t\t// " + e.getClass().getName() + ": "
|
||||||
|
+ e.getMessage() + "\n" + Arrays.toString(e.getStackTrace())
|
||||||
|
.replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "")
|
||||||
|
+ "\n\t}\n\n";
|
||||||
|
}
|
||||||
|
return ms;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
StringContext ctx = new StringContext(futures.length);
|
||||||
|
for (Future<String> f : futures) {
|
||||||
|
ctx.next(f.get());
|
||||||
|
}
|
||||||
|
return ctx.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String doFields(List<FieldNode> fields, Object nodeToFind, AtomicInteger lineFound) {
|
||||||
|
StringContext ctx = new StringContext(fields.size());
|
||||||
|
for (FieldNode fn : fields) {
|
||||||
String s = "";
|
String s = "";
|
||||||
s += "// #Annotations:\n";
|
if (fn.signature != null)
|
||||||
if (classNode.visibleAnnotations != null && !classNode.visibleAnnotations.isEmpty()) {
|
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n";
|
||||||
for (AnnotationNode annotationNode : classNode.visibleAnnotations) {
|
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) {
|
||||||
s += "@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
for (AnnotationNode annotationNode : fn.visibleAnnotations) {
|
||||||
|
s += "\t@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
||||||
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
||||||
s += " (";
|
s += " (";
|
||||||
boolean valBefore = true;
|
boolean valBefore = true;
|
||||||
@@ -123,8 +370,6 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s = s.substring(0, s.length() - 2);
|
s = s.substring(0, s.length() - 2);
|
||||||
s += " }]";
|
s += " }]";
|
||||||
} else if (o instanceof String) {
|
|
||||||
s += "\"" + UnicodeUtils.escapeWithSpaces((String) o) + "\"], ";
|
|
||||||
} else {
|
} else {
|
||||||
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
||||||
}
|
}
|
||||||
@@ -138,262 +383,75 @@ public class Disassembler {
|
|||||||
s += "\n";
|
s += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s += "// #Class v:" + classNode.version + "\n";
|
if (fn.equals(nodeToFind)) {
|
||||||
if (classNode.signature != null)
|
lineFound.set(s.split("\\n").length);
|
||||||
s += "// #Signature: " + UnicodeUtils.escapeWithSpaces(classNode.signature) + "\n";
|
|
||||||
if (classNode.outerMethod != null)
|
|
||||||
s += "// #OuterMethod: " + (classNode.outerMethod == null ? "null"
|
|
||||||
: (UnicodeUtils.escapeWithSpaces(classNode.outerMethod) + " "
|
|
||||||
+ UnicodeUtils.escapeWithSpaces(classNode.outerMethodDesc)))
|
|
||||||
+ "\n";
|
|
||||||
if (classNode.outerClass != null)
|
|
||||||
s += "// #OuterClass: " + UnicodeUtils.escapeWithSpaces(classNode.outerClass) + "\n";
|
|
||||||
s += "// #InnerClasses:\n";
|
|
||||||
if (classNode.innerClasses != null) {
|
|
||||||
for (InnerClassNode icn : classNode.innerClasses) {
|
|
||||||
s += "// " + UnicodeUtils.escapeWithSpaces(icn.name) + " "
|
|
||||||
+ UnicodeUtils.escapeWithSpaces(icn.outerName) + " "
|
|
||||||
+ UnicodeUtils.escapeWithSpaces(icn.innerName)
|
|
||||||
+ (icn.access == 0 ? "" : " " + ClassUtil.getAccessFlagsFull(icn.access).trim()) + "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
s += ClassUtil.getAccessFlagsClass(classNode.access) + UnicodeUtils.escapeWithSpaces(classNode.name) + " ";
|
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient")
|
||||||
s += "extends " + UnicodeUtils.escapeWithSpaces(classNode.superName) + " ";
|
+ UnicodeUtils.escapeWithSpaces(fn.desc) + " " + UnicodeUtils.escapeWithSpaces(fn.name);
|
||||||
if (classNode.interfaces != null && !classNode.interfaces.isEmpty()) {
|
if (fn.value != null) {
|
||||||
String interfaceStr = "";
|
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true);
|
||||||
for (String interfc : classNode.interfaces) {
|
|
||||||
if (interfaceStr.isEmpty()) {
|
|
||||||
interfaceStr += UnicodeUtils.escapeWithSpaces(interfc);
|
|
||||||
} else {
|
|
||||||
interfaceStr += ", " + UnicodeUtils.escapeWithSpaces(interfc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!interfaceStr.isEmpty())
|
|
||||||
s += "implements " + interfaceStr + " ";
|
|
||||||
}
|
}
|
||||||
s += "{\n// #SourceFile: "
|
s += "\n";
|
||||||
+ (classNode.sourceFile == null ? "null" : UnicodeUtils.escape(classNode.sourceFile))
|
ctx.next(s);
|
||||||
+ "\n\n// #Fields\n";
|
|
||||||
for (FieldNode fn : classNode.fields) {
|
|
||||||
if (fn.signature != null)
|
|
||||||
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(fn.signature) + "\n";
|
|
||||||
if (fn.visibleAnnotations != null && !fn.visibleAnnotations.isEmpty()) {
|
|
||||||
for (AnnotationNode annotationNode : fn.visibleAnnotations) {
|
|
||||||
s += "\t@" + UnicodeUtils.escapeWithSpaces(annotationNode.desc);
|
|
||||||
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
|
||||||
s += " (";
|
|
||||||
boolean valBefore = true;
|
|
||||||
for (Object o : annotationNode.values) {
|
|
||||||
if (valBefore) {
|
|
||||||
s += o + " = [";
|
|
||||||
valBefore = false;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if (o instanceof String[]) {
|
|
||||||
String[] arr = (String[]) o;
|
|
||||||
boolean w8ing = false;
|
|
||||||
for (String rofl : arr) {
|
|
||||||
if (!w8ing) {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
|
||||||
w8ing = true;
|
|
||||||
} else {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s += ", ";
|
|
||||||
} else if (o instanceof List) {
|
|
||||||
List list = (List) o;
|
|
||||||
s += "{ ";
|
|
||||||
for (Object obj : list) {
|
|
||||||
if (obj instanceof String[]) {
|
|
||||||
String[] arr = (String[]) obj;
|
|
||||||
boolean w8ing = false;
|
|
||||||
for (String rofl : arr) {
|
|
||||||
if (!w8ing) {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
|
||||||
w8ing = true;
|
|
||||||
} else {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
|
||||||
}
|
|
||||||
s += ", ";
|
|
||||||
}
|
|
||||||
s = s.substring(0, s.length() - 2);
|
|
||||||
s += " }]";
|
|
||||||
} else {
|
|
||||||
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
|
||||||
}
|
|
||||||
valBefore = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s.endsWith(", "))
|
|
||||||
s = s.substring(0, s.length() - 2);
|
|
||||||
s += ")";
|
|
||||||
}
|
|
||||||
s += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fn.equals(nodeToFind)) {
|
|
||||||
lineFound = s.split("\\n").length;
|
|
||||||
}
|
|
||||||
s += "\t" + ClassUtil.getAccessFlagsFull(fn.access).replace("varargs", "transient")
|
|
||||||
+ UnicodeUtils.escapeWithSpaces(fn.desc) + " " + UnicodeUtils.escapeWithSpaces(fn.name);
|
|
||||||
if (fn.value != null) {
|
|
||||||
s += " = " + ClassUtil.getDecompiledValue(fn.value, fn.desc, true);
|
|
||||||
}
|
|
||||||
s += "\n";
|
|
||||||
}
|
|
||||||
s += "\n// #Methods\n";
|
|
||||||
for (MethodNode mn : classNode.methods) {
|
|
||||||
try {
|
|
||||||
s += "\t// #Max: l:" + mn.maxLocals + " s:" + mn.maxStack + "\n";
|
|
||||||
if (mn.signature != null)
|
|
||||||
s += "\t// #Signature: " + UnicodeUtils.escapeWithSpaces(mn.signature) + "\n";
|
|
||||||
String[] dis = disassembleMethod(classNode.name, mn);
|
|
||||||
s += dis[2];
|
|
||||||
s += dis[1];
|
|
||||||
if (mn.visibleAnnotations != null && !mn.visibleAnnotations.isEmpty()) {
|
|
||||||
for (AnnotationNode annotationNode : mn.visibleAnnotations) {
|
|
||||||
s += "\t@" + annotationNode.desc;
|
|
||||||
if (annotationNode.values != null && !annotationNode.values.isEmpty()) {
|
|
||||||
s += " (";
|
|
||||||
boolean valBefore = true;
|
|
||||||
for (Object o : annotationNode.values) {
|
|
||||||
if (valBefore) {
|
|
||||||
s += o + " = [";
|
|
||||||
valBefore = false;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if (o instanceof String[]) {
|
|
||||||
String[] arr = (String[]) o;
|
|
||||||
boolean w8ing = false;
|
|
||||||
for (String rofl : arr) {
|
|
||||||
if (!w8ing) {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
|
||||||
w8ing = true;
|
|
||||||
} else {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "]";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s += ", ";
|
|
||||||
} else if (o instanceof List) {
|
|
||||||
List list = (List) o;
|
|
||||||
s += "{ ";
|
|
||||||
for (Object obj : list) {
|
|
||||||
if (obj instanceof String[]) {
|
|
||||||
String[] arr = (String[]) obj;
|
|
||||||
boolean w8ing = false;
|
|
||||||
for (String rofl : arr) {
|
|
||||||
if (!w8ing) {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl) + "/";
|
|
||||||
w8ing = true;
|
|
||||||
} else {
|
|
||||||
s += UnicodeUtils.escapeWithSpaces(rofl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
|
||||||
}
|
|
||||||
s += ", ";
|
|
||||||
}
|
|
||||||
s = s.substring(0, s.length() - 2);
|
|
||||||
s += " }]";
|
|
||||||
} else {
|
|
||||||
s += "(" + o.getClass().getName().replace(".", "/") + ") " + o + "], ";
|
|
||||||
}
|
|
||||||
valBefore = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s.endsWith(", "))
|
|
||||||
s = s.substring(0, s.length() - 2);
|
|
||||||
s += ")";
|
|
||||||
}
|
|
||||||
s += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mn.equals(nodeToFind)) {
|
|
||||||
lineFound = s.split("\\n").length;
|
|
||||||
}
|
|
||||||
s += "\t" + ClassUtil.getAccessFlagsFull(mn.access) + UnicodeUtils.escapeWithSpaces(mn.name) + " "
|
|
||||||
+ UnicodeUtils.escapeWithSpaces(mn.desc) + " ";
|
|
||||||
if (mn.exceptions != null && !mn.exceptions.isEmpty()) {
|
|
||||||
String exceptionStr = "";
|
|
||||||
for (String exc : mn.exceptions) {
|
|
||||||
if (exceptionStr.isEmpty()) {
|
|
||||||
exceptionStr += UnicodeUtils.escapeWithSpaces(exc);
|
|
||||||
} else {
|
|
||||||
exceptionStr += ", " + UnicodeUtils.escapeWithSpaces(exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!exceptionStr.isEmpty())
|
|
||||||
s += "throws " + exceptionStr + " ";
|
|
||||||
}
|
|
||||||
s += "{\n";
|
|
||||||
s += dis[0];
|
|
||||||
s += "\t}\n\n";
|
|
||||||
} catch (Exception e) {
|
|
||||||
s += "\t\t// Method couldn't be disassembled:\n\t\t// "
|
|
||||||
+ e.getClass().getName() + ": " + e.getMessage() + "\n" + Arrays.toString(e.getStackTrace())
|
|
||||||
.replace(", ", "\n\t\t// \tat ").replace("[", "\t\t// \tat ").replace("]", "")
|
|
||||||
+ "\n\t}\n\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s += "}\n";
|
|
||||||
return new DisassembleTuple(s, lineFound);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
return new DisassembleTuple("Class couldn't be decompiled:\n" + e.getClass().getName() + ": "
|
|
||||||
+ e.getMessage() + "\n"
|
|
||||||
+ Arrays.toString(e.getStackTrace()).replace(", ", "\n\tat ").replace("[", "\tat ").replace("]", "")
|
|
||||||
+ "\n");
|
|
||||||
}
|
}
|
||||||
|
return ctx.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] disassembleMethod(String className, MethodNode mn) {
|
private static String[] disassembleMethod(String className, MethodNode mn) {
|
||||||
HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
|
HashMap<Label, Integer> labels = new HashMap<Label, Integer>();
|
||||||
String s = "";
|
String localVarTable;
|
||||||
String localVarTable = "";
|
String tryCatchTable;
|
||||||
String tryCatchTable = "";
|
|
||||||
for (AbstractInsnNode n : mn.instructions.toArray()) {
|
for (AbstractInsnNode n : mn.instructions.toArray()) {
|
||||||
if (n instanceof LabelNode) {
|
if (n instanceof LabelNode) {
|
||||||
labels.put(((LabelNode) n).getLabel(), labels.size() + 1);
|
labels.put(((LabelNode) n).getLabel(), labels.size() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mn.localVariables != null && !mn.localVariables.isEmpty()) {
|
if (mn.localVariables != null && !mn.localVariables.isEmpty()) {
|
||||||
localVarTable = "\t// #LocalVars:\n";
|
List<LocalVariableNode> list = mn.localVariables;
|
||||||
for (LocalVariableNode lvn : mn.localVariables) {
|
StringContext ctx = new StringContext(list.size() + 1);
|
||||||
localVarTable += "\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": "
|
ctx.next("\t// #LocalVars:\n");
|
||||||
|
for (LocalVariableNode lvn : list) {
|
||||||
|
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(lvn.name) + ": "
|
||||||
+ UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" + lvn.index + " s:"
|
+ UnicodeUtils.escapeWithSpaces(lvn.desc) + " i:" + lvn.index + " s:"
|
||||||
+ labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:"
|
+ labels.get(lvn.start.getLabel()) + " e:" + labels.get(lvn.end.getLabel()) + " sig:"
|
||||||
+ UnicodeUtils.escapeWithSpaces(lvn.signature) + "\n";
|
+ UnicodeUtils.escapeWithSpaces(lvn.signature) + "\n");
|
||||||
}
|
}
|
||||||
}
|
localVarTable = ctx.finish();
|
||||||
|
} else
|
||||||
|
localVarTable = "";
|
||||||
if (mn.tryCatchBlocks != null && !mn.tryCatchBlocks.isEmpty()) {
|
if (mn.tryCatchBlocks != null && !mn.tryCatchBlocks.isEmpty()) {
|
||||||
tryCatchTable = "\t// #TryCatch:\n";
|
List<TryCatchBlockNode> list = mn.tryCatchBlocks;
|
||||||
|
StringContext ctx = new StringContext(list.size() + 1);
|
||||||
|
ctx.next("\t// #TryCatch:\n");
|
||||||
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
|
for (TryCatchBlockNode tcbn : mn.tryCatchBlocks) {
|
||||||
tryCatchTable += "\t// " + UnicodeUtils.escapeWithSpaces(tcbn.type) + " s:"
|
ctx.next("\t// " + UnicodeUtils.escapeWithSpaces(tcbn.type) + " s:" + labels.get(tcbn.start.getLabel())
|
||||||
+ labels.get(tcbn.start.getLabel()) + " e:" + labels.get(tcbn.end.getLabel()) + " h:"
|
+ " e:" + labels.get(tcbn.end.getLabel()) + " h:" + labels.get(tcbn.handler.getLabel()) + "\n");
|
||||||
+ labels.get(tcbn.handler.getLabel()) + "\n";
|
|
||||||
}
|
}
|
||||||
|
tryCatchTable = ctx.finish();
|
||||||
|
} else
|
||||||
|
tryCatchTable = "";
|
||||||
|
AbstractInsnNode[] insns = mn.instructions.toArray();
|
||||||
|
StringContext ctx = new StringContext(insns.length);
|
||||||
|
for (AbstractInsnNode n : insns) {
|
||||||
|
ctx.next(disassembleInstruction(n, labels));
|
||||||
}
|
}
|
||||||
for (AbstractInsnNode n : mn.instructions.toArray()) {
|
return new String[] { ctx.finish(), localVarTable, tryCatchTable };
|
||||||
s += disassembleInstruction(n, labels);
|
|
||||||
}
|
|
||||||
return new String[] { s, localVarTable, tryCatchTable };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) {
|
public static final HashMap<Class, InstructionInterface> iiMap = new HashMap<>();
|
||||||
if (FieldInsnNode.class.isInstance(n)) {
|
|
||||||
|
static {
|
||||||
|
iiMap.put(FieldInsnNode.class, (n, labels) -> {
|
||||||
FieldInsnNode node = (FieldInsnNode) n;
|
FieldInsnNode node = (FieldInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
||||||
} else if (LabelNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(LabelNode.class, (n, labels) -> {
|
||||||
LabelNode node = (LabelNode) n;
|
LabelNode node = (LabelNode) n;
|
||||||
return "\t\t// label " + labels.get(node.getLabel()) + "\n";
|
return "\t\t// label " + labels.get(node.getLabel()) + "\n";
|
||||||
} else if (FrameNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(FrameNode.class, (n, labels) -> {
|
||||||
FrameNode node = (FrameNode) n;
|
FrameNode node = (FrameNode) n;
|
||||||
String type = "";
|
String type = "";
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
@@ -470,10 +528,12 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "\n";
|
s += "\n";
|
||||||
return s;
|
return s;
|
||||||
} else if (LineNumberNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(LineNumberNode.class, (n, labels) -> {
|
||||||
LineNumberNode node = (LineNumberNode) n;
|
LineNumberNode node = (LineNumberNode) n;
|
||||||
return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n";
|
return "\t\t// line " + node.line + " " + labels.get(node.start.getLabel()) + "\n";
|
||||||
} else if (InvokeDynamicInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(InvokeDynamicInsnNode.class, (n, labels) -> {
|
||||||
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
|
InvokeDynamicInsnNode node = (InvokeDynamicInsnNode) n;
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: "
|
String s = "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " [\n\t\t\tname: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: "
|
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n\t\t\tdesc: "
|
||||||
@@ -484,7 +544,7 @@ public class Disassembler {
|
|||||||
+ node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(node.bsm.getTag())
|
+ node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(node.bsm.getTag())
|
||||||
+ "\n\t\t\t]\n\t\t\targs: [\n";
|
+ "\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 instanceof Type) {
|
||||||
Type type = (Type) l;
|
Type type = (Type) l;
|
||||||
int valueBegin = type.valueBegin;
|
int valueBegin = type.valueBegin;
|
||||||
int valueEnd = type.valueEnd;
|
int valueEnd = type.valueEnd;
|
||||||
@@ -494,7 +554,7 @@ public class Disassembler {
|
|||||||
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
|
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
|
||||||
+ ClassUtil.getDecompiledValue(buf, "");
|
+ ClassUtil.getDecompiledValue(buf, "");
|
||||||
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 instanceof Handle) {
|
||||||
Handle h = (Handle) l;
|
Handle h = (Handle) l;
|
||||||
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: "
|
s += "\t\t\t\tHandle: [\n\t\t\t\t\tname: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: "
|
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: "
|
||||||
@@ -508,31 +568,26 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "\t\t\t]\n\t\t]\n";
|
s += "\t\t\t]\n\t\t]\n";
|
||||||
return s;
|
return s;
|
||||||
} else if (MethodInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(MethodInsnNode.class, (n, labels) -> {
|
||||||
MethodInsnNode node = (MethodInsnNode) n;
|
MethodInsnNode node = (MethodInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + UnicodeUtils.escapeWithSpaces(node.owner) + "/"
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
+ UnicodeUtils.escapeWithSpaces(node.name).replace("/", "\\u002F") + "\n";
|
||||||
} else if (TypeInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(TypeInsnNode.class, (n, labels) -> {
|
||||||
TypeInsnNode node = (TypeInsnNode) n;
|
TypeInsnNode node = (TypeInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n";
|
+ UnicodeUtils.escapeWithSpaces(node.desc) + "\n";
|
||||||
} else if (MultiANewArrayInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(MultiANewArrayInsnNode.class, (n, labels) -> {
|
||||||
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
|
MultiANewArrayInsnNode node = (MultiANewArrayInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims + "\n";
|
+ UnicodeUtils.escapeWithSpaces(node.desc) + " " + node.dims + "\n";
|
||||||
} else if (LdcInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(LdcInsnNode.class, (n, labels) -> {
|
||||||
LdcInsnNode node = (LdcInsnNode) n;
|
LdcInsnNode node = (LdcInsnNode) n;
|
||||||
switch (node.cst.getClass().getSimpleName()) {
|
if (node.cst instanceof Type) {
|
||||||
case "String":
|
|
||||||
case "Double":
|
|
||||||
case "Integer":
|
|
||||||
case "Float":
|
|
||||||
case "Long": {
|
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
|
||||||
+ ClassUtil.getDecompiledValue(node.cst, "") + "\n";
|
|
||||||
}
|
|
||||||
case "Type": {
|
|
||||||
Type type = (Type) node.cst;
|
Type type = (Type) node.cst;
|
||||||
int valueBegin = type.valueBegin;
|
int valueBegin = type.valueBegin;
|
||||||
int valueEnd = type.valueEnd;
|
int valueEnd = type.valueEnd;
|
||||||
@@ -543,19 +598,20 @@ public class Disassembler {
|
|||||||
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
||||||
s += "\n\t\t]\n";
|
s += "\n\t\t]\n";
|
||||||
return s;
|
return s;
|
||||||
|
} else {
|
||||||
|
return "\t\t" + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
||||||
|
+ ClassUtil.getDecompiledValue(node.cst, "") + "\n";
|
||||||
}
|
}
|
||||||
default: {
|
});
|
||||||
return "\t\tUNRESOLVED TYPE! " + OpcodesReverse.reverseOpcode(node.getOpcode()) + " "
|
iiMap.put(VarInsnNode.class, (n, labels) -> {
|
||||||
+ node.cst.getClass().getName().replace(".", "/") + " " + node.cst + "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (VarInsnNode.class.isInstance(n)) {
|
|
||||||
VarInsnNode node = (VarInsnNode) n;
|
VarInsnNode node = (VarInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n";
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + "\n";
|
||||||
} else if (InsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(InsnNode.class, (n, labels) -> {
|
||||||
InsnNode node = (InsnNode) n;
|
InsnNode node = (InsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n";
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + "\n";
|
||||||
} else if (IntInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(IntInsnNode.class, (n, labels) -> {
|
||||||
IntInsnNode node = (IntInsnNode) n;
|
IntInsnNode node = (IntInsnNode) n;
|
||||||
if (n.getOpcode() == Opcodes.NEWARRAY) {
|
if (n.getOpcode() == Opcodes.NEWARRAY) {
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
||||||
@@ -563,11 +619,13 @@ public class Disassembler {
|
|||||||
} else {
|
} else {
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n";
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.operand + "\n";
|
||||||
}
|
}
|
||||||
} else if (JumpInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(JumpInsnNode.class, (n, labels) -> {
|
||||||
JumpInsnNode node = (JumpInsnNode) n;
|
JumpInsnNode node = (JumpInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel())
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + labels.get(node.label.getLabel())
|
||||||
+ "\n";
|
+ "\n";
|
||||||
} else if (TableSwitchInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(TableSwitchInsnNode.class, (n, labels) -> {
|
||||||
TableSwitchInsnNode node = (TableSwitchInsnNode) n;
|
TableSwitchInsnNode node = (TableSwitchInsnNode) n;
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tmin: " + node.min
|
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\tmax: " + node.max + "\n\t\t\tdefault: " + labels.get(node.dflt.getLabel())
|
||||||
@@ -577,7 +635,8 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "\t\t\t]\n\t\t]\n";
|
s += "\t\t\t]\n\t\t]\n";
|
||||||
return s;
|
return s;
|
||||||
} else if (LookupSwitchInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(LookupSwitchInsnNode.class, (n, labels) -> {
|
||||||
LookupSwitchInsnNode node = (LookupSwitchInsnNode) n;
|
LookupSwitchInsnNode node = (LookupSwitchInsnNode) n;
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: "
|
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " [\n\t\t\tdefault: "
|
||||||
+ labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n";
|
+ labels.get(node.dflt.getLabel()) + "\n\t\t\tkeys: [\n";
|
||||||
@@ -590,13 +649,24 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "\t\t\t]\n\t\t]\n";
|
s += "\t\t\t]\n\t\t]\n";
|
||||||
return s;
|
return s;
|
||||||
} else if (IincInsnNode.class.isInstance(n)) {
|
});
|
||||||
|
iiMap.put(IincInsnNode.class, (n, labels) -> {
|
||||||
IincInsnNode node = (IincInsnNode) n;
|
IincInsnNode node = (IincInsnNode) n;
|
||||||
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n";
|
return "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " " + node.var + " " + node.incr + "\n";
|
||||||
} else {
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static interface InstructionInterface {
|
||||||
|
String apply(AbstractInsnNode n, HashMap<Label, Integer> labels);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) {
|
||||||
|
InstructionInterface ii = iiMap.get(n.getClass());
|
||||||
|
if (ii != null)
|
||||||
|
return ii.apply(n, labels);
|
||||||
|
else
|
||||||
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
||||||
+ n.getClass().getSimpleName() + "\n";
|
+ n.getClass().getSimpleName() + "\n";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2857,8 +2857,8 @@ public class JavaAssemblyTokenMaker extends AbstractJFlexCTokenMaker {
|
|||||||
* @see #addToken(int, int, int)
|
* @see #addToken(int, int, int)
|
||||||
*/
|
*/
|
||||||
private void addHyperlinkToken(int start, int end, int tokenType) {
|
private void addHyperlinkToken(int start, int end, int tokenType) {
|
||||||
int so = start + offsetShift;
|
super.addToken(zzBuffer, start, end, tokenType, start + offsetShift, true);
|
||||||
addToken(zzBuffer, start, end, tokenType, so, true);
|
zzStartRead = zzMarkedPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2867,7 +2867,8 @@ public class JavaAssemblyTokenMaker extends AbstractJFlexCTokenMaker {
|
|||||||
* @param tokenType The token's type.
|
* @param tokenType The token's type.
|
||||||
*/
|
*/
|
||||||
private void addToken(int tokenType) {
|
private void addToken(int tokenType) {
|
||||||
addToken(zzStartRead, zzMarkedPos - 1, tokenType);
|
super.addToken(zzBuffer, zzStartRead, zzMarkedPos - 1, tokenType, zzStartRead + offsetShift, false);
|
||||||
|
zzStartRead = zzMarkedPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2877,8 +2878,8 @@ public class JavaAssemblyTokenMaker extends AbstractJFlexCTokenMaker {
|
|||||||
* @see #addHyperlinkToken(int, int, int)
|
* @see #addHyperlinkToken(int, int, int)
|
||||||
*/
|
*/
|
||||||
private void addToken(int start, int end, int tokenType) {
|
private void addToken(int start, int end, int tokenType) {
|
||||||
int so = start + offsetShift;
|
super.addToken(zzBuffer, start, end, tokenType, start + offsetShift, false);
|
||||||
addToken(zzBuffer, start, end, tokenType, so, false);
|
zzStartRead = zzMarkedPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package me.ByteEdit.edit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a quiet fast String concatenation helper class. It appears to be a
|
||||||
|
* lot faster than Java's StringBuilder class, especially for very large
|
||||||
|
* Strings, which will be made by the Disassembler.
|
||||||
|
*/
|
||||||
|
public class StringContext {
|
||||||
|
|
||||||
|
private String[] arrs;
|
||||||
|
private int idx;
|
||||||
|
private int len;
|
||||||
|
|
||||||
|
public StringContext(int amt) {
|
||||||
|
if (amt > 0)
|
||||||
|
arrs = new String[amt];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void next(String s) {
|
||||||
|
len += (arrs[idx++] = s).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String finish() {
|
||||||
|
if (arrs == null)
|
||||||
|
return "";
|
||||||
|
char[] full = new char[len];
|
||||||
|
int off = 0;
|
||||||
|
for (int i = 0; i < idx; i++) {
|
||||||
|
int len = arrs[i].length();
|
||||||
|
arrs[i].getChars(0, len, full, off);
|
||||||
|
off += len;
|
||||||
|
arrs[i] = null;
|
||||||
|
}
|
||||||
|
String s = new String(full);
|
||||||
|
arrs = null;
|
||||||
|
full = null;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -848,10 +848,10 @@ public class Main extends JFrame {
|
|||||||
if (optionBox.chckbxComputeMax.isSelected()) {
|
if (optionBox.chckbxComputeMax.isSelected()) {
|
||||||
computeFlags |= ClassWriter.COMPUTE_MAXS;
|
computeFlags |= ClassWriter.COMPUTE_MAXS;
|
||||||
}
|
}
|
||||||
for (ClassNode element : classes) {
|
for (ClassNode node : classes) {
|
||||||
ClassWriter writer = new ClassWriter(computeFlags);
|
ClassWriter writer = new ClassWriter(computeFlags);
|
||||||
element.accept(writer);
|
node.accept(writer);
|
||||||
output.putNextEntry(new JarEntry(getFullName(element.name)));
|
output.putNextEntry(new JarEntry(getFullName(node.name)));
|
||||||
output.write(writer.toByteArray());
|
output.write(writer.toByteArray());
|
||||||
output.closeEntry();
|
output.closeEntry();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -522,27 +522,27 @@ public class ClassUtil {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final HashMap<Class, DecompilationInterface> diMap = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
diMap.put(String.class, (o, desc, escapeSpaces) -> "\""
|
||||||
|
+ (escapeSpaces ? UnicodeUtils.escapeWithSpaces((String) o) : UnicodeUtils.escape((String) o)) + "\"");
|
||||||
|
diMap.put(Integer.class,
|
||||||
|
(o, desc, escape) -> desc.equals("Z") ? (((int) o) == 0 ? "false" : "true") : o.toString());
|
||||||
|
diMap.put(Long.class, (o, desc, escape) -> o.toString() + "l");
|
||||||
|
diMap.put(Float.class, (o, desc, escape) -> o.toString() + "f");
|
||||||
|
}
|
||||||
|
|
||||||
|
static interface DecompilationInterface {
|
||||||
|
String apply(Object o, String desc, boolean escape);
|
||||||
|
}
|
||||||
|
|
||||||
public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces) {
|
public static String getDecompiledValue(Object o, String desc, boolean escapeSpaces) {
|
||||||
switch (o.getClass().getName()) {
|
DecompilationInterface di = diMap.get(o.getClass());
|
||||||
case "java.lang.String": {
|
if (di != null)
|
||||||
return "\"" + (escapeSpaces ? UnicodeUtils.escapeWithSpaces((String) o) : UnicodeUtils.escape((String) o))
|
return di.apply(o, desc, escapeSpaces);
|
||||||
+ "\"";
|
else
|
||||||
}
|
|
||||||
case "java.lang.Integer": {
|
|
||||||
if (desc.equals("Z")) {
|
|
||||||
return ((int) o) == 0 ? "false" : "true";
|
|
||||||
}
|
|
||||||
return o.toString();
|
return o.toString();
|
||||||
}
|
|
||||||
case "java.lang.Long": {
|
|
||||||
return o.toString() + "l";
|
|
||||||
}
|
|
||||||
case "java.lang.Float": {
|
|
||||||
return o.toString() + "f";
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return o.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getDecompiledValue(Object o, String desc) {
|
public static String getDecompiledValue(Object o, String desc) {
|
||||||
|
|||||||
@@ -82,14 +82,80 @@ public class UnicodeUtils {
|
|||||||
if (s == null) {
|
if (s == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
s = escape(s).replace(" ", "\\u0020");
|
StringBuilder sb = new StringBuilder();
|
||||||
if (s.startsWith("/")) {
|
char[] arr = s.toCharArray();
|
||||||
s = "\\u002F" + s.substring(1);
|
int i = 0;
|
||||||
|
int len = arr.length;
|
||||||
|
boolean addSlash = false;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
if (arr[0] == '/') {
|
||||||
|
sb.append("\\u002F");
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (arr[len - 1] == '/') {
|
||||||
|
addSlash = true;
|
||||||
|
len--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (s.endsWith("/")) {
|
|
||||||
s = s.substring(0, s.length() - 1) + "\\u002F";
|
for (; i < len; i++) {
|
||||||
|
char c = arr[i];
|
||||||
|
switch (c) {
|
||||||
|
case 'Ä':
|
||||||
|
case 'ä':
|
||||||
|
case 'Ö':
|
||||||
|
case 'ö':
|
||||||
|
case 'Ü':
|
||||||
|
case 'ü':
|
||||||
|
case 'ß':
|
||||||
|
case '€':
|
||||||
|
case '©':
|
||||||
|
case '®':
|
||||||
|
case '«':
|
||||||
|
case '»':
|
||||||
|
case '§':
|
||||||
|
case '£':
|
||||||
|
case '¥':
|
||||||
|
sb.append(c);
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
sb.append("\\u0020");
|
||||||
|
break;
|
||||||
|
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:
|
||||||
|
if (c > ' ' && c <= '~') {
|
||||||
|
sb.append(c);
|
||||||
|
} else {
|
||||||
|
sb.append(String.format("\\u%04X", (int) c));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return s;
|
|
||||||
|
if (addSlash)
|
||||||
|
sb.append("\\u002F");
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String escape(String s) {
|
public static String escape(String s) {
|
||||||
@@ -98,63 +164,55 @@ public class UnicodeUtils {
|
|||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (char c : s.toCharArray()) {
|
for (char c : s.toCharArray()) {
|
||||||
if (isPrintable(c)) {
|
switch (c) {
|
||||||
|
case 'Ä':
|
||||||
|
case 'ä':
|
||||||
|
case 'Ö':
|
||||||
|
case 'ö':
|
||||||
|
case 'Ü':
|
||||||
|
case 'ü':
|
||||||
|
case 'ß':
|
||||||
|
case '€':
|
||||||
|
case '©':
|
||||||
|
case '®':
|
||||||
|
case '«':
|
||||||
|
case '»':
|
||||||
|
case '§':
|
||||||
|
case '£':
|
||||||
|
case '¥':
|
||||||
sb.append(c);
|
sb.append(c);
|
||||||
} else {
|
break;
|
||||||
switch (c) {
|
case '\b':
|
||||||
case '\b':
|
sb.append("\\b");
|
||||||
sb.append("\\b");
|
break;
|
||||||
break;
|
case '\t':
|
||||||
case '\t':
|
sb.append("\\t");
|
||||||
sb.append("\\t");
|
break;
|
||||||
break;
|
case '\n':
|
||||||
case '\n':
|
sb.append("\\n");
|
||||||
sb.append("\\n");
|
break;
|
||||||
break;
|
case '\r':
|
||||||
case '\r':
|
sb.append("\\r");
|
||||||
sb.append("\\r");
|
break;
|
||||||
break;
|
case '\f':
|
||||||
case '\f':
|
sb.append("\\f");
|
||||||
sb.append("\\f");
|
break;
|
||||||
break;
|
case '"':
|
||||||
case '"':
|
sb.append("\\\"");
|
||||||
sb.append("\\\"");
|
break;
|
||||||
break;
|
case '\\':
|
||||||
case '\\':
|
sb.append("\\\\");
|
||||||
sb.append("\\\\");
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
if (c >= ' ' && c <= '~') {
|
||||||
|
sb.append(c);
|
||||||
|
} else {
|
||||||
sb.append(String.format("\\u%04X", (int) c));
|
sb.append(String.format("\\u%04X", (int) c));
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sb.toString();
|
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 <= '~';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user