parent
5603f466b3
commit
2314af5f7f
5 changed files with 135 additions and 120 deletions
|
@ -72,29 +72,31 @@ import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
* http://the.bytecode.club
|
* http://the.bytecode.club
|
||||||
*
|
*
|
||||||
* TODO BUGS:
|
* TODO BUGS:
|
||||||
* Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
* + Tab simplified titles aren't working correctly until refreshed
|
||||||
|
* + Synchronized scrolling is broken
|
||||||
|
* + Spam-clicking the refresh button will cause the swing thread to deadlock (Quickly opening resources used to also do this)
|
||||||
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
|
* This is caused by the ctrlMouseWheelZoom code, a temporary patch is just removing it worst case
|
||||||
* Open as folder doesn't actually work
|
* + Open as folder doesn't actually work
|
||||||
* Fix classfile searcher
|
* + Fix classfile searcher
|
||||||
* Smali Assembly compile - Needs to be fixed
|
* + Smali Assembly compile - Needs to be fixed
|
||||||
* Krakatau Assembly compile - Needs to be fixed
|
* + Krakatau Assembly compile - Needs to be fixed
|
||||||
*
|
*
|
||||||
* TODO IN-PROGRESS:
|
* TODO IN-PROGRESS:
|
||||||
* Finish dragging code
|
* + Finish dragging code
|
||||||
* Finish right-click tab menu detection
|
* + Finish right-click tab menu detection
|
||||||
* Fix hook inject for EZ-Injection
|
* + Fix hook inject for EZ-Injection
|
||||||
*
|
*
|
||||||
* TODO FEATURES:
|
* TODO FEATURES:
|
||||||
* Add stackmapframes to bytecode decompiler
|
* + Add stackmapframes to bytecode decompiler
|
||||||
* Add JEB decompiler optionally, requires them to add jeb library jar
|
* + Add JEB decompiler optionally, requires them to add jeb library jar
|
||||||
* Add https://github.com/ptnkjke/Java-Bytecode-Editor visualize as a plugin
|
* + Add https://github.com/ptnkjke/Java-Bytecode-Editor visualize as a plugin
|
||||||
* Add https://github.com/exbin/bined as the replacement Hed Viewer/Editor
|
* + Add https://github.com/exbin/bined as the replacement Hed Viewer/Editor
|
||||||
* Make the decompilers launch in a separate process
|
* + Make the decompilers launch in a separate process
|
||||||
* Make it use that global last used inside of export as jar
|
* + Make it use that global last used inside of export as jar
|
||||||
* Make zipfile not include the decode shit
|
* + Make zipfile not include the decode shit
|
||||||
* Make ez-injection plugin console show all sys.out calls
|
* + Make ez-injection plugin console show all sys.out calls
|
||||||
* Add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
|
* + Add decompile as zip for krakatau-bytecode, jd-gui and smali for CLI
|
||||||
* Add decompile all as zip for CLI
|
* + Add decompile all as zip for CLI
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
* @author The entire BCV community
|
* @author The entire BCV community
|
||||||
|
@ -235,7 +237,7 @@ public class BytecodeViewer
|
||||||
}));
|
}));
|
||||||
|
|
||||||
viewer.calledAfterLoad();
|
viewer.calledAfterLoad();
|
||||||
resetRecentFilesMenu();
|
Constants.resetRecentFilesMenu();
|
||||||
|
|
||||||
if (!Configuration.pingback) {
|
if (!Configuration.pingback) {
|
||||||
pingBack.start();
|
pingBack.start();
|
||||||
|
@ -518,7 +520,7 @@ public class BytecodeViewer
|
||||||
if (recentFiles)
|
if (recentFiles)
|
||||||
for (File f : files)
|
for (File f : files)
|
||||||
if (f.exists())
|
if (f.exists())
|
||||||
BytecodeViewer.addRecentFile(f);
|
Constants.addRecentFile(f);
|
||||||
|
|
||||||
BytecodeViewer.viewer.updateBusyStatus(true);
|
BytecodeViewer.viewer.updateBusyStatus(true);
|
||||||
Configuration.needsReDump = true;
|
Configuration.needsReDump = true;
|
||||||
|
@ -585,90 +587,6 @@ public class BytecodeViewer
|
||||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().clear();
|
the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<String> killList = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the recent file
|
|
||||||
*
|
|
||||||
* @param f the recent file
|
|
||||||
*/
|
|
||||||
public static void addRecentFile(File f) {
|
|
||||||
for (int i = 0; i < recentFiles.size(); i++) { // remove dead strings
|
|
||||||
String s = recentFiles.get(i);
|
|
||||||
if (s.isEmpty() || i > maxRecentFiles)
|
|
||||||
killList.add(s);
|
|
||||||
}
|
|
||||||
if (!killList.isEmpty()) {
|
|
||||||
for (String s : killList)
|
|
||||||
recentFiles.remove(s);
|
|
||||||
killList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// already added on the list
|
|
||||||
recentFiles.remove(f.getAbsolutePath());
|
|
||||||
if (recentFiles.size() >= maxRecentFiles)
|
|
||||||
recentFiles.remove(maxRecentFiles - 1); // zero indexing
|
|
||||||
|
|
||||||
recentFiles.add(0, f.getAbsolutePath());
|
|
||||||
DiskWriter.replaceFile(filesName, MiscUtils.listToString(recentFiles), false);
|
|
||||||
resetRecentFilesMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final List<String> killList2 = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to the recent plugin list
|
|
||||||
*
|
|
||||||
* @param f the plugin file
|
|
||||||
*/
|
|
||||||
public static void addRecentPlugin(File f) {
|
|
||||||
for (int i = 0; i < recentPlugins.size(); i++) { // remove dead strings
|
|
||||||
String s = recentPlugins.get(i);
|
|
||||||
if (s.isEmpty() || i > maxRecentFiles)
|
|
||||||
killList2.add(s);
|
|
||||||
}
|
|
||||||
if (!killList2.isEmpty()) {
|
|
||||||
for (String s : killList2)
|
|
||||||
recentPlugins.remove(s);
|
|
||||||
killList2.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// already added on the list
|
|
||||||
recentPlugins.remove(f.getAbsolutePath());
|
|
||||||
if (recentPlugins.size() >= maxRecentFiles)
|
|
||||||
recentPlugins.remove(maxRecentFiles - 1); // zero indexing
|
|
||||||
|
|
||||||
recentPlugins.add(0, f.getAbsolutePath());
|
|
||||||
DiskWriter.replaceFile(pluginsName, MiscUtils.listToString(recentPlugins), false);
|
|
||||||
resetRecentFilesMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resets the recent files menu
|
|
||||||
*/
|
|
||||||
public static void resetRecentFilesMenu() {
|
|
||||||
viewer.recentFilesSecondaryMenu.removeAll();
|
|
||||||
for (String s : recentFiles)
|
|
||||||
if (!s.isEmpty()) {
|
|
||||||
JMenuItem m = new JMenuItem(s);
|
|
||||||
m.addActionListener(e -> {
|
|
||||||
JMenuItem m12 = (JMenuItem) e.getSource();
|
|
||||||
openFiles(new File[]{new File(m12.getText())}, true);
|
|
||||||
});
|
|
||||||
viewer.recentFilesSecondaryMenu.add(m);
|
|
||||||
}
|
|
||||||
viewer.recentPluginsSecondaryMenu.removeAll();
|
|
||||||
for (String s : recentPlugins)
|
|
||||||
if (!s.isEmpty()) {
|
|
||||||
JMenuItem m = new JMenuItem(s);
|
|
||||||
m.addActionListener(e -> {
|
|
||||||
JMenuItem m1 = (JMenuItem) e.getSource();
|
|
||||||
startPlugin(new File(m1.getText()));
|
|
||||||
});
|
|
||||||
viewer.recentPluginsSecondaryMenu.add(m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the temp directory
|
* Clears the temp directory
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,7 +4,10 @@ import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import me.konloch.kontainer.io.DiskReader;
|
import me.konloch.kontainer.io.DiskReader;
|
||||||
|
import me.konloch.kontainer.io.DiskWriter;
|
||||||
|
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -42,12 +45,14 @@ public class Constants
|
||||||
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
|
public static String enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + enjarifyVersion;
|
||||||
public static final String[] SUPPORTED_FILE_EXTENSIONS = new String[]{"jar", "zip", "class", "apk", "dex", "war", "jsp"};
|
public static final String[] SUPPORTED_FILE_EXTENSIONS = new String[]{"jar", "zip", "class", "apk", "dex", "war", "jsp"};
|
||||||
|
|
||||||
public static List<String> recentPlugins;
|
private static List<String> recentPlugins;
|
||||||
public static List<String> recentFiles;
|
private static List<String> recentFiles;
|
||||||
public static Gson gson;
|
public static Gson gson;
|
||||||
|
|
||||||
static {
|
static
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
gson = new GsonBuilder().setPrettyPrinting().create();
|
gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
if (new File(filesName).exists())
|
if (new File(filesName).exists())
|
||||||
recentFiles = gson.fromJson(DiskReader.loadAsString(filesName), new TypeToken<ArrayList<String>>() {}.getType());
|
recentFiles = gson.fromJson(DiskReader.loadAsString(filesName), new TypeToken<ArrayList<String>>() {}.getType());
|
||||||
|
@ -58,17 +63,89 @@ public class Constants
|
||||||
recentPlugins = gson.fromJson(DiskReader.loadAsString(pluginsName), new TypeToken<ArrayList<String>>() {}.getType());
|
recentPlugins = gson.fromJson(DiskReader.loadAsString(pluginsName), new TypeToken<ArrayList<String>>() {}.getType());
|
||||||
else
|
else
|
||||||
recentPlugins = DiskReader.loadArrayList(getBCVDirectory() + fs + "recentplugins.bcv", false);
|
recentPlugins = DiskReader.loadArrayList(getBCVDirectory() + fs + "recentplugins.bcv", false);
|
||||||
} catch (Exception e) {
|
|
||||||
|
MiscUtils.deduplicateAndTrim(recentFiles, 25);
|
||||||
|
MiscUtils.deduplicateAndTrim(recentPlugins, 25);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the recent file
|
||||||
|
*
|
||||||
|
* @param f the recent file
|
||||||
|
*/
|
||||||
|
public static void addRecentFile(File f)
|
||||||
|
{
|
||||||
|
recentFiles.remove(f.getAbsolutePath()); // already added on the list
|
||||||
|
recentFiles.add(0, f.getAbsolutePath());
|
||||||
|
MiscUtils.deduplicateAndTrim(recentFiles, 25);
|
||||||
|
DiskWriter.replaceFile(filesName, MiscUtils.listToString(recentFiles), false);
|
||||||
|
resetRecentFilesMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to the recent plugin list
|
||||||
|
*
|
||||||
|
* @param f the plugin file
|
||||||
|
*/
|
||||||
|
public static void addRecentPlugin(File f)
|
||||||
|
{
|
||||||
|
recentPlugins.remove(f.getAbsolutePath()); // already added on the list
|
||||||
|
recentPlugins.add(0, f.getAbsolutePath());
|
||||||
|
MiscUtils.deduplicateAndTrim(recentPlugins, 25);
|
||||||
|
DiskWriter.replaceFile(pluginsName, MiscUtils.listToString(recentPlugins), false);
|
||||||
|
resetRecentFilesMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resets the recent files menu
|
||||||
|
*/
|
||||||
|
protected static void resetRecentFilesMenu()
|
||||||
|
{
|
||||||
|
//build recent files
|
||||||
|
BytecodeViewer.viewer.recentFilesSecondaryMenu.removeAll();
|
||||||
|
for (String s : recentFiles)
|
||||||
|
{
|
||||||
|
if (!s.isEmpty())
|
||||||
|
{
|
||||||
|
JMenuItem m = new JMenuItem(s);
|
||||||
|
m.addActionListener(e ->
|
||||||
|
{
|
||||||
|
JMenuItem m12 = (JMenuItem) e.getSource();
|
||||||
|
BytecodeViewer.openFiles(new File[]{new File(m12.getText())}, true);
|
||||||
|
});
|
||||||
|
BytecodeViewer.viewer.recentFilesSecondaryMenu.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//build recent plugins
|
||||||
|
BytecodeViewer.viewer.recentPluginsSecondaryMenu.removeAll();
|
||||||
|
for (String s : recentPlugins)
|
||||||
|
{
|
||||||
|
if (!s.isEmpty())
|
||||||
|
{
|
||||||
|
JMenuItem m = new JMenuItem(s);
|
||||||
|
m.addActionListener(e ->
|
||||||
|
{
|
||||||
|
JMenuItem m1 = (JMenuItem) e.getSource();
|
||||||
|
BytecodeViewer.startPlugin(new File(m1.getText()));
|
||||||
|
});
|
||||||
|
BytecodeViewer.viewer.recentPluginsSecondaryMenu.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the BCV directory
|
* Returns the BCV directory
|
||||||
*
|
*
|
||||||
* @return the static BCV directory
|
* @return the static BCV directory
|
||||||
*/
|
*/
|
||||||
public static String getBCVDirectory() {
|
public static String getBCVDirectory()
|
||||||
|
{
|
||||||
while (!BCVDir.exists())
|
while (!BCVDir.exists())
|
||||||
BCVDir.mkdirs();
|
BCVDir.mkdirs();
|
||||||
|
|
||||||
|
@ -83,7 +160,8 @@ public class Constants
|
||||||
*
|
*
|
||||||
* @return true if the os.name property contains 'win'
|
* @return true if the os.name property contains 'win'
|
||||||
*/
|
*/
|
||||||
private static boolean isWindows() {
|
private static boolean isWindows()
|
||||||
|
{
|
||||||
return System.getProperty("os.name").toLowerCase().contains("win");
|
return System.getProperty("os.name").toLowerCase().contains("win");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +170,8 @@ public class Constants
|
||||||
*
|
*
|
||||||
* @param f file you want hidden
|
* @param f file you want hidden
|
||||||
*/
|
*/
|
||||||
private static void hideFile(File f) {
|
private static void hideFile(File f)
|
||||||
|
{
|
||||||
BytecodeViewer.sm.stopBlocking();
|
BytecodeViewer.sm.stopBlocking();
|
||||||
try {
|
try {
|
||||||
// Hide file by running attrib system command (on Windows)
|
// Hide file by running attrib system command (on Windows)
|
||||||
|
|
|
@ -51,7 +51,6 @@ import the.bytecode.club.bytecodeviewer.util.SyntaxLanguage;
|
||||||
|
|
||||||
public class FileViewer extends ResourceViewer
|
public class FileViewer extends ResourceViewer
|
||||||
{
|
{
|
||||||
public final String name;
|
|
||||||
public final byte[] contents;
|
public final byte[] contents;
|
||||||
public final String workingName;
|
public final String workingName;
|
||||||
|
|
||||||
|
@ -82,8 +81,6 @@ public class FileViewer extends ResourceViewer
|
||||||
final String nameLowerCase = this.name.toLowerCase();
|
final String nameLowerCase = this.name.toLowerCase();
|
||||||
final String contentsAsString = new String(contents);
|
final String contentsAsString = new String(contents);
|
||||||
|
|
||||||
refreshTitle();
|
|
||||||
|
|
||||||
//image viewer
|
//image viewer
|
||||||
if (!MiscUtils.isPureAscii(contentsAsString))
|
if (!MiscUtils.isPureAscii(contentsAsString))
|
||||||
{
|
{
|
||||||
|
@ -128,6 +125,8 @@ public class FileViewer extends ResourceViewer
|
||||||
textArea.setCaretPosition(0);
|
textArea.setCaretPosition(0);
|
||||||
|
|
||||||
mainPanel.add(textArea.getScrollPane());
|
mainPanel.add(textArea.getScrollPane());
|
||||||
|
|
||||||
|
refreshTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -139,6 +138,8 @@ public class FileViewer extends ResourceViewer
|
||||||
|
|
||||||
public void refresh(JButton src)
|
public void refresh(JButton src)
|
||||||
{
|
{
|
||||||
|
refreshTitle();
|
||||||
|
|
||||||
if (!canRefresh)
|
if (!canRefresh)
|
||||||
{
|
{
|
||||||
src.setEnabled(true);
|
src.setEnabled(true);
|
||||||
|
@ -152,8 +153,6 @@ public class FileViewer extends ResourceViewer
|
||||||
JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER);
|
JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER);
|
||||||
mainPanel.add(label, BorderLayout.CENTER);
|
mainPanel.add(label, BorderLayout.CENTER);
|
||||||
mainPanel.updateUI();
|
mainPanel.updateUI();
|
||||||
|
|
||||||
refreshTitle();
|
|
||||||
|
|
||||||
src.setEnabled(true);
|
src.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,20 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A ResourceViewer
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
*/
|
||||||
|
|
||||||
public abstract class ResourceViewer extends JPanel
|
public abstract class ResourceViewer extends JPanel
|
||||||
{
|
{
|
||||||
public ClassNode cn;
|
public ClassNode cn;
|
||||||
public String originalName;
|
|
||||||
public String name;
|
public String name;
|
||||||
public FileContainer container;
|
public FileContainer container;
|
||||||
|
|
||||||
|
public abstract void refreshTitle();
|
||||||
|
|
||||||
public String getTabName()
|
public String getTabName()
|
||||||
{
|
{
|
||||||
String tabName = name;
|
String tabName = name;
|
||||||
|
@ -42,8 +49,6 @@ public abstract class ResourceViewer extends JPanel
|
||||||
|
|
||||||
return tabName;
|
return tabName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void refreshTitle();
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -2965538493489119191L;
|
private static final long serialVersionUID = -2965538493489119191L;
|
||||||
}
|
}
|
|
@ -210,6 +210,20 @@ public class MiscUtils
|
||||||
return defaultImage;
|
return defaultImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deduplicateAndTrim(List<String> list, int maxLength)
|
||||||
|
{
|
||||||
|
List<String> temporaryList = new ArrayList<>();
|
||||||
|
for(String s : list)
|
||||||
|
if(!s.isEmpty() && !temporaryList.contains(s))
|
||||||
|
temporaryList.add(s);
|
||||||
|
|
||||||
|
list.clear();
|
||||||
|
list.addAll(temporaryList);
|
||||||
|
|
||||||
|
while(temporaryList.size() > maxLength)
|
||||||
|
list.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isPureAscii(String v) {
|
public static boolean isPureAscii(String v) {
|
||||||
return asciiEncoder.canEncode(v);
|
return asciiEncoder.canEncode(v);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue