2.9.8
This commit is contained in:
parent
908ba230fe
commit
3dadae6f99
Binary file not shown.
BIN
src/resources/class.png
Normal file
BIN
src/resources/class.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 639 B |
Binary file not shown.
Before Width: | Height: | Size: 639 B After Width: | Height: | Size: 488 B |
|
@ -13,6 +13,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -85,7 +87,6 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
||||||
* Spiffy up the plugin console with hilighted lines
|
* Spiffy up the plugin console with hilighted lines
|
||||||
* Take https://github.com/ptnkjke/Java-Bytecode-Editor visualize
|
* Take https://github.com/ptnkjke/Java-Bytecode-Editor visualize
|
||||||
* make zipfile not include the decode shit
|
* make zipfile not include the decode shit
|
||||||
* When you drag a folder, it must add the folder name not just the child into the root jtree path
|
|
||||||
* add stackmapframes to bytecode decompiler
|
* add stackmapframes to bytecode decompiler
|
||||||
* add stackmapframes remover?
|
* add stackmapframes remover?
|
||||||
* make ez-injection plugin console show all sys.out calls
|
* make ez-injection plugin console show all sys.out calls
|
||||||
|
@ -109,6 +110,13 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
|
||||||
* 07/22/2015 - Fixed a typo (Thanks affffsdsd)
|
* 07/22/2015 - Fixed a typo (Thanks affffsdsd)
|
||||||
* 07/22/2015 - Finally added icons to the File Navigator, credits to http://famfamfam.com/lab/icons/silk/ for the icons.
|
* 07/22/2015 - Finally added icons to the File Navigator, credits to http://famfamfam.com/lab/icons/silk/ for the icons.
|
||||||
* 07/22/2015 - JD-GUI is now the default decompiler for GUI.
|
* 07/22/2015 - JD-GUI is now the default decompiler for GUI.
|
||||||
|
* 07/22/2015 - Added Set Python 3.X to the UI.
|
||||||
|
* 07/22/2015 - Fixed krakatau/export as jar bug introduced by file system update.
|
||||||
|
* 07/22/2015 - Sped up krakatau decompiler/disassembler on big files.
|
||||||
|
* 07/22/2015 - Made it so when you press enter on the file navigation pane it opens the class.
|
||||||
|
* 07/22/2015 - The Quick file search now opens the files again.
|
||||||
|
* 07/23/2015 - Fixed opening single files and file folders into BCV
|
||||||
|
* 07/24/2015 - Added File>Reload Resources.
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
*
|
*
|
||||||
|
@ -619,7 +627,8 @@ public class BytecodeViewer {
|
||||||
|
|
||||||
for(FileContainer container : files)
|
for(FileContainer container : files)
|
||||||
for(ClassNode c : container.classes)
|
for(ClassNode c : container.classes)
|
||||||
a.add(c);
|
if(!a.contains(c))
|
||||||
|
a.add(c);
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -741,7 +750,38 @@ public class BytecodeViewer {
|
||||||
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
||||||
} else {
|
} else {
|
||||||
if(f.isDirectory()) {
|
if(f.isDirectory()) {
|
||||||
openFiles(f.listFiles(), false);
|
FileContainer container = new FileContainer(f);
|
||||||
|
HashMap<String, byte[]> files = new HashMap<String, byte[]>();
|
||||||
|
boolean finished = false;
|
||||||
|
ArrayList<File> totalFiles = new ArrayList<File>();
|
||||||
|
totalFiles.add(f);
|
||||||
|
String dir = f.getAbsolutePath();//f.getAbsolutePath().substring(0, f.getAbsolutePath().length()-f.getName().length());
|
||||||
|
|
||||||
|
while(!finished) {
|
||||||
|
boolean added = false;
|
||||||
|
for(int i = 0; i < totalFiles.size(); i++) {
|
||||||
|
File child = totalFiles.get(i);
|
||||||
|
if(child.listFiles() != null)
|
||||||
|
for(File rocket : child.listFiles())
|
||||||
|
if(!totalFiles.contains(rocket)) {
|
||||||
|
totalFiles.add(rocket);
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!added) {
|
||||||
|
for(File child : totalFiles)
|
||||||
|
if(child.isFile()) {
|
||||||
|
String fileName = child.getAbsolutePath().substring(dir.length()+1, child.getAbsolutePath().length()).replaceAll("\\\\", "\\/");
|
||||||
|
|
||||||
|
|
||||||
|
files.put(fileName, Files.readAllBytes(Paths.get(child.getAbsolutePath())));
|
||||||
|
}
|
||||||
|
finished = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.files = files;
|
||||||
|
BytecodeViewer.files.add(container);
|
||||||
} else {
|
} else {
|
||||||
if (fn.endsWith(".jar") || fn.endsWith(".zip")) {
|
if (fn.endsWith(".jar") || fn.endsWith(".zip")) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -230,29 +230,69 @@ public class JarUtils {
|
||||||
* @param nodeList The loaded ClassNodes
|
* @param nodeList The loaded ClassNodes
|
||||||
* @param path the exact jar output path
|
* @param path the exact jar output path
|
||||||
*/
|
*/
|
||||||
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path) {
|
public static void saveAsJarClassesOnly(ArrayList<ClassNode> nodeList, String path) {
|
||||||
try {
|
try {
|
||||||
JarOutputStream out = new JarOutputStream(
|
System.out.println("zipping");
|
||||||
new FileOutputStream(path));
|
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
|
||||||
|
ArrayList<String> noDupe = new ArrayList<String>();
|
||||||
for (ClassNode cn : nodeList) {
|
for (ClassNode cn : nodeList) {
|
||||||
ClassWriter cw = new ClassWriter(0);
|
ClassWriter cw = new ClassWriter(0);
|
||||||
cn.accept(cw);
|
cn.accept(cw);
|
||||||
|
|
||||||
out.putNextEntry(new ZipEntry(cn.name + ".class"));
|
String name = cn.name + ".class";
|
||||||
out.write(cw.toByteArray());
|
|
||||||
out.closeEntry();
|
if(!noDupe.contains(name)) {
|
||||||
|
noDupe.add(name);
|
||||||
|
out.putNextEntry(new ZipEntry(name));
|
||||||
|
out.write(cw.toByteArray());
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
noDupe.clear();
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a jar without the manifest
|
||||||
|
* @param nodeList The loaded ClassNodes
|
||||||
|
* @param path the exact jar output path
|
||||||
|
*/
|
||||||
|
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path) {
|
||||||
|
try {
|
||||||
|
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
|
||||||
|
ArrayList<String> noDupe = new ArrayList<String>();
|
||||||
|
for (ClassNode cn : nodeList) {
|
||||||
|
ClassWriter cw = new ClassWriter(0);
|
||||||
|
cn.accept(cw);
|
||||||
|
|
||||||
|
String name = cn.name + ".class";
|
||||||
|
|
||||||
|
if(!noDupe.contains(name)) {
|
||||||
|
noDupe.add(name);
|
||||||
|
out.putNextEntry(new ZipEntry(name));
|
||||||
|
out.write(cw.toByteArray());
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(FileContainer container : BytecodeViewer.files)
|
for(FileContainer container : BytecodeViewer.files)
|
||||||
for (Entry<String, byte[]> entry : container.files.entrySet()) {
|
for (Entry<String, byte[]> entry : container.files.entrySet()) {
|
||||||
String filename = entry.getKey();
|
String filename = entry.getKey();
|
||||||
if (!filename.startsWith("META-INF")) {
|
if (!filename.startsWith("META-INF")) {
|
||||||
out.putNextEntry(new ZipEntry(filename));
|
if(!noDupe.contains(filename)) {
|
||||||
out.write(entry.getValue());
|
noDupe.add(filename);
|
||||||
out.closeEntry();
|
out.putNextEntry(new ZipEntry(filename));
|
||||||
|
out.write(entry.getValue());
|
||||||
|
out.closeEntry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noDupe.clear();
|
||||||
out.close();
|
out.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -47,7 +47,7 @@ public class KrakatauDecompiler extends Decompiler {
|
||||||
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
|
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
|
||||||
tempDirectory.mkdir();
|
tempDirectory.mkdir();
|
||||||
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
|
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
|
||||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
||||||
|
|
||||||
BytecodeViewer.sm.stopBlocking();
|
BytecodeViewer.sm.stopBlocking();
|
||||||
try {
|
try {
|
||||||
|
@ -121,7 +121,7 @@ public class KrakatauDecompiler extends Decompiler {
|
||||||
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
|
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
|
||||||
tempDirectory.mkdir();
|
tempDirectory.mkdir();
|
||||||
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
||||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
||||||
|
|
||||||
BytecodeViewer.sm.stopBlocking();
|
BytecodeViewer.sm.stopBlocking();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class KrakatauDisassembler extends Decompiler {
|
||||||
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
|
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
|
||||||
tempDirectory.mkdir();
|
tempDirectory.mkdir();
|
||||||
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
|
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
|
||||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
||||||
|
|
||||||
BytecodeViewer.sm.stopBlocking();
|
BytecodeViewer.sm.stopBlocking();
|
||||||
try {
|
try {
|
||||||
|
@ -102,7 +102,7 @@ public class KrakatauDisassembler extends Decompiler {
|
||||||
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
|
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
|
||||||
tempDirectory.mkdir();
|
tempDirectory.mkdir();
|
||||||
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
|
||||||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
|
||||||
|
|
||||||
BytecodeViewer.sm.stopBlocking();
|
BytecodeViewer.sm.stopBlocking();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -581,6 +581,13 @@ public class ClassViewer extends Viewer {
|
||||||
java2 = null;
|
java2 = null;
|
||||||
java3 = null;
|
java3 = null;
|
||||||
|
|
||||||
|
if(this.cn == null) {
|
||||||
|
panel1.add(new JLabel("This file has been removed from the reload."));
|
||||||
|
panel2.add(new JLabel("This file has been removed from the reload."));
|
||||||
|
panel3.add(new JLabel("This file has been removed from the reload."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (pane1 != 0 && pane1 != 5)
|
if (pane1 != 0 && pane1 != 5)
|
||||||
panel1.add(panel1Search, BorderLayout.NORTH);
|
panel1.add(panel1Search, BorderLayout.NORTH);
|
||||||
if (pane2 != 0 && pane2 != 5)
|
if (pane2 != 0 && pane2 != 5)
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.event.KeyListener;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -61,187 +62,156 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
|
|
||||||
MyTreeNode treeRoot = new MyTreeNode("Loaded Files:");
|
MyTreeNode treeRoot = new MyTreeNode("Loaded Files:");
|
||||||
MyTree tree = new MyTree(treeRoot);
|
MyTree tree = new MyTree(treeRoot);
|
||||||
|
final String quickSearchText = "Quick file search (no file extension)";
|
||||||
|
final JTextField quickSearch = new JTextField(quickSearchText);
|
||||||
|
|
||||||
|
public KeyAdapter search = new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(final KeyEvent ke) {
|
||||||
|
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||||
|
|
||||||
|
final String qt = quickSearch.getText();
|
||||||
|
quickSearch.setText("");
|
||||||
|
|
||||||
|
|
||||||
|
String[] path = null;
|
||||||
|
|
||||||
|
if (qt.contains(".")) {
|
||||||
|
path = qt.split("\\.");
|
||||||
|
String[] path2 = new String[path.length];
|
||||||
|
for(int i = 0; i < path.length; i++) {
|
||||||
|
path2[i] = path[i];
|
||||||
|
if(i+2 == path.length) {
|
||||||
|
path2[i+1] = "." + path[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
path = new String[] { qt };
|
||||||
|
}
|
||||||
|
|
||||||
|
MyTreeNode curNode = treeRoot;
|
||||||
|
if (exact.isSelected()) {
|
||||||
|
pathLoop: for (int i = 0; i < path.length; i++) {
|
||||||
|
final String pathName = path[i];
|
||||||
|
final boolean isLast = i == path.length - 1;
|
||||||
|
|
||||||
|
for (int c = 0; c < curNode.getChildCount(); c++) {
|
||||||
|
final MyTreeNode child = (MyTreeNode) curNode.getChildAt(c);
|
||||||
|
System.out.println(pathName +":"+((String) child.getUserObject()));
|
||||||
|
|
||||||
|
if (((String) child.getUserObject()).equals(pathName)) {
|
||||||
|
curNode = child;
|
||||||
|
if (isLast) {
|
||||||
|
final TreePath pathn = new TreePath(curNode.getPath());
|
||||||
|
tree.setSelectionPath(pathn);
|
||||||
|
tree.makeVisible(pathn);
|
||||||
|
tree.scrollPathToVisible(pathn);
|
||||||
|
openPath(pathn); //auto open
|
||||||
|
System.out.println("Found! " + curNode);
|
||||||
|
break pathLoop;
|
||||||
|
}
|
||||||
|
continue pathLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Could not find " + pathName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Enumeration<MyTreeNode> enums = curNode.depthFirstEnumeration();
|
||||||
|
while (enums != null && enums.hasMoreElements()) {
|
||||||
|
|
||||||
|
MyTreeNode node = enums.nextElement();
|
||||||
|
if (node.isLeaf()) {
|
||||||
|
if (((String) (node.getUserObject())).toLowerCase().contains(path[path.length - 1].toLowerCase())) {
|
||||||
|
TreeNode pathArray[] = node.getPath();
|
||||||
|
int k = 0;
|
||||||
|
StringBuffer fullPath = new StringBuffer();
|
||||||
|
while (pathArray != null
|
||||||
|
&& k < pathArray.length) {
|
||||||
|
MyTreeNode n = (MyTreeNode) pathArray[k];
|
||||||
|
String s = (String) (n.getUserObject());
|
||||||
|
fullPath.append(s);
|
||||||
|
if (k++ != pathArray.length - 1) {
|
||||||
|
fullPath.append(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String fullPathString = fullPath.toString();
|
||||||
|
if (fullPathString != null && fullPathString.toLowerCase().contains(qt.toLowerCase())) {
|
||||||
|
System.out.println("Found! " + node);
|
||||||
|
final TreePath pathn = new TreePath(node.getPath());
|
||||||
|
tree.setSelectionPath(pathn.getParentPath());
|
||||||
|
tree.setSelectionPath(pathn);
|
||||||
|
tree.makeVisible(pathn);
|
||||||
|
tree.scrollPathToVisible(pathn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public FileNavigationPane(final FileChangeNotifier fcn) {
|
public FileNavigationPane(final FileChangeNotifier fcn) {
|
||||||
super("ClassNavigation");
|
super("ClassNavigation");
|
||||||
setTitle("Files");
|
this.fcn = fcn;
|
||||||
|
|
||||||
|
|
||||||
tree.setRootVisible(false);
|
tree.setRootVisible(false);
|
||||||
tree.setShowsRootHandles(true);
|
tree.setShowsRootHandles(true);
|
||||||
|
quickSearch.setForeground(Color.gray);
|
||||||
|
setTitle("Files");
|
||||||
|
|
||||||
this.fcn = fcn;
|
this.open.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
open.addActionListener(new ActionListener() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
||||||
expandAll(tree, new TreePath(root), true);
|
expandAll(tree, new TreePath(root), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
close.addActionListener(new ActionListener() {
|
this.close.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
final TreeNode root = (TreeNode) tree.getModel().getRoot();
|
||||||
expandAll(tree, new TreePath(root), false);
|
expandAll(tree, new TreePath(root), false);
|
||||||
tree.expandPath(new TreePath(root));
|
tree.expandPath(new TreePath(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
getContentPane().setLayout(new BorderLayout());
|
|
||||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
|
||||||
|
|
||||||
MouseAdapter ml = new MouseAdapter() {
|
this.tree.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
|
openPath(tree.getPathForLocation(e.getX(), e.getY()));
|
||||||
if (path == null)
|
|
||||||
return;
|
|
||||||
final StringBuffer nameBuffer = new StringBuffer();
|
|
||||||
for (int i = 2; i < path.getPathCount(); i++) {
|
|
||||||
nameBuffer.append(path.getPathComponent(i));
|
|
||||||
if (i < path.getPathCount() - 1) {
|
|
||||||
nameBuffer.append("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = nameBuffer.toString();
|
|
||||||
if(name.endsWith(".class")) {
|
|
||||||
final ClassNode cn = BytecodeViewer.getClassNode(name.substring(0, name.length() - ".class".length()));
|
|
||||||
if (cn != null) {
|
|
||||||
openClassFileToWorkSpace(nameBuffer.toString(), cn);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
openFileToWorkSpace(nameBuffer.toString(), BytecodeViewer.getFileContents(nameBuffer.toString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
this.tree.addMouseListener(ml);
|
|
||||||
|
|
||||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void valueChanged(final TreeSelectionEvent arg0) {
|
public void valueChanged(final TreeSelectionEvent arg0) {
|
||||||
final TreePath path = arg0.getPath();
|
openPath(arg0.getPath());
|
||||||
if (((TreeNode) path.getLastPathComponent()).getChildCount() > 0)
|
|
||||||
return;
|
|
||||||
final StringBuffer nameBuffer = new StringBuffer();
|
|
||||||
for (int i = 1; i < path.getPathCount(); i++) {
|
|
||||||
nameBuffer.append(path.getPathComponent(i));
|
|
||||||
if (i < path.getPathCount() - 1) {
|
|
||||||
nameBuffer.append("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = nameBuffer.toString();
|
|
||||||
if(name.endsWith(".class")) {
|
|
||||||
final ClassNode cn = BytecodeViewer.getClassNode(name.substring(0, name.length() - ".class".length()));
|
|
||||||
if (cn != null) {
|
|
||||||
openClassFileToWorkSpace(nameBuffer.toString(), cn);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
openFileToWorkSpace(nameBuffer.toString(), BytecodeViewer.getFileContents(nameBuffer.toString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final String quickSearchText = "Quick class search (no file extension)";
|
this.tree.addKeyListener(new KeyListener() {
|
||||||
|
|
||||||
final JTextField quickSearch = new JTextField(quickSearchText);
|
|
||||||
quickSearch.setForeground(Color.gray);
|
|
||||||
quickSearch.addKeyListener(new KeyAdapter() {
|
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(final KeyEvent ke) {
|
public void keyReleased(KeyEvent arg0) {
|
||||||
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
|
if(arg0.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||||
|
if(arg0.getSource() instanceof MyTree) {
|
||||||
final String qt = quickSearch.getText();
|
MyTree tree = (MyTree) arg0.getSource();
|
||||||
quickSearch.setText("");
|
openPath(tree.getSelectionPath());
|
||||||
|
|
||||||
|
|
||||||
String[] path = null;
|
|
||||||
|
|
||||||
if (qt.contains(".")) {
|
|
||||||
path = qt.split("\\.");
|
|
||||||
String[] path2 = new String[path.length];
|
|
||||||
for(int i = 0; i < path.length; i++) {
|
|
||||||
path2[i] = path[i];
|
|
||||||
if(i+2 == path.length) {
|
|
||||||
path2[i+1] = "." + path[i+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
path = new String[] { qt };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MyTreeNode curNode = treeRoot;
|
|
||||||
if (exact.isSelected()) {
|
|
||||||
pathLoop: for (int i = 0; i < path.length; i++) {
|
|
||||||
final String pathName = path[i];
|
|
||||||
final boolean isLast = i == path.length - 1;
|
|
||||||
|
|
||||||
for (int c = 0; c < curNode.getChildCount(); c++) {
|
|
||||||
final MyTreeNode child = (MyTreeNode) curNode.getChildAt(c);
|
|
||||||
System.out.println(pathName +":"+((String) child.getUserObject()));
|
|
||||||
|
|
||||||
if (((String) child.getUserObject()).equals(pathName)) {
|
|
||||||
curNode = child;
|
|
||||||
if (isLast) {
|
|
||||||
final TreePath pathn = new TreePath(curNode.getPath());
|
|
||||||
tree.setSelectionPath(pathn);
|
|
||||||
tree.makeVisible(pathn);
|
|
||||||
tree.scrollPathToVisible(pathn);
|
|
||||||
System.out.println("Found! " + curNode);
|
|
||||||
break pathLoop;
|
|
||||||
}
|
|
||||||
continue pathLoop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println("Could not find " + pathName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
{
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Enumeration<MyTreeNode> enums = curNode.depthFirstEnumeration();
|
|
||||||
while (enums != null && enums.hasMoreElements()) {
|
|
||||||
|
|
||||||
MyTreeNode node = enums.nextElement();
|
|
||||||
if (node.isLeaf()) {
|
|
||||||
if (((String) (node.getUserObject())).toLowerCase().contains(path[path.length - 1].toLowerCase())) {
|
|
||||||
TreeNode pathArray[] = node.getPath();
|
|
||||||
int k = 0;
|
|
||||||
StringBuffer fullPath = new StringBuffer();
|
|
||||||
while (pathArray != null
|
|
||||||
&& k < pathArray.length) {
|
|
||||||
MyTreeNode n = (MyTreeNode) pathArray[k];
|
|
||||||
String s = (String) (n.getUserObject());
|
|
||||||
fullPath.append(s);
|
|
||||||
if (k++ != pathArray.length - 1) {
|
|
||||||
fullPath.append(".");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String fullPathString = fullPath.toString();
|
|
||||||
if (fullPathString != null && fullPathString.toLowerCase().contains(qt.toLowerCase())) {
|
|
||||||
System.out.println("Found! " + node);
|
|
||||||
final TreePath pathn = new TreePath(node.getPath());
|
|
||||||
tree.setSelectionPath(pathn.getParentPath());
|
|
||||||
tree.setSelectionPath(pathn);
|
|
||||||
tree.makeVisible(pathn);
|
|
||||||
tree.scrollPathToVisible(pathn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void keyPressed(KeyEvent arg0) { }
|
||||||
|
@Override public void keyTyped(KeyEvent arg0) { }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
quickSearch.addKeyListener(search);
|
||||||
|
|
||||||
quickSearch.addFocusListener(new FocusListener() {
|
quickSearch.addFocusListener(new FocusListener() {
|
||||||
@Override
|
@Override
|
||||||
public void focusGained(final FocusEvent arg0) {
|
public void focusGained(final FocusEvent arg0) {
|
||||||
|
@ -259,6 +229,9 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
getContentPane().setLayout(new BorderLayout());
|
||||||
|
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||||
|
|
||||||
JPanel p2 = new JPanel();
|
JPanel p2 = new JPanel();
|
||||||
p2.setLayout(new BorderLayout());
|
p2.setLayout(new BorderLayout());
|
||||||
|
@ -518,6 +491,28 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
tree.updateUI();
|
tree.updateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openPath(TreePath path) {
|
||||||
|
if (path == null)
|
||||||
|
return;
|
||||||
|
final StringBuffer nameBuffer = new StringBuffer();
|
||||||
|
for (int i = 2; i < path.getPathCount(); i++) {
|
||||||
|
nameBuffer.append(path.getPathComponent(i));
|
||||||
|
if (i < path.getPathCount() - 1) {
|
||||||
|
nameBuffer.append("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = nameBuffer.toString();
|
||||||
|
if(name.endsWith(".class")) {
|
||||||
|
final ClassNode cn = BytecodeViewer.getClassNode(name.substring(0, name.length() - ".class".length()));
|
||||||
|
if (cn != null) {
|
||||||
|
openClassFileToWorkSpace(nameBuffer.toString(), cn);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
openFileToWorkSpace(nameBuffer.toString(), BytecodeViewer.getFileContents(nameBuffer.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author http://stackoverflow.com/questions/14968005
|
* @author http://stackoverflow.com/questions/14968005
|
||||||
|
@ -544,31 +539,33 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
String name = node.toString().toLowerCase();
|
String name = node.toString().toLowerCase();
|
||||||
|
|
||||||
if(name.endsWith(".jar")) {
|
if(name.endsWith(".jar")) {
|
||||||
setIcon(Resources.jar);
|
setIcon(Resources.jarIcon);
|
||||||
} else if(name.endsWith(".zip")) {
|
} else if(name.endsWith(".zip")) {
|
||||||
setIcon(Resources.zip);
|
setIcon(Resources.zipIcon);
|
||||||
} else if(name.endsWith(".bat")) {
|
} else if(name.endsWith(".bat")) {
|
||||||
setIcon(Resources.bat);
|
setIcon(Resources.batIcon);
|
||||||
} else if(name.endsWith(".sh")) {
|
} else if(name.endsWith(".sh")) {
|
||||||
setIcon(Resources.sh);
|
setIcon(Resources.shIcon);
|
||||||
} else if(name.endsWith(".cs")) {
|
} else if(name.endsWith(".cs")) {
|
||||||
setIcon(Resources.csharp);
|
setIcon(Resources.csharpIcon);
|
||||||
} else if(name.endsWith(".c") ||name.endsWith(".cpp") ||name.endsWith(".h")) {
|
} else if(name.endsWith(".c") ||name.endsWith(".cpp") ||name.endsWith(".h")) {
|
||||||
setIcon(Resources.cplusplus);
|
setIcon(Resources.cplusplusIcon);
|
||||||
} else if(name.endsWith(".apk") || name.endsWith(".dex")) {
|
} else if(name.endsWith(".apk") || name.endsWith(".dex")) {
|
||||||
setIcon(Resources.android);
|
setIcon(Resources.androidIcon);
|
||||||
} else if(name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".bmp") || name.endsWith(".gif")) {
|
} else if(name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".bmp") || name.endsWith(".gif")) {
|
||||||
setIcon(Resources.imageFile);
|
setIcon(Resources.imageIcon);
|
||||||
} else if(name.endsWith(".class")) {
|
} else if(name.endsWith(".class")) {
|
||||||
setIcon(Resources.classFile);
|
setIcon(Resources.classIcon);
|
||||||
|
} else if(name.endsWith(".java")) {
|
||||||
|
setIcon(Resources.javaIcon);
|
||||||
} else if(name.endsWith(".txt") || name.endsWith(".md")) {
|
} else if(name.endsWith(".txt") || name.endsWith(".md")) {
|
||||||
setIcon(Resources.textFile);
|
setIcon(Resources.textIcon);
|
||||||
} else if(name.equals("decoded resources")) {
|
} else if(name.equals("decoded resources")) {
|
||||||
setIcon(Resources.decoded);
|
setIcon(Resources.decodedIcon);
|
||||||
} else if(name.endsWith(".properties") || name.endsWith(".xml") || name.endsWith(".mf") || name.endsWith(".config") || name.endsWith(".cfg")) {
|
} else if(name.endsWith(".properties") || name.endsWith(".xml") || name.endsWith(".mf") || name.endsWith(".config") || name.endsWith(".cfg")) {
|
||||||
setIcon(Resources.config);
|
setIcon(Resources.configIcon);
|
||||||
} else if(node.getChildCount() <= 0) { //random file
|
} else if(node.getChildCount() <= 0) { //random file
|
||||||
setIcon(Resources.file);
|
setIcon(Resources.fileIcon);
|
||||||
} else { //folder
|
} else { //folder
|
||||||
ArrayList<TreeNode> nodes = new ArrayList<TreeNode>();
|
ArrayList<TreeNode> nodes = new ArrayList<TreeNode>();
|
||||||
ArrayList<TreeNode> totalNodes = new ArrayList<TreeNode>();
|
ArrayList<TreeNode> totalNodes = new ArrayList<TreeNode>();
|
||||||
|
@ -605,9 +602,9 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isJava)
|
if(isJava)
|
||||||
setIcon(Resources.packages);
|
setIcon(Resources.packagesIcon);
|
||||||
else {
|
else {
|
||||||
setIcon(Resources.folder);
|
setIcon(Resources.folderIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.objectweb.asm.tree.ClassNode;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
import the.bytecode.club.bytecodeviewer.Dex2Jar;
|
import the.bytecode.club.bytecodeviewer.Dex2Jar;
|
||||||
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
||||||
|
import the.bytecode.club.bytecodeviewer.FileContainer;
|
||||||
import the.bytecode.club.bytecodeviewer.JarUtils;
|
import the.bytecode.club.bytecodeviewer.JarUtils;
|
||||||
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
||||||
import the.bytecode.club.bytecodeviewer.Resources;
|
import the.bytecode.club.bytecodeviewer.Resources;
|
||||||
|
@ -526,9 +527,9 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (busy) {
|
if (busy) {
|
||||||
try {
|
try {
|
||||||
mntmNewMenuItem_4.setIcon(Resources.busy);
|
mntmNewMenuItem_4.setIcon(Resources.busyIcon);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
mntmNewMenuItem_4.setIcon(Resources.busyB64);
|
mntmNewMenuItem_4.setIcon(Resources.busyB64Icon);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
mntmNewMenuItem_4.setIcon(null);
|
mntmNewMenuItem_4.setIcon(null);
|
||||||
|
@ -564,6 +565,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
public final ButtonGroup apkConversionGroup = new ButtonGroup();
|
public final ButtonGroup apkConversionGroup = new ButtonGroup();
|
||||||
public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar");
|
public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar");
|
||||||
public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify");
|
public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify");
|
||||||
|
private final JMenuItem mntmSetPythonx = new JMenuItem("Set Python 3.X Executable");
|
||||||
|
private final JMenuItem mntmReloadResources = new JMenuItem("Reload Resources");
|
||||||
|
private final JSeparator separator_39 = new JSeparator();
|
||||||
|
private final JSeparator separator_40 = new JSeparator();
|
||||||
|
|
||||||
public void calledAfterLoad() {
|
public void calledAfterLoad() {
|
||||||
chckbxmntmDeleteForiegnoutdatedLibs.setSelected(BytecodeViewer.deleteForiegnLibraries);
|
chckbxmntmDeleteForiegnoutdatedLibs.setSelected(BytecodeViewer.deleteForiegnLibraries);
|
||||||
|
@ -677,6 +682,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mnNewMenu.add(mntmLoadJar);
|
mnNewMenu.add(mntmLoadJar);
|
||||||
|
|
||||||
|
mnNewMenu.add(separator_40);
|
||||||
|
|
||||||
mnNewMenu.add(mntmNewWorkspace);
|
mnNewMenu.add(mntmNewWorkspace);
|
||||||
|
|
||||||
|
@ -747,6 +754,35 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mnNewMenu.add(separator_39);
|
||||||
|
mntmReloadResources.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
JOptionPane pane = new JOptionPane("Are you sure you wish to reload the resources?");
|
||||||
|
Object[] options = new String[] { "Yes", "No" };
|
||||||
|
pane.setOptions(options);
|
||||||
|
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Reload Resources");
|
||||||
|
dialog.setVisible(true);
|
||||||
|
Object obj = pane.getValue();
|
||||||
|
int result = -1;
|
||||||
|
for (int k = 0; k < options.length; k++)
|
||||||
|
if (options[k].equals(obj))
|
||||||
|
result = k;
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
ArrayList<File> reopen = new ArrayList<File>();
|
||||||
|
for(FileContainer container : BytecodeViewer.files)
|
||||||
|
reopen.add(container.file);
|
||||||
|
|
||||||
|
BytecodeViewer.files.clear();
|
||||||
|
BytecodeViewer.openFiles(reopen.toArray(new File[reopen.size()]), false);
|
||||||
|
|
||||||
|
//refresh panes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mnNewMenu.add(mntmReloadResources);
|
||||||
|
|
||||||
mnNewMenu.add(separator_3);
|
mnNewMenu.add(separator_3);
|
||||||
mntmNewMenuItem_3.addActionListener(new ActionListener() {
|
mntmNewMenuItem_3.addActionListener(new ActionListener() {
|
||||||
|
@ -1491,6 +1527,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
mnApkConversion.add(apkConversionEnjarify);
|
mnApkConversion.add(apkConversionEnjarify);
|
||||||
|
|
||||||
mnSettings.add(separator_37);
|
mnSettings.add(separator_37);
|
||||||
|
chckbxmntmNewCheckItem_12.setSelected(true);
|
||||||
mnSettings.add(chckbxmntmNewCheckItem_12);
|
mnSettings.add(chckbxmntmNewCheckItem_12);
|
||||||
chckbxmntmDeleteForiegnoutdatedLibs.addActionListener(new ActionListener() {
|
chckbxmntmDeleteForiegnoutdatedLibs.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
@ -1519,6 +1556,13 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
rtC();
|
rtC();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
mntmSetPythonx.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
pythonC3();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mnSettings.add(mntmSetPythonx);
|
||||||
|
|
||||||
mnSettings.add(mntmSetJreRt);
|
mnSettings.add(mntmSetJreRt);
|
||||||
mntmSetOpitonalLibrary.addActionListener(new ActionListener() {
|
mntmSetOpitonalLibrary.addActionListener(new ActionListener() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user