mirror of
https://github.com/SuspiciousActivity/ByteEdit.git
synced 2026-08-13 17:56:17 +00:00
New stuff
This commit is contained in:
1 parent
6b66ff27e2
commit
c91d8ccada
13 files changed
+3914
-3060
No files matched your search
@@ -3,46 +3,16 @@ package me.ByteEdit.boxes;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.KeyStroke;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.tools.FileObject;
|
|
||||||
import javax.tools.JavaCompiler;
|
|
||||||
import javax.tools.JavaCompiler.CompilationTask;
|
|
||||||
import javax.tools.JavaFileManager;
|
|
||||||
import javax.tools.JavaFileObject;
|
|
||||||
import javax.tools.JavaFileObject.Kind;
|
|
||||||
import javax.tools.SimpleJavaFileObject;
|
|
||||||
import javax.tools.StandardJavaFileManager;
|
|
||||||
import javax.tools.ToolProvider;
|
|
||||||
|
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||||
import org.fife.ui.rtextarea.RTextScrollPane;
|
import org.fife.ui.rtextarea.RTextScrollPane;
|
||||||
import org.objectweb.asm.ClassReader;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
|
|
||||||
import me.ByteEdit.edit.Disassembler;
|
|
||||||
import me.ByteEdit.main.Main;
|
import me.ByteEdit.main.Main;
|
||||||
|
|
||||||
public class CompilationSuccess extends JFrame {
|
public class CompilationSuccess extends JFrame {
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public class GlobalSearchBox extends JFrame {
|
|||||||
openBox.model.clear();
|
openBox.model.clear();
|
||||||
Set<Info> set = new HashSet<>();
|
Set<Info> set = new HashSet<>();
|
||||||
if (!txtString.getText().isEmpty()) {
|
if (!txtString.getText().isEmpty()) {
|
||||||
String str = txtString.getText();
|
String str = UnicodeUtils.unescape(txtString.getText());
|
||||||
if (ignoreCase) {
|
if (ignoreCase) {
|
||||||
str = str.toLowerCase();
|
str = str.toLowerCase();
|
||||||
}
|
}
|
||||||
@@ -162,19 +162,24 @@ public class GlobalSearchBox extends JFrame {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String owner = UnicodeUtils.unescape(txtOwner.getText());
|
String owner = UnicodeUtils.unescape(txtOwner.getText());
|
||||||
|
boolean wildCardOwner = owner.isEmpty();
|
||||||
String name = UnicodeUtils.unescape(txtName.getText());
|
String name = UnicodeUtils.unescape(txtName.getText());
|
||||||
|
boolean wildCardName = name.isEmpty();
|
||||||
String desc = UnicodeUtils.unescape(txtDesc.getText());
|
String desc = UnicodeUtils.unescape(txtDesc.getText());
|
||||||
|
boolean wildCardDesc = desc.isEmpty();
|
||||||
for (ClassNode cn : Main.classNodes.values()) {
|
for (ClassNode cn : Main.classNodes.values()) {
|
||||||
for (MethodNode mn : cn.methods) {
|
for (MethodNode mn : cn.methods) {
|
||||||
for (AbstractInsnNode insn : mn.instructions.toArray()) {
|
for (AbstractInsnNode insn : mn.instructions.toArray()) {
|
||||||
if (insn instanceof FieldInsnNode) {
|
if (insn instanceof FieldInsnNode) {
|
||||||
if (((FieldInsnNode) insn).owner.equals(owner) && ((FieldInsnNode) insn).name.equals(name)
|
if ((wildCardOwner || ((FieldInsnNode) insn).owner.equals(owner))
|
||||||
&& ((FieldInsnNode) insn).desc.equals(desc)) {
|
&& (wildCardName || ((FieldInsnNode) insn).name.equals(name))
|
||||||
|
&& (wildCardDesc || ((FieldInsnNode) insn).desc.equals(desc))) {
|
||||||
set.add(new Info(cn.name, mn.name, mn.desc, mn));
|
set.add(new Info(cn.name, mn.name, mn.desc, mn));
|
||||||
}
|
}
|
||||||
} else if (insn instanceof MethodInsnNode) {
|
} else if (insn instanceof MethodInsnNode) {
|
||||||
if (((MethodInsnNode) insn).owner.equals(owner) && ((MethodInsnNode) insn).name.equals(name)
|
if ((wildCardOwner || ((MethodInsnNode) insn).owner.equals(owner))
|
||||||
&& ((MethodInsnNode) insn).desc.equals(desc)) {
|
&& (wildCardName || ((MethodInsnNode) insn).name.equals(name))
|
||||||
|
&& (wildCardDesc || ((MethodInsnNode) insn).desc.equals(desc))) {
|
||||||
set.add(new Info(cn.name, mn.name, mn.desc, mn));
|
set.add(new Info(cn.name, mn.name, mn.desc, mn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import javax.swing.event.ListSelectionEvent;
|
|||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.text.BadLocationException;
|
import javax.swing.text.BadLocationException;
|
||||||
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
import org.objectweb.asm.tree.MethodNode;
|
import org.objectweb.asm.tree.MethodNode;
|
||||||
|
|
||||||
import me.ByteEdit.main.Main;
|
import me.ByteEdit.main.Main;
|
||||||
@@ -79,7 +78,7 @@ public class GlobalSearchOpenBox extends JFrame {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.desc = desc;
|
this.desc = desc;
|
||||||
this.mn = mn;
|
this.mn = mn;
|
||||||
nodePath = owner + ".class";
|
nodePath = Main.getFullName(owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class RenameBox extends JFrame {
|
|||||||
JOptionPane.showMessageDialog(null, "Desc not set!", "Error!", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, "Desc not set!", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ClassNode clazz = Main.classNodes.get(className + ".class");
|
ClassNode clazz = Main.classNodes.get(Main.getFullName(className));
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(null, "ClassNode not found!", "Error!", JOptionPane.ERROR_MESSAGE);
|
||||||
return;
|
return;
|
||||||
@@ -94,7 +94,7 @@ public class RenameBox extends JFrame {
|
|||||||
if (newDesc.startsWith("(")) { // method
|
if (newDesc.startsWith("(")) { // method
|
||||||
ClassNode lastHit = clazz;
|
ClassNode lastHit = clazz;
|
||||||
while (clazz != null && clazz.superName != null) {
|
while (clazz != null && clazz.superName != null) {
|
||||||
ClassNode tmp = Main.classNodes.get(clazz.superName + ".class");
|
ClassNode tmp = Main.classNodes.get(Main.getFullName(clazz.superName));
|
||||||
if (tmp != null) {
|
if (tmp != null) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (MethodNode mn : clazz.methods) {
|
for (MethodNode mn : clazz.methods) {
|
||||||
@@ -127,7 +127,7 @@ public class RenameBox extends JFrame {
|
|||||||
extendsMyClass = true;
|
extendsMyClass = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ClassNode tmp = Main.classNodes.get(checkCN.superName + ".class");
|
ClassNode tmp = Main.classNodes.get(Main.getFullName(checkCN.superName));
|
||||||
if (tmp != null) {
|
if (tmp != null) {
|
||||||
checkCN = tmp;
|
checkCN = tmp;
|
||||||
} else {
|
} else {
|
||||||
@@ -230,6 +230,7 @@ public class RenameBox extends JFrame {
|
|||||||
}
|
}
|
||||||
name = newName;
|
name = newName;
|
||||||
desc = newDesc;
|
desc = newDesc;
|
||||||
|
RenameBox.this.setVisible(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
btnRename.setBounds(345, 237, 89, 23);
|
btnRename.setBounds(345, 237, 89, 23);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import javax.swing.event.ListSelectionEvent;
|
|||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
|
||||||
import me.ByteEdit.main.Main;
|
import me.ByteEdit.main.Main;
|
||||||
|
import me.ByteEdit.utils.UnicodeUtils;
|
||||||
|
|
||||||
public class TypeOpenBox extends JFrame {
|
public class TypeOpenBox extends JFrame {
|
||||||
|
|
||||||
@@ -81,7 +82,7 @@ public class TypeOpenBox extends JFrame {
|
|||||||
if (txtSearch.getText().isEmpty()) {
|
if (txtSearch.getText().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String search = txtSearch.getText().toLowerCase();
|
String search = UnicodeUtils.unescape(txtSearch.getText()).toLowerCase();
|
||||||
if (search.contains("/")) {
|
if (search.contains("/")) {
|
||||||
for (String s : Main.classNodes.keySet()) {
|
for (String s : Main.classNodes.keySet()) {
|
||||||
String className = s.substring(0, s.length() - 6);
|
String className = s.substring(0, s.length() - 6);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package me.ByteEdit.edit;
|
package me.ByteEdit.edit;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -46,6 +45,7 @@ import org.objectweb.asm.tree.VarInsnNode;
|
|||||||
import me.ByteEdit.main.Main;
|
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.OpcodesReverse;
|
||||||
import me.ByteEdit.utils.SwitchIntContainer;
|
import me.ByteEdit.utils.SwitchIntContainer;
|
||||||
import me.ByteEdit.utils.UnicodeUtils;
|
import me.ByteEdit.utils.UnicodeUtils;
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ public class Assembler {
|
|||||||
_end = new LabelNode(entry.getKey());
|
_end = new LabelNode(entry.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.localVariables.add(new LocalVariableNode(sp[0],
|
node.localVariables.add(new LocalVariableNode(UnicodeUtils.unescape(sp[0]),
|
||||||
UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat, _start, _end,
|
UnicodeUtils.unescape(sp[1].substring(1, sp[1].length() - 2)), signat, _start, _end,
|
||||||
Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
Integer.parseInt(sp[2].substring(0, sp[2].length() - 2))));
|
||||||
}
|
}
|
||||||
@@ -492,6 +492,31 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String[] splitWithStrings(String s) {
|
||||||
|
ArrayList<String> ret = new ArrayList<>();
|
||||||
|
String[] split = s.split(", ");
|
||||||
|
String building = null;
|
||||||
|
|
||||||
|
for (int i = 0; i < split.length; i++) {
|
||||||
|
if (split[i].startsWith("(")) {
|
||||||
|
ret.add(split[i]);
|
||||||
|
} else if (split[i].endsWith("\"")) {
|
||||||
|
if (building == null)
|
||||||
|
ret.add(split[i]);
|
||||||
|
else
|
||||||
|
ret.add(building + ", " + split[i]);
|
||||||
|
building = null;
|
||||||
|
} else {
|
||||||
|
if (building == null)
|
||||||
|
building = split[i];
|
||||||
|
else
|
||||||
|
building += ", " + split[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
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(" ");
|
||||||
@@ -510,7 +535,7 @@ public class Assembler {
|
|||||||
if (value.endsWith("]"))
|
if (value.endsWith("]"))
|
||||||
value = value.substring(0, value.length() - 1);
|
value = value.substring(0, value.length() - 1);
|
||||||
if (value.startsWith("{ ")) {
|
if (value.startsWith("{ ")) {
|
||||||
String split3[] = value.substring(2, value.length() - 2).split(", ");
|
String split3[] = splitWithStrings(value.substring(2, value.length() - 2));
|
||||||
List<Object> list = new ArrayList<>();
|
List<Object> list = new ArrayList<>();
|
||||||
for (String rofl : split3) {
|
for (String rofl : split3) {
|
||||||
rofl = UnicodeUtils.unescape(rofl);
|
rofl = UnicodeUtils.unescape(rofl);
|
||||||
@@ -790,13 +815,11 @@ public class Assembler {
|
|||||||
if (str.startsWith("Type: ")) {
|
if (str.startsWith("Type: ")) {
|
||||||
str = str.substring(8, str.length() - 2);
|
str = str.substring(8, str.length() - 2);
|
||||||
String[] split2 = str.split("\n\t");
|
String[] split2 = str.split("\n\t");
|
||||||
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, String.class, int.class,
|
|
||||||
int.class);
|
|
||||||
constr.setAccessible(true);
|
|
||||||
String type = split2[0].substring(7);
|
String type = split2[0].substring(7);
|
||||||
val = constr.newInstance(new Object[] { ClassUtil.getIDFromClassNameForType(type),
|
// Reflection
|
||||||
split2[3].substring(6, split2[3].length() - 1),
|
val = new Type(ClassUtil.getIDFromClassNameForType(type),
|
||||||
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)) });
|
UnicodeUtils.unescape(split2[3].substring(6, split2[3].length() - 1)),
|
||||||
|
Integer.parseInt(split2[1].substring(7)), Integer.parseInt(split2[2].substring(5)));
|
||||||
} else if (str.startsWith("\"") && str.endsWith("\"")) {
|
} else if (str.startsWith("\"") && str.endsWith("\"")) {
|
||||||
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
|
val = UnicodeUtils.unescape(str.substring(1, str.length() - 1));
|
||||||
} else if (str.endsWith("l")) {
|
} else if (str.endsWith("l")) {
|
||||||
@@ -1472,18 +1495,16 @@ public class Assembler {
|
|||||||
if (st.equals("]")) {
|
if (st.equals("]")) {
|
||||||
if (stage == 1) {
|
if (stage == 1) {
|
||||||
try {
|
try {
|
||||||
Constructor<Type> constr = Type.class.getDeclaredConstructor(int.class, String.class,
|
// Reflection
|
||||||
int.class, int.class);
|
args.add(new Type(ClassUtil.getIDFromClassNameForType(vals.get(0).substring(6)),
|
||||||
constr.setAccessible(true);
|
|
||||||
args.add(constr.newInstance(new Object[] { Integer.parseInt(vals.get(0).substring(6)),
|
|
||||||
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)),
|
UnicodeUtils.unescape(vals.get(3).substring(6, vals.get(3).length() - 1)),
|
||||||
Integer.parseInt(vals.get(1).substring(7)),
|
Integer.parseInt(vals.get(1).substring(7)),
|
||||||
Integer.parseInt(vals.get(2).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)),
|
args.add(new Handle(OpcodesReverse.getHandleOpcode(vals.get(4).substring(5)),
|
||||||
UnicodeUtils.unescape(vals.get(1).substring(7)),
|
UnicodeUtils.unescape(vals.get(1).substring(7)),
|
||||||
UnicodeUtils.unescape(vals.get(0).substring(6)),
|
UnicodeUtils.unescape(vals.get(0).substring(6)),
|
||||||
UnicodeUtils.unescape(vals.get(2).substring(6)),
|
UnicodeUtils.unescape(vals.get(2).substring(6)),
|
||||||
@@ -1502,6 +1523,18 @@ public class Assembler {
|
|||||||
} else if (stage == 2) {
|
} else if (stage == 2) {
|
||||||
st = st.substring(1);
|
st = st.substring(1);
|
||||||
vals.add(st);
|
vals.add(st);
|
||||||
|
} else if (stage == 0) {
|
||||||
|
if (st.startsWith("\"") && st.endsWith("\"")) {
|
||||||
|
args.add(UnicodeUtils.unescape(st.substring(1, st.length() - 1)));
|
||||||
|
} else if (st.endsWith("l")) {
|
||||||
|
args.add(Long.parseLong(st.substring(0, st.length() - 1)));
|
||||||
|
} else if (st.endsWith("f")) {
|
||||||
|
args.add(Float.parseFloat(st.substring(0, st.length() - 1)));
|
||||||
|
} else if (st.contains(".")) {
|
||||||
|
args.add(Double.parseDouble(st));
|
||||||
|
} else {
|
||||||
|
args.add(Integer.parseInt(st));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object[] _args = new Object[args.size()];
|
Object[] _args = new Object[args.size()];
|
||||||
@@ -1512,9 +1545,9 @@ public class Assembler {
|
|||||||
}
|
}
|
||||||
return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)),
|
return new InvokeDynamicInsnNode(UnicodeUtils.unescape(sp[0].substring(7)),
|
||||||
UnicodeUtils.unescape(sp[1].substring(6)),
|
UnicodeUtils.unescape(sp[1].substring(6)),
|
||||||
new Handle(Integer.parseInt(sp[7].substring(6)), UnicodeUtils.unescape(sp[4].substring(8)),
|
new Handle(OpcodesReverse.getHandleOpcode(sp[7].substring(6)),
|
||||||
UnicodeUtils.unescape(sp[3].substring(7)), UnicodeUtils.unescape(sp[5].substring(7)),
|
UnicodeUtils.unescape(sp[4].substring(8)), UnicodeUtils.unescape(sp[3].substring(7)),
|
||||||
Boolean.parseBoolean(sp[6].substring(14))),
|
UnicodeUtils.unescape(sp[5].substring(7)), Boolean.parseBoolean(sp[6].substring(14))),
|
||||||
_args);
|
_args);
|
||||||
}
|
}
|
||||||
case "new": {
|
case "new": {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package me.ByteEdit.edit;
|
package me.ByteEdit.edit;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -118,12 +117,14 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s += "\"" + obj + "\"";
|
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||||
}
|
}
|
||||||
s += ", ";
|
s += ", ";
|
||||||
}
|
}
|
||||||
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 + "], ";
|
||||||
}
|
}
|
||||||
@@ -216,7 +217,7 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s += "\"" + obj + "\"";
|
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||||
}
|
}
|
||||||
s += ", ";
|
s += ", ";
|
||||||
}
|
}
|
||||||
@@ -294,7 +295,7 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s += "\"" + obj + "\"";
|
s += "\"" + UnicodeUtils.escape(String.valueOf(obj)) + "\"";
|
||||||
}
|
}
|
||||||
s += ", ";
|
s += ", ";
|
||||||
}
|
}
|
||||||
@@ -384,18 +385,15 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) {
|
public static String disassembleInstruction(AbstractInsnNode n, HashMap<Label, Integer> labels) {
|
||||||
switch (n.getClass().getSimpleName()) {
|
if (FieldInsnNode.class.isInstance(n)) {
|
||||||
case "FieldInsnNode": {
|
|
||||||
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)) {
|
||||||
case "LabelNode": {
|
|
||||||
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)) {
|
||||||
case "FrameNode": {
|
|
||||||
FrameNode node = (FrameNode) n;
|
FrameNode node = (FrameNode) n;
|
||||||
String type = "";
|
String type = "";
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
@@ -472,12 +470,10 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
s += "\n";
|
s += "\n";
|
||||||
return s;
|
return s;
|
||||||
}
|
} else if (LineNumberNode.class.isInstance(n)) {
|
||||||
case "LineNumberNode": {
|
|
||||||
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)) {
|
||||||
case "InvokeDynamicInsnNode": {
|
|
||||||
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: "
|
||||||
@@ -485,25 +481,15 @@ public class Disassembler {
|
|||||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: "
|
+ UnicodeUtils.escapeWithSpaces(node.bsm.getName()) + "\n\t\t\t\towner: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
|
+ UnicodeUtils.escapeWithSpaces(node.bsm.getOwner()) + "\n\t\t\t\tdesc: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(node.bsm.getDesc()) + "\n\t\t\t\tisInterface: "
|
+ UnicodeUtils.escapeWithSpaces(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";
|
+ node.bsm.isInterface() + "\n\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(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;
|
||||||
int valueBegin = 0;
|
int valueBegin = type.valueBegin;
|
||||||
int valueEnd = 0;
|
int valueEnd = type.valueEnd;
|
||||||
String buf = null;
|
String buf = type.valueBuffer;
|
||||||
try {
|
// Reflection
|
||||||
Field f_off = Type.class.getDeclaredField("valueBegin");
|
|
||||||
f_off.setAccessible(true);
|
|
||||||
valueBegin = f_off.getInt(type);
|
|
||||||
Field f_len = Type.class.getDeclaredField("valueEnd");
|
|
||||||
f_len.setAccessible(true);
|
|
||||||
valueEnd = f_len.getInt(type);
|
|
||||||
Field f_buf = Type.class.getDeclaredField("valueBuffer");
|
|
||||||
f_buf.setAccessible(true);
|
|
||||||
buf = (String) f_buf.get(type);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type)
|
s += "\t\t\t\tType: [\n\t\t\t\t\ttype: " + ClassUtil.getClassNameFromType(type)
|
||||||
+ "\n\t\t\t\t\tstart: " + valueBegin + "\n\t\t\t\t\tend: " + valueEnd + "\n\t\t\t\t\tbuf: "
|
+ "\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, "");
|
||||||
@@ -514,7 +500,7 @@ public class Disassembler {
|
|||||||
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: "
|
+ UnicodeUtils.escapeWithSpaces(h.getName()).replace("/", "\\u002F") + "\n\t\t\t\t\towner: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: "
|
+ UnicodeUtils.escapeWithSpaces(h.getOwner()) + "\n\t\t\t\t\tdesc: "
|
||||||
+ UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface()
|
+ UnicodeUtils.escapeWithSpaces(h.getDesc()) + "\n\t\t\t\t\tisInterface: " + h.isInterface()
|
||||||
+ "\n\t\t\t\t\ttag: " + h.getTag();
|
+ "\n\t\t\t\t\ttag: " + OpcodesReverse.reverseHandleOpcode(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";
|
||||||
@@ -522,24 +508,20 @@ 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)) {
|
||||||
case "MethodInsnNode": {
|
|
||||||
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)) {
|
||||||
case "TypeInsnNode": {
|
|
||||||
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)) {
|
||||||
case "MultiANewArrayInsnNode": {
|
|
||||||
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)) {
|
||||||
case "LdcInsnNode": {
|
|
||||||
LdcInsnNode node = (LdcInsnNode) n;
|
LdcInsnNode node = (LdcInsnNode) n;
|
||||||
switch (node.cst.getClass().getSimpleName()) {
|
switch (node.cst.getClass().getSimpleName()) {
|
||||||
case "String":
|
case "String":
|
||||||
@@ -552,21 +534,10 @@ public class Disassembler {
|
|||||||
}
|
}
|
||||||
case "Type": {
|
case "Type": {
|
||||||
Type type = (Type) node.cst;
|
Type type = (Type) node.cst;
|
||||||
int valueBegin = 0;
|
int valueBegin = type.valueBegin;
|
||||||
int valueEnd = 0;
|
int valueEnd = type.valueEnd;
|
||||||
String buf = null;
|
String buf = type.valueBuffer;
|
||||||
try {
|
// Reflection
|
||||||
Field f_off = Type.class.getDeclaredField("valueBegin");
|
|
||||||
f_off.setAccessible(true);
|
|
||||||
valueBegin = f_off.getInt(type);
|
|
||||||
Field f_len = Type.class.getDeclaredField("valueEnd");
|
|
||||||
f_len.setAccessible(true);
|
|
||||||
valueEnd = f_len.getInt(type);
|
|
||||||
Field f_buf = Type.class.getDeclaredField("valueBuffer");
|
|
||||||
f_buf.setAccessible(true);
|
|
||||||
buf = (String) f_buf.get(type);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
|
String s = "\t\t" + OpcodesReverse.reverseOpcode(n.getOpcode()) + " Type: [\n\t\t\ttype: "
|
||||||
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: "
|
+ ClassUtil.getClassNameFromType(type) + "\n\t\t\tstart: " + valueBegin + "\n\t\t\tend: "
|
||||||
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
+ valueEnd + "\n\t\t\tbuf: " + ClassUtil.getDecompiledValue(buf, "");
|
||||||
@@ -578,16 +549,13 @@ public class Disassembler {
|
|||||||
+ node.cst.getClass().getName().replace(".", "/") + " " + node.cst + "\n";
|
+ node.cst.getClass().getName().replace(".", "/") + " " + node.cst + "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (VarInsnNode.class.isInstance(n)) {
|
||||||
case "VarInsnNode": {
|
|
||||||
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)) {
|
||||||
case "InsnNode": {
|
|
||||||
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)) {
|
||||||
case "IntInsnNode": {
|
|
||||||
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()) + " "
|
||||||
@@ -595,13 +563,11 @@ 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)) {
|
||||||
case "JumpInsnNode": {
|
|
||||||
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)) {
|
||||||
case "TableSwitchInsnNode": {
|
|
||||||
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())
|
||||||
@@ -611,8 +577,7 @@ 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)) {
|
||||||
case "LookupSwitchInsnNode": {
|
|
||||||
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";
|
||||||
@@ -625,12 +590,10 @@ 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)) {
|
||||||
case "IincInsnNode": {
|
|
||||||
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 {
|
||||||
default:
|
|
||||||
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
return "\t\tNOT HANDLED! " + OpcodesReverse.reverseOpcode(n.getOpcode()) + " "
|
||||||
+ n.getClass().getSimpleName() + "\n";
|
+ n.getClass().getSimpleName() + "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
+141
-36
@@ -18,20 +18,26 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
@@ -45,14 +51,18 @@ import javax.swing.JTree;
|
|||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.event.TreeExpansionEvent;
|
||||||
|
import javax.swing.event.TreeExpansionListener;
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
import javax.swing.event.TreeSelectionEvent;
|
||||||
import javax.swing.event.TreeSelectionListener;
|
import javax.swing.event.TreeSelectionListener;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
import javax.swing.text.BadLocationException;
|
import javax.swing.text.BadLocationException;
|
||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||||
import javax.swing.tree.DefaultTreeModel;
|
import javax.swing.tree.DefaultTreeModel;
|
||||||
|
import javax.swing.tree.TreeNode;
|
||||||
|
import javax.swing.tree.TreePath;
|
||||||
|
import javax.swing.tree.TreeSelectionModel;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.fife.ui.autocomplete.AutoCompletion;
|
import org.fife.ui.autocomplete.AutoCompletion;
|
||||||
import org.fife.ui.autocomplete.BasicCompletion;
|
import org.fife.ui.autocomplete.BasicCompletion;
|
||||||
import org.fife.ui.autocomplete.CompletionProvider;
|
import org.fife.ui.autocomplete.CompletionProvider;
|
||||||
@@ -106,6 +116,8 @@ public class Main extends JFrame {
|
|||||||
public static Theme theme;
|
public static Theme theme;
|
||||||
public static File saveFolder;
|
public static File saveFolder;
|
||||||
|
|
||||||
|
public static HashSet<String> fakedFolders = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch the application.
|
* Launch the application.
|
||||||
*/
|
*/
|
||||||
@@ -236,6 +248,8 @@ public class Main extends JFrame {
|
|||||||
FoldParserManager.get().addFoldParserMapping(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE,
|
FoldParserManager.get().addFoldParserMapping(SyntaxConstants.SYNTAX_STYLE_JAVA_DISASSEMBLE,
|
||||||
new CurlyFoldParser(false, true));
|
new CurlyFoldParser(false, true));
|
||||||
tree = new JTree(new DefaultTreeModel(null));
|
tree = new JTree(new DefaultTreeModel(null));
|
||||||
|
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||||
|
tree.addTreeExpansionListener(new FurtherExpandingTreeExpansionListener());
|
||||||
tree.addKeyListener(new KeyAdapter() {
|
tree.addKeyListener(new KeyAdapter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -283,13 +297,15 @@ public class Main extends JFrame {
|
|||||||
});
|
});
|
||||||
tree.setFont(new Font("Verdana", Font.PLAIN, 11));
|
tree.setFont(new Font("Verdana", Font.PLAIN, 11));
|
||||||
tree.setBackground(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY);
|
tree.setBackground(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY);
|
||||||
if (tree.getCellRenderer() instanceof DefaultTreeCellRenderer) {
|
tree.setCellRenderer(new DefaultTreeCellRenderer() {
|
||||||
final DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) (tree.getCellRenderer());
|
{
|
||||||
renderer.setBackgroundNonSelectionColor(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY);
|
putClientProperty("html.disable", Boolean.TRUE);
|
||||||
renderer.setBackgroundSelectionColor(Color.GRAY);
|
setBackgroundNonSelectionColor(dark ? new Color(0x2F2F2F) : Color.LIGHT_GRAY);
|
||||||
renderer.setTextNonSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK);
|
setBackgroundSelectionColor(Color.GRAY);
|
||||||
renderer.setTextSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK);
|
setTextNonSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK);
|
||||||
}
|
setTextSelectionColor(dark ? new Color(0xeeeeee) : Color.BLACK);
|
||||||
|
}
|
||||||
|
});
|
||||||
scrollPane.setViewportView(tree);
|
scrollPane.setViewportView(tree);
|
||||||
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||||
|
|
||||||
@@ -535,16 +551,16 @@ public class Main extends JFrame {
|
|||||||
methodName = "/" + methodName;
|
methodName = "/" + methodName;
|
||||||
className = className.substring(0, className.length() - 1);
|
className = className.substring(0, className.length() - 1);
|
||||||
}
|
}
|
||||||
ClassNode classNode = classNodes.get(className + ".class");
|
ClassNode classNode = classNodes.get(getFullName(className));
|
||||||
if (classNode == null) {
|
if (classNode == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (MethodNode mn : classNode.methods) {
|
for (MethodNode mn : classNode.methods) {
|
||||||
if (mn.name.equals(methodName) && mn.desc.equals(desc)) {
|
if (mn.name.equals(methodName) && mn.desc.equals(desc)) {
|
||||||
while (classNode.outerClass != null) {
|
while (classNode.outerClass != null) {
|
||||||
classNode = classNodes.get(classNode.outerClass + ".class");
|
classNode = classNodes.get(getFullName(classNode.outerClass));
|
||||||
}
|
}
|
||||||
int lineFound = selectFileWithSearch(classNode.name + ".class", mn);
|
int lineFound = selectFileWithSearch(getFullName(classNode.name), mn);
|
||||||
if (lineFound != -1) {
|
if (lineFound != -1) {
|
||||||
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
|
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
|
||||||
}
|
}
|
||||||
@@ -554,11 +570,11 @@ public class Main extends JFrame {
|
|||||||
} else if (line.startsWith("new ")) {
|
} else if (line.startsWith("new ")) {
|
||||||
String[] split = line.split(" ");
|
String[] split = line.split(" ");
|
||||||
String className = UnicodeUtils.unescape(split[1]);
|
String className = UnicodeUtils.unescape(split[1]);
|
||||||
ClassNode classNode = classNodes.get(className + ".class");
|
ClassNode classNode = classNodes.get(getFullName(className));
|
||||||
if (classNode == null) {
|
if (classNode == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
selectFile(className + ".class");
|
selectFile(getFullName(className));
|
||||||
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ")
|
} else if (line.startsWith("getstatic ") || line.startsWith("putstatic ") || line.startsWith("getfield ")
|
||||||
|| line.startsWith("putfield ")) {
|
|| line.startsWith("putfield ")) {
|
||||||
String[] split = line.split(" ");
|
String[] split = line.split(" ");
|
||||||
@@ -571,16 +587,16 @@ public class Main extends JFrame {
|
|||||||
fieldName = "/" + fieldName;
|
fieldName = "/" + fieldName;
|
||||||
className = className.substring(0, className.length() - 1);
|
className = className.substring(0, className.length() - 1);
|
||||||
}
|
}
|
||||||
ClassNode classNode = classNodes.get(className + ".class");
|
ClassNode classNode = classNodes.get(getFullName(className));
|
||||||
if (classNode == null) {
|
if (classNode == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (FieldNode fn : classNode.fields) {
|
for (FieldNode fn : classNode.fields) {
|
||||||
if (fn.name.equals(fieldName) && fn.desc.equals(desc)) {
|
if (fn.name.equals(fieldName) && fn.desc.equals(desc)) {
|
||||||
while (classNode.outerClass != null) {
|
while (classNode.outerClass != null) {
|
||||||
classNode = classNodes.get(classNode.outerClass + ".class");
|
classNode = classNodes.get(getFullName(classNode.outerClass));
|
||||||
}
|
}
|
||||||
int lineFound = selectFileWithSearch(classNode.name + ".class", fn);
|
int lineFound = selectFileWithSearch(getFullName(classNode.name), fn);
|
||||||
if (lineFound != -1) {
|
if (lineFound != -1) {
|
||||||
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
|
Main.txtByteEditView.setCaretPosition(Main.txtByteEditView.getLineStartOffset(lineFound));
|
||||||
}
|
}
|
||||||
@@ -656,15 +672,15 @@ public class Main extends JFrame {
|
|||||||
if (node == null) {
|
if (node == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (classNodes.replace(node.name + ".class", node) == null) {
|
if (classNodes.replace(getFullName(node.name), node) == null) {
|
||||||
classNodes.put(node.name + ".class", node);
|
classNodes.put(getFullName(node.name), node);
|
||||||
ArchiveTreeModel model;
|
ArchiveTreeModel model;
|
||||||
if (tree.getModel().getClass().equals(DefaultTreeModel.class)) {
|
if (tree.getModel().getClass().equals(DefaultTreeModel.class)) {
|
||||||
tree.setModel(model = new ArchiveTreeModel());
|
tree.setModel(model = new ArchiveTreeModel());
|
||||||
} else {
|
} else {
|
||||||
model = (ArchiveTreeModel) tree.getModel();
|
model = (ArchiveTreeModel) tree.getModel();
|
||||||
}
|
}
|
||||||
String name = node.name + ".class";
|
String name = getFullName(node.name);
|
||||||
if (name.contains("/") ? (!name.split("/")[name.split("/").length - 1].contains("$"))
|
if (name.contains("/") ? (!name.split("/")[name.split("/").length - 1].contains("$"))
|
||||||
: (!name.contains("$"))) {
|
: (!name.contains("$"))) {
|
||||||
model.paths.add(name);
|
model.paths.add(name);
|
||||||
@@ -678,10 +694,13 @@ public class Main extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static int selectFileWithSearch(String s, Object nodeToFind) {
|
public static int selectFileWithSearch(String s, Object nodeToFind) {
|
||||||
if (s.endsWith(".class")) {
|
if (s != null && (s.endsWith(".class")
|
||||||
|
|| (s.endsWith(".class/") && fakedFolders.contains(s.substring(0, s.length() - 7))))) {
|
||||||
currentNodeName = s;
|
currentNodeName = s;
|
||||||
int lineFound = -1;
|
int lineFound = -1;
|
||||||
ClassNode classNode = classNodes.get(s);
|
ClassNode classNode = classNodes.get(s);
|
||||||
|
if (classNode == null)
|
||||||
|
return -1;
|
||||||
String dis = "";
|
String dis = "";
|
||||||
DisassembleTuple tuple = Disassembler.disassemble(classNode, nodeToFind);
|
DisassembleTuple tuple = Disassembler.disassemble(classNode, nodeToFind);
|
||||||
if (tuple.getLine() != -1) {
|
if (tuple.getLine() != -1) {
|
||||||
@@ -784,7 +803,7 @@ public class Main extends JFrame {
|
|||||||
for (ClassNode element : classes) {
|
for (ClassNode element : classes) {
|
||||||
ClassWriter writer = new ClassWriter(computeFlags);
|
ClassWriter writer = new ClassWriter(computeFlags);
|
||||||
element.accept(writer);
|
element.accept(writer);
|
||||||
output.putNextEntry(new JarEntry(element.name + ".class"));
|
output.putNextEntry(new JarEntry(getFullName(element.name)));
|
||||||
output.write(writer.toByteArray());
|
output.write(writer.toByteArray());
|
||||||
output.closeEntry();
|
output.closeEntry();
|
||||||
}
|
}
|
||||||
@@ -811,6 +830,13 @@ public class Main extends JFrame {
|
|||||||
JOptionPane.showMessageDialog(INSTANCE, s, "Error!", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(INSTANCE, s, "Error!", JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFullName(String s) {
|
||||||
|
if (fakedFolders.contains(s))
|
||||||
|
return s + ".class/";
|
||||||
|
else
|
||||||
|
return s + ".class";
|
||||||
|
}
|
||||||
|
|
||||||
class ArchiveTreeModel extends DefaultTreeModel {
|
class ArchiveTreeModel extends DefaultTreeModel {
|
||||||
|
|
||||||
public ArrayList<String> paths = new ArrayList<>();
|
public ArrayList<String> paths = new ArrayList<>();
|
||||||
@@ -831,26 +857,26 @@ public class Main extends JFrame {
|
|||||||
Enumeration<JarEntry> enumeration = jar.entries();
|
Enumeration<JarEntry> enumeration = jar.entries();
|
||||||
while (enumeration.hasMoreElements()) {
|
while (enumeration.hasMoreElements()) {
|
||||||
JarEntry next = enumeration.nextElement();
|
JarEntry next = enumeration.nextElement();
|
||||||
byte[] data = IOUtils.toByteArray(jar.getInputStream(next));
|
byte[] data = toByteArray(jar.getInputStream(next));
|
||||||
if (!next.getName().startsWith("META-INF") && next.getName().endsWith(".class")) {
|
if (next.getSize() != 0 && !next.getName().startsWith("META-INF")
|
||||||
if (next.getName().contains("/")
|
&& (next.getName().endsWith(".class") || next.getName().endsWith(".class/"))) {
|
||||||
|
if ((next.getName().contains("/")
|
||||||
? (!next.getName().split("/")[next.getName().split("/").length - 1].contains("$"))
|
? (!next.getName().split("/")[next.getName().split("/").length - 1].contains("$"))
|
||||||
: (!next.getName().contains("$"))) {
|
: (!next.getName().contains("$")))
|
||||||
paths.add(next.getName());
|
|| (next.getName().startsWith("$") || next.getName().contains("$$")
|
||||||
} else if (next.getName().startsWith("$") || next.getName().contains("$$")
|
|| next.getName().endsWith("$"))) {
|
||||||
|| next.getName().endsWith("$")) { // obfuscated
|
|
||||||
paths.add(next.getName());
|
paths.add(next.getName());
|
||||||
|
if (next.getName().endsWith(".class/") && next.getSize() != 0)
|
||||||
|
fakedFolders.add(next.getName().substring(0, next.getName().length() - 7));
|
||||||
}
|
}
|
||||||
ClassReader reader;
|
|
||||||
try {
|
try {
|
||||||
reader = new ClassReader(data);
|
ClassReader reader = new ClassReader(data);
|
||||||
|
ClassNode node = new ClassNode();
|
||||||
|
reader.accept(node, 0);
|
||||||
|
classNodes.put(next.getName(), node);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
OTHER_FILES.put(next.getName(), data);
|
OTHER_FILES.put(next.getName(), data);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
ClassNode node = new ClassNode();
|
|
||||||
reader.accept(node, 0);
|
|
||||||
classNodes.put(next.getName(), node);
|
|
||||||
} else {
|
} else {
|
||||||
OTHER_FILES.put(next.getName(), data);
|
OTHER_FILES.put(next.getName(), data);
|
||||||
}
|
}
|
||||||
@@ -865,10 +891,58 @@ public class Main extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getSlashCount(String s) {
|
||||||
|
int count = 0;
|
||||||
|
for (char c : s.toCharArray()) {
|
||||||
|
if (c == '/')
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
public void refresh() {
|
public void refresh() {
|
||||||
setRoot(new ByteEditTreeNode(((ByteEditTreeNode) getRoot()).toString()));
|
setRoot(new ByteEditTreeNode(((ByteEditTreeNode) getRoot()).toString()));
|
||||||
Collections.sort(paths);
|
Collections.sort(paths, String.CASE_INSENSITIVE_ORDER);
|
||||||
for (String s : paths) {
|
Collections.sort(paths, new Comparator<String>() {
|
||||||
|
public int compare(String s1, String s2) {
|
||||||
|
return getSlashCount(s2) - getSlashCount(s1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
List<String> tmp = new ArrayList<>(paths);
|
||||||
|
|
||||||
|
List<String> folders = tmp.stream().map(s -> {
|
||||||
|
int idx = s.lastIndexOf('/');
|
||||||
|
if (idx == s.length() - 1)
|
||||||
|
idx = s.lastIndexOf('/', idx - 1);
|
||||||
|
if (idx == -1)
|
||||||
|
return s;
|
||||||
|
return s.substring(0, idx);
|
||||||
|
}).distinct().sorted(new Comparator<String>() {
|
||||||
|
@Override
|
||||||
|
public int compare(String s, String s2) {
|
||||||
|
// From String#compareToIgnoreCase(String)
|
||||||
|
int n = s.length();
|
||||||
|
int n2 = s2.length();
|
||||||
|
int n3 = Math.min(n, n2);
|
||||||
|
for (int i = 0; i < n3; ++i) {
|
||||||
|
char c;
|
||||||
|
char c2 = s.charAt(i);
|
||||||
|
if (c2 == (c = s2.charAt(i))
|
||||||
|
|| (c2 = Character.toUpperCase(c2)) == (c = Character.toUpperCase(c))
|
||||||
|
|| (c2 = Character.toLowerCase(c2)) == (c = Character.toLowerCase(c)))
|
||||||
|
continue;
|
||||||
|
return c2 - c;
|
||||||
|
}
|
||||||
|
// Other way around
|
||||||
|
return n2 - n;
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
tmp.removeAll(folders);
|
||||||
|
tmp.addAll(0, folders);
|
||||||
|
|
||||||
|
for (String s : tmp) {
|
||||||
String[] elements = s.split("/");
|
String[] elements = s.split("/");
|
||||||
ByteEditTreeNode currentNode = (ByteEditTreeNode) getRoot();
|
ByteEditTreeNode currentNode = (ByteEditTreeNode) getRoot();
|
||||||
for (int i = 0; i < elements.length; i++) {
|
for (int i = 0; i < elements.length; i++) {
|
||||||
@@ -894,4 +968,35 @@ public class Main extends JFrame {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FurtherExpandingTreeExpansionListener implements TreeExpansionListener {
|
||||||
|
public void treeExpanded(TreeExpansionEvent event) {
|
||||||
|
TreePath treePath = event.getPath();
|
||||||
|
Object expandedTreePathObject = treePath.getLastPathComponent();
|
||||||
|
if (!(expandedTreePathObject instanceof TreeNode))
|
||||||
|
return;
|
||||||
|
TreeNode expandedTreeNode = (TreeNode) expandedTreePathObject;
|
||||||
|
if (expandedTreeNode.getChildCount() == 1) {
|
||||||
|
TreeNode descendantTreeNode = expandedTreeNode.getChildAt(0);
|
||||||
|
if (descendantTreeNode.isLeaf())
|
||||||
|
return;
|
||||||
|
TreePath nextTreePath = treePath.pathByAddingChild(descendantTreeNode);
|
||||||
|
tree.expandPath(nextTreePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void treeCollapsed(TreeExpansionEvent event) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] toByteArray(final InputStream input) throws IOException {
|
||||||
|
try (final ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||||||
|
byte[] buffer = new byte[4096];
|
||||||
|
int read;
|
||||||
|
while ((read = input.read(buffer)) != -1) {
|
||||||
|
output.write(buffer, 0, read);
|
||||||
|
}
|
||||||
|
return output.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -206,20 +206,20 @@ public class ClassUtil {
|
|||||||
|
|
||||||
public static int getFrameTypeByName(String type) {
|
public static int getFrameTypeByName(String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "top":
|
case "top":
|
||||||
return 0;
|
return 0;
|
||||||
case "I":
|
case "I":
|
||||||
return 1;
|
return 1;
|
||||||
case "F":
|
case "F":
|
||||||
return 2;
|
return 2;
|
||||||
case "D":
|
case "D":
|
||||||
return 3;
|
return 3;
|
||||||
case "J":
|
case "J":
|
||||||
return 4;
|
return 4;
|
||||||
case "null":
|
case "null":
|
||||||
return 5;
|
return 5;
|
||||||
case "uninitializedThis":
|
case "uninitializedThis":
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ public class ExternalTypeEnumeration {
|
|||||||
setDescriptor(paramString);
|
setDescriptor(paramString);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalTypeEnumeration() {}
|
ExternalTypeEnumeration() {
|
||||||
|
}
|
||||||
|
|
||||||
void setDescriptor(String paramString) {
|
void setDescriptor(String paramString) {
|
||||||
this.descriptor = paramString;
|
this.descriptor = paramString;
|
||||||
@@ -33,7 +34,8 @@ public class ExternalTypeEnumeration {
|
|||||||
if (this.index < 0) {
|
if (this.index < 0) {
|
||||||
this.index = this.descriptor.indexOf(')', i);
|
this.index = this.descriptor.indexOf(')', i);
|
||||||
if (this.index < 0) {
|
if (this.index < 0) {
|
||||||
throw new IllegalArgumentException("Missing closing parenthesis in descriptor [" + this.descriptor + "]");
|
throw new IllegalArgumentException(
|
||||||
|
"Missing closing parenthesis in descriptor [" + this.descriptor + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.descriptor.substring(i, this.index++).trim();
|
return this.descriptor.substring(i, this.index++).trim();
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -16,45 +16,46 @@ public class UnicodeUtils {
|
|||||||
}
|
}
|
||||||
if (stage == 1) {
|
if (stage == 1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
sb.append('\b');
|
sb.append('\b');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
sb.append('\t');
|
sb.append('\t');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
sb.append('\r');
|
sb.append('\r');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
sb.append('\f');
|
sb.append('\f');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
sb.append('"');
|
sb.append('"');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case '\\':
|
case '\\':
|
||||||
sb.append('\\');
|
sb.append('\\');
|
||||||
stage = 0;
|
stage = 0;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
stage++;
|
stage++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("'\\" + c + "' is invalid.");
|
throw new IllegalArgumentException("'\\" + c + "' is invalid.");
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (stage > 1 && stage < 6) { // \u1234 => up to 6
|
} else if (stage > 1 && stage < 6) { // \u1234 => up to 6
|
||||||
try {
|
try {
|
||||||
int i = Integer.parseInt(Character.toString(c), 16);
|
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
|
unicodeBuffer += i << (4 * (5 - stage++)); // 4 bytes each, shift left byte * 4..3..2..1 and add to
|
||||||
|
// unicodeBuffer
|
||||||
if (stage == 6) {
|
if (stage == 6) {
|
||||||
sb.append(unicodeBuffer);
|
sb.append(unicodeBuffer);
|
||||||
stage = 0;
|
stage = 0;
|
||||||
@@ -101,29 +102,29 @@ public class UnicodeUtils {
|
|||||||
sb.append(c);
|
sb.append(c);
|
||||||
} else {
|
} else {
|
||||||
switch (c) {
|
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:
|
||||||
sb.append(String.format("\\u%04X", (int) c));
|
sb.append(String.format("\\u%04X", (int) c));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,27 +133,27 @@ public class UnicodeUtils {
|
|||||||
|
|
||||||
private static boolean isPrintable(char c) {
|
private static boolean isPrintable(char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'Ä':
|
case 'Ä':
|
||||||
case 'ä':
|
case 'ä':
|
||||||
case 'Ö':
|
case 'Ö':
|
||||||
case 'ö':
|
case 'ö':
|
||||||
case 'Ü':
|
case 'Ü':
|
||||||
case 'ü':
|
case 'ü':
|
||||||
case 'ß':
|
case 'ß':
|
||||||
case '€':
|
case '€':
|
||||||
case '©':
|
case '©':
|
||||||
case '®':
|
case '®':
|
||||||
case '«':
|
case '«':
|
||||||
case '»':
|
case '»':
|
||||||
case '§':
|
case '§':
|
||||||
case '£':
|
case '£':
|
||||||
case '¥':
|
case '¥':
|
||||||
return true;
|
return true;
|
||||||
case '"':
|
case '"':
|
||||||
case '\\':
|
case '\\':
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
return c >= ' ' && c <= '~';
|
return c >= ' ' && c <= '~';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user