Code Style Update

This commit is contained in:
Konloch 2024-09-25 21:40:07 -06:00
parent c85a8a21f3
commit fda1ecab66

AI 샘플 코드 생성 중입니다

Loading...
350 changed files with 26760 additions and 27726 deletions

View File

@ -1,14 +1,11 @@
package me.konloch.kontainer.io;
import the.bytecode.club.bytecodeviewer.util.EncodeUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import the.bytecode.club.bytecodeviewer.util.EncodeUtils;
import java.util.*;
/**
* Used to load from the disk, optional caching
@ -16,7 +13,8 @@ import the.bytecode.club.bytecodeviewer.util.EncodeUtils;
* @author Konloch
*/
public class DiskReader {
public class DiskReader
{
public static Random random = new Random();
public static Map<String, List<String>> map = new HashMap<>();
@ -24,17 +22,19 @@ public class DiskReader {
/**
* Used to load from file, allows caching
*/
public synchronized static List<String> loadArrayList(String fileName,
boolean cache) {
public synchronized static List<String> loadArrayList(String fileName, boolean cache)
{
List<String> array = new ArrayList<>();
if (!map.containsKey(fileName)) {
try {
if (!map.containsKey(fileName))
{
try
{
File file = new File(fileName);
if (!file.exists()) // doesn't exist, return empty
return array;
try (FileReader fr = new FileReader(file);
BufferedReader reader = new BufferedReader(fr)) {
try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr))
{
String add;
while ((add = reader.readLine()) != null)
@ -44,10 +44,14 @@ public class DiskReader {
if (cache)
map.put(fileName, array);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
} else {
}
else
{
array = map.get(fileName);
}
@ -58,12 +62,14 @@ public class DiskReader {
/**
* Used to load from file
*/
public synchronized static String loadAsString(String fileName) throws Exception {
public synchronized static String loadAsString(String fileName) throws Exception
{
StringBuilder s = new StringBuilder();
try (FileReader fr = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fr)) {
for (String add = reader.readLine(); add != null; add = reader.readLine()) {
try (FileReader fr = new FileReader(fileName); BufferedReader reader = new BufferedReader(fr))
{
for (String add = reader.readLine(); add != null; add = reader.readLine())
{
s.append(EncodeUtils.unicodeToString(add)).append(System.lineSeparator());
}
}
@ -74,16 +80,17 @@ public class DiskReader {
/**
* Used to load a string via line number lineNumber = -1 means random.
*/
public static String loadString(String fileName, int lineNumber,
boolean cache) throws Exception {
public static String loadString(String fileName, int lineNumber, boolean cache) throws Exception
{
List<String> array;
if (!map.containsKey(fileName)) {
if (!map.containsKey(fileName))
{
array = new ArrayList<>();
File file = new File(fileName);
try (FileReader fr = new FileReader(file);
BufferedReader reader = new BufferedReader(fr)) {
try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr))
{
String add;
while ((add = reader.readLine()) != null)
@ -92,14 +99,18 @@ public class DiskReader {
if (cache)
map.put(fileName, array);
} else {
}
else
{
array = map.get(fileName);
}
if (lineNumber == -1) {
if (lineNumber == -1)
{
int size = array.size();
return array.get(random.nextInt(size));
} else
}
else
return array.get(lineNumber);
}

View File

@ -1,10 +1,6 @@
package me.konloch.kontainer.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.*;
import java.util.Arrays;
/**
@ -13,7 +9,8 @@ import java.util.Arrays;
* @author Konloch
*/
public class DiskWriter {
public class DiskWriter
{
/**
* Used to insert a difference string with preserving the file extension
@ -23,13 +20,15 @@ public class DiskWriter {
* @return The filename with the difference inserted and the file extension
* preserved
*/
public static String insertFileName(String fileName, String difference) {
public static String insertFileName(String fileName, String difference)
{
String[] babe = fileName.split("\\.");
int count = 0;
int math = babe.length;
StringBuilder m = new StringBuilder();
for (String s2 : babe) {
for (String s2 : babe)
{
m.append(s2);
if (math - 2 == count)
m.append(difference).append(".");
@ -49,8 +48,8 @@ public class DiskWriter {
* @param fileContents
* @param debug
*/
public static synchronized void writeNewLine(String filename,
byte[] fileContents, boolean debug) {
public static synchronized void writeNewLine(String filename, byte[] fileContents, boolean debug)
{
new File(filename).getParentFile().mkdirs();
String original = filename;
int counter = 0;
@ -59,20 +58,22 @@ public class DiskWriter {
int failSafe = 0;
while (!saved && failSafe++ <= 42069)
{
try (FileWriter fr = new FileWriter(filename, true);
BufferedWriter bw = new BufferedWriter(fr);
PrintWriter writer = new PrintWriter(bw)) {
try (FileWriter fr = new FileWriter(filename, true); BufferedWriter bw = new BufferedWriter(fr); PrintWriter writer = new PrintWriter(bw))
{
writer.println(Arrays.toString(fileContents));
if (debug)
System.out.println("Saved " + filename + " to disk");
saved = true;
} catch (Exception e) {
}
catch (Exception e)
{
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
System.out.println("Failed saving, trying to save as " + filename);
if (original.contains("."))
{
filename = insertFileName(original, "" + counter);
} else
}
else
filename = original + counter;
counter++;
}
@ -90,8 +91,8 @@ public class DiskWriter {
/**
* Writes a string to the file
*/
public static synchronized void writeNewLine(String filename,
String lineToWrite, boolean debug) {
public static synchronized void writeNewLine(String filename, String lineToWrite, boolean debug)
{
new File(filename).getParentFile().mkdirs();
String original = filename;
int counter = 0;
@ -100,21 +101,22 @@ public class DiskWriter {
int failSafe = 0;
while (!saved && failSafe++ <= 42069)
{
try (FileWriter fr = new FileWriter(filename, true);
BufferedWriter bw = new BufferedWriter(fr);
PrintWriter writer = new PrintWriter(bw)) {
try (FileWriter fr = new FileWriter(filename, true); BufferedWriter bw = new BufferedWriter(fr); PrintWriter writer = new PrintWriter(bw))
{
writer.println(lineToWrite);
if (debug)
System.out.println("Saved " + filename + ">" + lineToWrite
+ " to disk");
System.out.println("Saved " + filename + ">" + lineToWrite + " to disk");
saved = true;
} catch (Exception e) {
}
catch (Exception e)
{
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
System.out.println("Failed saving, trying to save as " + filename);
if (original.contains("."))
{
filename = insertFileName(original, "" + counter);
} else
}
else
filename = original + counter;
counter++;
}
@ -129,8 +131,8 @@ public class DiskWriter {
* @param fileContents
* @param debug
*/
public static synchronized void replaceFileBytes(String filename,
byte[] fileContents, boolean debug) {
public static synchronized void replaceFileBytes(String filename, byte[] fileContents, boolean debug)
{
new File(filename).getParentFile().mkdirs();
File f = new File(filename);
if (f.exists())
@ -150,13 +152,16 @@ public class DiskWriter {
if (debug)
System.out.println("Saved " + filename + " to disk");
saved = true;
} catch (Exception e) {
}
catch (Exception e)
{
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
System.out.println("Failed saving, trying to save as " + filename);
if (original.contains("."))
{
filename = insertFileName(original, "" + counter);
} else
}
else
filename = original + counter;
counter++;
}
@ -171,8 +176,8 @@ public class DiskWriter {
* @param lineToWrite
* @param debug
*/
public static synchronized void replaceFile(String filename,
String lineToWrite, boolean debug) {
public static synchronized void replaceFile(String filename, String lineToWrite, boolean debug)
{
new File(filename).getParentFile().mkdirs();
File f = new File(filename);
if (f.exists())
@ -184,21 +189,22 @@ public class DiskWriter {
int failSafe = 0;
while (!saved && failSafe++ <= 42069)
{
try (FileWriter fr = new FileWriter(filename, true);
BufferedWriter bw = new BufferedWriter(fr);
PrintWriter writer = new PrintWriter(bw)) {
try (FileWriter fr = new FileWriter(filename, true); BufferedWriter bw = new BufferedWriter(fr); PrintWriter writer = new PrintWriter(bw))
{
writer.println(lineToWrite);
if (debug)
System.out.println("Saved " + filename + ">" + lineToWrite
+ " to disk");
System.out.println("Saved " + filename + ">" + lineToWrite + " to disk");
saved = true;
} catch (Exception e) {
}
catch (Exception e)
{
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename + "_");
if (original.contains(".")) {
System.out.println("Failed saving, trying to save as " + filename + "_");
if (original.contains("."))
{
filename = insertFileName(original, "" + counter);
} else
}
else
filename = original + counter;
counter++;
}

View File

@ -20,14 +20,6 @@ package the.bytecode.club.bytecodeviewer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import javax.swing.*;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.io.FileUtils;
import org.objectweb.asm.tree.ClassNode;
@ -50,56 +42,55 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginWriter;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.importing.ImportResource;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.BootCheck;
import the.bytecode.club.bytecodeviewer.util.ClassFileUtils;
import the.bytecode.club.bytecodeviewer.util.LazyNameUtil;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.PingBack;
import the.bytecode.club.bytecodeviewer.util.SecurityMan;
import the.bytecode.club.bytecodeviewer.util.*;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.*;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import static the.bytecode.club.bytecodeviewer.Constants.DEV_MODE;
import static the.bytecode.club.bytecodeviewer.Constants.FAT_JAR;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* A lightweight Java Reverse Engineering suite, developed by Konloch - http://konloch.me
*
* <p>
* All you have to do is add a jar or class file into the workspace,
* select the file you want then it will start decompiling the class in the background.
* When it's done it will show the Source code, Bytecode and Hexcode of the class file you chose.
*
* <p>
* There is also a plugin system that will allow you to interact with the loaded classfiles.
* For example you can write a String deobfuscator, a malicious code searcher,
* or anything else you can think of.
*
* <p>
* You can either use one of the pre-written plugins, or write your own. It supports java scripting.
* Once a plugin is activated, it will send a ClassNode ArrayList of every single class loaded in the
* file system to the execute function, this allows the user to handle it completely using ASM.
*
* <p>
* Are you a Java Reverse Engineer? Or maybe you want to learn Java Reverse Engineering?
* Join The Bytecode Club, we're noob friendly, and censorship free.
* http://the.bytecode.club
*
* <p>
* TODO BUGS:
* + View>Visual Settings>Show Class Methods
* + 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
*
* <p>
* TODO API BUGS:
* + All of the plugins that modify code need to include BytecodeViewer.updateAllClassNodeByteArrays();
* + All of the plugins that do any code changes should also include BytecodeViewer.refreshAllTabs();
* + Anything using getLoadedClasses() needs to be replaced with the new API
* + Anything using blindlySearchForClassNode() should instead search through the resource container search function
* + BCV's classLoader should be destroyed each time a resource is added or removed
*
* <p>
* TODO IN-PROGRESS:
* + Resource Exporter/Save/Decompile As Zip needs to be rewritten
* + Finish dragging code
* + Finish right-click tab menu detection
* + Fix hook inject for EZ-Injection
*
* <p>
* TODO FEATURES:
* + On refresh save scroll position
* + Option to only compile currently viewed class (true by default)
@ -111,7 +102,7 @@ import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
* + Add decompile all as zip for CLI
* + Console on the Main Viewer UI
* + Font settings
*
* <p>
* TODO IDEAS:
* + App Bundle Support
* + Add JEB decompiler optionally, requires them to add jeb library jar
@ -138,7 +129,7 @@ public class BytecodeViewer
public static MainViewerGUI viewer;
//All of the opened resources (Files/Classes/Etc)
public static Map<String,ResourceContainer> resourceContainers = new LinkedHashMap<>();
public static Map<String, ResourceContainer> resourceContainers = new LinkedHashMap<>();
//All of the created processes (Decompilers/etc)
public static List<Process> createdProcesses = new ArrayList<>();
@ -176,9 +167,12 @@ public class BytecodeViewer
System.out.println(" - https://bytecodeviewer.com\r\nCreated by @Konloch - https://konloch.com\r\nPresented by https://the.bytecode.club");
// Set the security manager
try {
try
{
System.setSecurityManager(sm);
} catch (Throwable t) {
}
catch (Throwable t)
{
System.err.println("Cannot set security manager! Are you on Java 18+ and have not enabled support for it?");
System.err.println("Because of this, you may be susceptible to some exploits!");
System.err.println("Either deal with it or allow it using the -Djava.security.manager=allow parameter.");
@ -303,9 +297,12 @@ public class BytecodeViewer
resourceContainers.put(container.name, container);
SwingUtilities.invokeLater(() ->
{
try {
try
{
viewer.resourcePane.addResourceContainer(container);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
});
@ -424,7 +421,7 @@ public class BytecodeViewer
/**
* Gets all of the loaded classes as an array list
*
* <p>
* TODO: remove this and replace it with:
* BytecodeViewer.getResourceContainers().forEach(container -> {
* execute(new ArrayList<>(container.resourceClasses.values()));
@ -588,8 +585,7 @@ public class BytecodeViewer
*/
public static String showInput(String message, String title, String initialMessage)
{
return (String) ExtendedJOptionPane.showInputDialog(viewer, message, title,
QUESTION_MESSAGE, null, null, initialMessage);
return (String) ExtendedJOptionPane.showInputDialog(viewer, message, title, QUESTION_MESSAGE, null, null, initialMessage);
}
/**
@ -665,7 +661,7 @@ public class BytecodeViewer
*/
public static void refreshAllTabTitles()
{
for(int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
for (int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
{
//ResourceViewer viewer = ((TabbedPane) BytecodeViewer.viewer.workPane.tabs.getTabComponentAt(i)).resource;
//viewer.refreshTitle();
@ -678,7 +674,7 @@ public class BytecodeViewer
*/
public static void refreshAllTabs()
{
new Thread(()->
new Thread(() ->
{
updateBusyStatus(true);
for (int i = 0; i < BytecodeViewer.viewer.workPane.tabs.getTabCount(); i++)
@ -699,9 +695,7 @@ public class BytecodeViewer
{
if (ask)
{
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.RESET_TITLE.toString(),
TranslatedStrings.RESET_CONFIRM.toString(),
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.RESET_TITLE.toString(), TranslatedStrings.RESET_CONFIRM.toString(), new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
if (dialog.promptChoice() != 0)
return;
@ -740,9 +734,13 @@ public class BytecodeViewer
{
File tempF = new File(tempDirectory);
try {
try
{
FileUtils.deleteDirectory(tempF);
} catch (Exception ignored) { }
}
catch (Exception ignored)
{
}
while (!tempF.exists()) // keep making dirs
tempF.mkdir();
@ -751,31 +749,36 @@ public class BytecodeViewer
/**
* because Smali and Baksmali System.exit if it failed
*/
public static void exit(int i) { }
public static void exit(int i)
{
}
/**
* Updates all UI components fonts.
*
* @param font The font to change everything to.
* @implNote {@link SearchableRSyntaxTextArea} and {@link SearchableJTextArea}
* do not update until "Refresh" button is clicked.
*
* @param font The font to change everything to.
*/
public static void updateAllFonts(Font font) {
public static void updateAllFonts(Font font)
{
Enumeration<Object> enumeration = UIManager.getDefaults().keys();
while (enumeration.hasMoreElements()) {
while (enumeration.hasMoreElements())
{
Object key = enumeration.nextElement();
Object value = UIManager.get (key);
Object value = UIManager.get(key);
if (value instanceof Font)
UIManager.put (key, font);
UIManager.put(key, font);
}
}
/**
* Updates all swing components.
*/
public static void updateUI() {
for (Window w : Window.getWindows()) {
public static void updateUI()
{
for (Window w : Window.getWindows())
{
SwingUtilities.updateComponentTreeUI(w);
}
}

View File

@ -18,7 +18,6 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
@ -31,9 +30,9 @@ import the.bytecode.club.bytecodeviewer.translation.Language;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import java.io.File;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* Used to allow BCV to be integrated as CLI instead of GUI.
@ -41,7 +40,8 @@ import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
* @author Konloch
*/
public class CommandLineInput {
public class CommandLineInput
{
private static final Options options = new Options();
private static final CommandLineParser parser = new DefaultParser();
@ -51,7 +51,8 @@ public class CommandLineInput {
public static int GUI = 0;
public static int CLI = 1;
static {
static
{
options.addOption("help", false, "prints the help menu.");
options.addOption("list", false, "lists all the available decompilers for BCV " + VERSION + ".");
options.addOption("decompiler", true, "sets the decompiler, procyon by default.");
@ -61,38 +62,36 @@ public class CommandLineInput {
options.addOption("nowait", true, "won't wait the 5 seconds to allow the user to read the CLI.");
}
public static boolean containsCommand(String[] args) {
public static boolean containsCommand(String[] args)
{
if (args == null || args.length == 0)
return false;
try {
try
{
CommandLine cmd = parser.parse(options, args);
if (
cmd.hasOption("help") ||
cmd.hasOption("clean") ||
cmd.hasOption("english") ||
cmd.hasOption("list") ||
cmd.hasOption("decompiler") ||
cmd.hasOption("i") ||
cmd.hasOption("o") ||
cmd.hasOption("t") ||
cmd.hasOption("nowait")
) {
if (cmd.hasOption("help") || cmd.hasOption("clean") || cmd.hasOption("english") || cmd.hasOption("list") || cmd.hasOption("decompiler") || cmd.hasOption("i") || cmd.hasOption("o") || cmd.hasOption("t") || cmd.hasOption("nowait"))
{
return true;
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
public static int parseCommandLine(String[] args) {
public static int parseCommandLine(String[] args)
{
if (!containsCommand(args))
return GUI;
try {
try
{
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("list")) {
if (cmd.hasOption("list"))
{
System.out.println("Procyon");
System.out.println("CFR");
System.out.println("FernFlower");
@ -102,38 +101,38 @@ public class CommandLineInput {
System.out.println("Smali");
System.out.println("ASMifier");
return STOP;
} else if (cmd.hasOption("clean")) {
}
else if (cmd.hasOption("clean"))
{
new File(Constants.getBCVDirectory()).delete();
if(cmd.getOptionValue("i") == null && cmd.getOptionValue("o") == null
&& cmd.getOptionValue("t") == null)
if (cmd.getOptionValue("i") == null && cmd.getOptionValue("o") == null && cmd.getOptionValue("t") == null)
return GUI;
} else if (cmd.hasOption("english")) {
}
else if (cmd.hasOption("english"))
{
Configuration.language = Language.ENGLISH;
return GUI;
} else if (cmd.hasOption("help")) {
for (String s : new String[]{
"-help Displays the help menu",
"-clean Deletes the BCV directory",
"-english Forces English language translations",
"-list Displays the available decompilers",
"-decompiler <decompiler> Selects the decompiler, procyon by default",
"-i <input file> Selects the input file",
"-o <output file> Selects the output file",
"-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip",
"-nowait Doesn't wait for the user to read the CLI messages"
})
}
else if (cmd.hasOption("help"))
{
for (String s : new String[]{"-help Displays the help menu", "-clean Deletes the BCV directory", "-english Forces English language translations", "-list Displays the available decompilers", "-decompiler <decompiler> Selects the decompiler, procyon by default", "-i <input file> Selects the input file", "-o <output file> Selects the output file", "-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip", "-nowait Doesn't wait for the user to read the CLI messages"})
System.out.println(s);
return STOP;
} else {
if (cmd.getOptionValue("i") == null) {
}
else
{
if (cmd.getOptionValue("i") == null)
{
System.err.println("Set the input with -i");
return STOP;
}
if (cmd.getOptionValue("o") == null) {
if (cmd.getOptionValue("o") == null)
{
System.err.println("Set the output with -o");
return STOP;
}
if (cmd.getOptionValue("t") == null) {
if (cmd.getOptionValue("t") == null)
{
System.err.println("Set the target with -t");
return STOP;
}
@ -142,12 +141,14 @@ public class CommandLineInput {
File output = new File(cmd.getOptionValue("o"));
String decompiler = cmd.getOptionValue("decompiler");
if (!input.exists()) {
if (!input.exists())
{
System.err.println(input.getAbsolutePath() + " does not exist.");
return STOP;
}
if (output.exists()) {
if (output.exists())
{
System.err.println("WARNING: Deleted old " + output.getAbsolutePath() + ".");
output.delete();
}
@ -156,19 +157,9 @@ public class CommandLineInput {
//if its zip/jar/apk/dex attempt unzip as whole zip
//if its just class allow any
if (
decompiler != null &&
!decompiler.equalsIgnoreCase("procyon") &&
!decompiler.equalsIgnoreCase("cfr") &&
!decompiler.equalsIgnoreCase("fernflower") &&
!decompiler.equalsIgnoreCase("krakatau") &&
!decompiler.equalsIgnoreCase("krakatau-bytecode") &&
!decompiler.equalsIgnoreCase("jd-gui") &&
!decompiler.equalsIgnoreCase("smali") &&
!decompiler.equalsIgnoreCase("asmifier")
) {
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list"
+ " for the list");
if (decompiler != null && !decompiler.equalsIgnoreCase("procyon") && !decompiler.equalsIgnoreCase("cfr") && !decompiler.equalsIgnoreCase("fernflower") && !decompiler.equalsIgnoreCase("krakatau") && !decompiler.equalsIgnoreCase("krakatau-bytecode") && !decompiler.equalsIgnoreCase("jd-gui") && !decompiler.equalsIgnoreCase("smali") && !decompiler.equalsIgnoreCase("asmifier"))
{
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -list" + " for the list");
}
@ -177,24 +168,28 @@ public class CommandLineInput {
return CLI;
}
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
return GUI;
}
public static void executeCommandLine(String[] args) {
try {
public static void executeCommandLine(String[] args)
{
try
{
CommandLine cmd = parser.parse(options, args);
String decompiler = cmd.getOptionValue("decompiler");
File input = new File(cmd.getOptionValue("i"));
File output = new File(cmd.getOptionValue("o"));
String target = cmd.getOptionValue("t");
if (cmd.getOptionValue("decompiler") == null) {
System.out.println("You can define another decompiler by appending -decompiler \"name\", by default "
+ "procyon has been set.");
if (cmd.getOptionValue("decompiler") == null)
{
System.out.println("You can define another decompiler by appending -decompiler \"name\", by default " + "procyon has been set.");
decompiler = "procyon";
}
@ -202,178 +197,247 @@ public class CommandLineInput {
//if its zip/jar/apk/dex attempt unzip as whole zip
//if its just class allow any
File tempZip =
new File(tempDirectory + fs + "temp_" + MiscUtils.getRandomizedName() + ".jar");
File tempZip = new File(tempDirectory + fs + "temp_" + MiscUtils.getRandomizedName() + ".jar");
if (tempZip.exists())
tempZip.delete();
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
if (decompiler.equalsIgnoreCase("procyon")) {
if (decompiler.equalsIgnoreCase("procyon"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with Procyon");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
Decompiler.PROCYON_DECOMPILER.getDecompiler().decompileToZip(tempZip.getAbsolutePath(), output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.PROCYON_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("cfr")) {
}
else if (decompiler.equalsIgnoreCase("cfr"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with CFR");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
Decompiler.CFR_DECOMPILER.getDecompiler().decompileToZip(tempZip.getAbsolutePath(), output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.CFR_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("fernflower")) {
}
else if (decompiler.equalsIgnoreCase("fernflower"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with FernFlower");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
Decompiler.FERNFLOWER_DECOMPILER.getDecompiler().decompileToZip(tempZip.getAbsolutePath(), output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.FERNFLOWER_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("krakatau")) {
}
else if (decompiler.equalsIgnoreCase("krakatau"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with Krakatau");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
Decompiler.KRAKATAU_DECOMPILER.getDecompiler().decompileToZip(tempZip.getAbsolutePath(), output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.KRAKATAU_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("krakatau-bytecode")) {
}
else if (decompiler.equalsIgnoreCase("krakatau-bytecode"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with Krakatau-Bytecode");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
System.out.println("Coming soon.");
//Decompiler.krakatauDA.decompileToZip(output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.KRAKATAU_DISASSEMBLER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("jd-gui")) {
}
else if (decompiler.equalsIgnoreCase("jd-gui"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with JD-GUI");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
System.out.println("Coming soon.");
//Decompiler.jdgui.decompileToZip(output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.JD_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("smali")) {
}
else if (decompiler.equalsIgnoreCase("smali"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with Smali");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
System.out.println("Coming soon.");
//Decompiler.smali.decompileToZip(output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.SMALI_DISASSEMBLER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
} else if (decompiler.equalsIgnoreCase("jadx")) {
}
else if (decompiler.equalsIgnoreCase("jadx"))
{
System.out.println("Decompiling " + input.getAbsolutePath() + " with JADX");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
System.out.println("Coming soon.");
//Decompiler.smali.decompileToZip(output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.JADX_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
}
else if (decompiler.equalsIgnoreCase("asmifier")) {
else if (decompiler.equalsIgnoreCase("asmifier"))
{
System.out.println("Generating ASM code for " + input.getAbsolutePath() + " with ASMifier");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
if (target.equalsIgnoreCase("all"))
{
System.out.println("Coming soon.");
//Decompiler.smali.decompileToZip(output.getAbsolutePath());
} else {
try {
}
else
{
try
{
ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.ASMIFIER_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
@ -383,21 +447,30 @@ public class CommandLineInput {
System.out.println("Bytecode Viewer " + VERSION + " [CLI] - Created by @Konloch - https://bytecodeviewer.com");
Configuration.canExit = true;
System.exit(0);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
public static ClassWriter accept(ClassNode cn) {
public static ClassWriter accept(ClassNode cn)
{
ClassWriter cw = new ClassWriter(0);
try {
try
{
cn.accept(cw);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
try {
try
{
Thread.sleep(200);
cn.accept(cw);
} catch (InterruptedException ignored) {
}
catch (InterruptedException ignored)
{
}
}
return cw;

View File

@ -18,15 +18,15 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import the.bytecode.club.bytecodeviewer.bootloader.BootState;
import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
import the.bytecode.club.bytecodeviewer.gui.theme.RSTATheme;
import the.bytecode.club.bytecodeviewer.translation.Language;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
/**
* A collection of variables that can be configured through the settings menu or some form of UI/plugin
*
@ -42,8 +42,7 @@ public class Configuration
public static boolean python3Extra = false;
public static String rt = "";
public static String library = "";
public static String java = Constants.JAVA_BINARY.exists() ? Constants.JAVA_BINARY.getAbsolutePath() :
Constants.JAVA_BINARY_NIX.exists() ? Constants.JAVA_BINARY_NIX.getAbsolutePath() : "";
public static String java = Constants.JAVA_BINARY.exists() ? Constants.JAVA_BINARY.getAbsolutePath() : Constants.JAVA_BINARY_NIX.exists() ? Constants.JAVA_BINARY_NIX.getAbsolutePath() : "";
public static String javac = "";
public static String javaTools = "";
public static File krakatauTempDir;
@ -108,7 +107,7 @@ public class Configuration
public static File getLastOpenDirectory()
{
File lastDir = new File(lastOpenDirectory);
if(lastDir.getParentFile() != null && lastDir.getParentFile().exists())
if (lastDir.getParentFile() != null && lastDir.getParentFile().exists())
return lastDir;
return new File(".");
@ -117,7 +116,7 @@ public class Configuration
public static File getLastSaveDirectory()
{
File lastDir = new File(lastSaveDirectory);
if(lastDir.getParentFile() != null && lastDir.getParentFile().exists())
if (lastDir.getParentFile() != null && lastDir.getParentFile().exists())
return lastDir;
try
@ -134,7 +133,7 @@ public class Configuration
{
File lastDir = new File(lastPluginDirectory);
if(lastDir.getParentFile() != null && lastDir.getParentFile().exists())
if (lastDir.getParentFile() != null && lastDir.getParentFile().exists())
return lastDir;
return new File(".");
@ -144,7 +143,7 @@ public class Configuration
{
Language language = Language.getLanguageCodeLookup().get(Locale.getDefault().getLanguage());
if(language != null)
if (language != null)
return language;
//fallback to english

View File

@ -18,12 +18,12 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import java.io.PrintStream;
import org.objectweb.asm.Opcodes;
import the.bytecode.club.bytecodeviewer.resources.ResourceType;
import java.io.File;
import java.io.PrintStream;
/**
* General program constants, to use this class include everything as a wildcard static import:
* import static the.bytecode.club.bytecodeviewer.Constants.*;
@ -93,18 +93,18 @@ public class Constants
File defaultLocation = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer");
//if BCV was previously installed using the default directory, continue to use that
if(defaultLocation.exists())
if (defaultLocation.exists())
return defaultLocation;
//handle XDG Base Directory - https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
if(isNix())
if (isNix())
{
File homeLocal = new File(System.getProperty("user.home") + fs + ".local");
if(homeLocal.exists())
if (homeLocal.exists())
return new File(homeLocal, "share" + fs + ".Bytecode-Viewer");
File homeConfig = new File(System.getProperty("user.home") + fs + ".config");
if(homeConfig.exists())
if (homeConfig.exists())
return new File(homeConfig, ".Bytecode-Viewer");
}
@ -125,13 +125,15 @@ public class Constants
//hides the BCV directory
if (isWindows() && !BCVDir.isHidden())
{
new Thread(()->{
try {
new Thread(() ->
{
try
{
// Hide file by running attrib system command (on Windows)
Process p = new ProcessBuilder("attrib",
"+H",
BCVDir.getAbsolutePath()).start();
} catch (Exception e) {
Process p = new ProcessBuilder("attrib", "+H", BCVDir.getAbsolutePath()).start();
}
catch (Exception e)
{
//ignore
}
}, "Hide BCV Dir").start();
@ -166,10 +168,10 @@ public class Constants
*/
public static String getVersion(String mavenVersion)
{
if(FORCE_VERSION_CHECKER_PROMPT)
if (FORCE_VERSION_CHECKER_PROMPT)
return "1.0.0";
if(mavenVersion == null)
if (mavenVersion == null)
{
DEV_MODE = true;
return "Developer Mode";

View File

@ -18,15 +18,16 @@
package the.bytecode.club.bytecodeviewer;
import java.awt.event.KeyEvent;
import java.io.File;
import javax.swing.JFileChooser;
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
import the.bytecode.club.bytecodeviewer.gui.components.RunOptions;
import the.bytecode.club.bytecodeviewer.util.DialogUtils;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.io.File;
/**
* Whenever a key is pressed on the swing UI it should get logged here
*
@ -49,11 +50,9 @@ public class GlobalHotKeys
{
Configuration.lastHotKeyExecuted = System.currentTimeMillis();
final File file = DialogUtils.fileChooser("Select File or Folder to open in BCV",
"APKs, DEX, Class Files or Zip/Jar/War Archives",
Constants.SUPPORTED_FILE_EXTENSIONS);
final File file = DialogUtils.fileChooser("Select File or Folder to open in BCV", "APKs, DEX, Class Files or Zip/Jar/War Archives", Constants.SUPPORTED_FILE_EXTENSIONS);
if(file == null)
if (file == null)
return;
BytecodeViewer.updateBusyStatus(true);
@ -104,10 +103,7 @@ public class GlobalHotKeys
if (!BytecodeViewer.autoCompileSuccessful())
return;
JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(),
"Select Zip Export",
"Zip Archives",
"zip");
JFileChooser fc = new FileChooser(Configuration.getLastSaveDirectory(), "Select Zip Export", "Zip Archives", "zip");
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
if (returnVal == JFileChooser.APPROVE_OPTION)
@ -120,9 +116,9 @@ public class GlobalHotKeys
return;
BytecodeViewer.updateBusyStatus(true);
Thread jarExport = new Thread(() -> {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
file.getAbsolutePath());
Thread jarExport = new Thread(() ->
{
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), file.getAbsolutePath());
BytecodeViewer.updateBusyStatus(false);
}, "Jar Export");
jarExport.start();
@ -149,10 +145,10 @@ public class GlobalHotKeys
String recentFile = Settings.getRecentFile();
if(!BytecodeViewer.hasResources() && recentFile != null)
if (!BytecodeViewer.hasResources() && recentFile != null)
{
File file = new File(recentFile);
if(file.exists())
if (file.exists())
{
BytecodeViewer.openFiles(new File[]{file}, false);
}

View File

@ -19,20 +19,18 @@
package the.bytecode.club.bytecodeviewer;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JMenuItem;
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.util.ArrayList;
import java.util.List;
import static the.bytecode.club.bytecodeviewer.BytecodeViewer.gson;
import static the.bytecode.club.bytecodeviewer.Configuration.maxRecentFiles;
import static the.bytecode.club.bytecodeviewer.Constants.filesName;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.getBCVDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.pluginsName;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* @author Konloch
@ -84,7 +82,7 @@ public class Settings
public static synchronized void removeRecentFile(File f)
{
if(recentFiles.remove(f.getAbsolutePath()))
if (recentFiles.remove(f.getAbsolutePath()))
{
DiskWriter.replaceFile(filesName, MiscUtils.listToString(recentFiles), false);
resetRecentFilesMenu();
@ -93,7 +91,7 @@ public class Settings
public static String getRecentFile()
{
if(recentFiles.isEmpty())
if (recentFiles.isEmpty())
return null;
return recentFiles.get(0);
@ -115,7 +113,7 @@ public class Settings
public static synchronized void removeRecentPlugin(File f)
{
if(recentPlugins.remove(f.getAbsolutePath()))
if (recentPlugins.remove(f.getAbsolutePath()))
{
DiskWriter.replaceFile(pluginsName, MiscUtils.listToString(recentPlugins), false);
resetRecentFilesMenu();

View File

@ -18,8 +18,6 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import javax.swing.JFrame;
import me.konloch.kontainer.io.DiskReader;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
@ -27,6 +25,9 @@ import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
import the.bytecode.club.bytecodeviewer.gui.theme.RSTATheme;
import the.bytecode.club.bytecodeviewer.translation.Language;
import javax.swing.*;
import java.io.File;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
import static the.bytecode.club.bytecodeviewer.Constants.settingsName;
@ -201,7 +202,9 @@ public class SettingsSerializer
save(Configuration.python3Extra);
save(BytecodeViewer.viewer.getMinSdkVersion());
save(BytecodeViewer.viewer.printLineNumbers.isSelected());
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}
@ -215,7 +218,7 @@ public class SettingsSerializer
{
settingsFileExists = new File(settingsName).exists();
if(!settingsFileExists)
if (!settingsFileExists)
return;
//precache the file
@ -240,7 +243,7 @@ public class SettingsSerializer
//utilizes the Disk Reader's caching system.
public static void loadSettings()
{
if(!settingsFileExists)
if (!settingsFileExists)
return;
Settings.firstBoot = false;
@ -335,7 +338,8 @@ public class SettingsSerializer
BytecodeViewer.viewer.refreshOnChange.setSelected(asBoolean(84));
boolean bool = Boolean.parseBoolean(asString(85));
if (bool) {
if (bool)
{
BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH);
BytecodeViewer.viewer.isMaximized = true;
}
@ -353,7 +357,7 @@ public class SettingsSerializer
Configuration.deleteForeignLibraries = asBoolean(113);
//APK Decompiler
switch(asInt(114))
switch (asInt(114))
{
case 0:
BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionDex.getModel(), true);
@ -382,7 +386,7 @@ public class SettingsSerializer
Configuration.simplifiedTabNames = BytecodeViewer.viewer.simplifyNameInTabTitle.isSelected();
//line 130 is used for preload
if(Configuration.language != Language.ENGLISH)
if (Configuration.language != Language.ENGLISH)
Configuration.language.setLanguageTranslations(); //load language translations
Settings.hasSetLanguageAsSystemLanguage = true;

View File

@ -18,15 +18,7 @@
package the.bytecode.club.bytecodeviewer.api;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.*;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
/**
@ -58,9 +50,7 @@ public final class ASMResourceUtil
return defaultFQN;
}
public static void renameFieldNode(String originalParentName,
String originalFieldName, String originalFieldDesc,
String newFieldParent, String newFieldName, String newFieldDesc)
public static void renameFieldNode(String originalParentName, String originalFieldName, String originalFieldDesc, String newFieldParent, String newFieldName, String newFieldDesc)
{
for (ClassNode c : BytecodeViewer.getLoadedClasses())
{
@ -73,9 +63,7 @@ public final class ASMResourceUtil
{
FieldInsnNode field = (FieldInsnNode) i;
if (field.owner.equals(originalParentName)
&& field.name.equals(originalFieldName)
&& field.desc.equals(originalFieldDesc))
if (field.owner.equals(originalParentName) && field.name.equals(originalFieldName) && field.desc.equals(originalFieldDesc))
{
if (newFieldParent != null)
field.owner = newFieldParent;
@ -90,9 +78,7 @@ public final class ASMResourceUtil
}
}
public static void renameMethodNode(String originalParentName,
String originalMethodName, String originalMethodDesc,
String newParent, String newName, String newDesc)
public static void renameMethodNode(String originalParentName, String originalMethodName, String originalMethodDesc, String newParent, String newName, String newDesc)
{
for (ClassNode c : BytecodeViewer.getLoadedClasses())
{
@ -104,9 +90,7 @@ public final class ASMResourceUtil
if (i instanceof MethodInsnNode)
{
MethodInsnNode mi = (MethodInsnNode) i;
if (mi.owner.equals(originalParentName)
&& mi.name.equals(originalMethodName)
&& mi.desc.equals(originalMethodDesc))
if (mi.owner.equals(originalParentName) && mi.name.equals(originalMethodName) && mi.desc.equals(originalMethodDesc))
{
if (newParent != null)
mi.owner = newParent;
@ -123,16 +107,12 @@ public final class ASMResourceUtil
if (m.signature != null)
{
if (newName != null)
m.signature = m.signature.replace(originalMethodName,
newName);
m.signature = m.signature.replace(originalMethodName, newName);
if (newParent != null)
m.signature = m.signature.replace(originalParentName,
newParent);
m.signature = m.signature.replace(originalParentName, newParent);
}
if (m.name.equals(originalMethodName)
&& m.desc.equals(originalMethodDesc)
&& c.name.equals(originalParentName))
if (m.name.equals(originalMethodName) && m.desc.equals(originalMethodDesc) && c.name.equals(originalParentName))
{
if (newName != null)
m.name = newName;

View File

@ -36,9 +36,12 @@ public class ASMUtil
{
ClassReader cr = new ClassReader(b);
ClassNode cn = new ClassNode();
try {
try
{
cr.accept(cn, ClassReader.EXPAND_FRAMES);
} catch (Exception e) {
}
catch (Exception e)
{
cr.accept(cn, ClassReader.SKIP_FRAMES);
}
return cn;
@ -51,14 +54,21 @@ public class ASMUtil
{
final ClassWriter cw = new ClassWriter(0);
try {
try
{
cn.accept(cw);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
try {
try
{
Thread.sleep(200);
cn.accept(cw);
} catch (InterruptedException ignored) { }
}
catch (InterruptedException ignored)
{
}
}
return cw.toByteArray();
@ -66,9 +76,9 @@ public class ASMUtil
public static MethodNode getMethodByName(ClassNode cn, String name)
{
for(MethodNode m : cn.methods)
for (MethodNode m : cn.methods)
{
if(m.name.equals(name))
if (m.name.equals(name))
return m;
}

View File

@ -18,17 +18,6 @@
package the.bytecode.club.bytecodeviewer.api;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.JFrame;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -42,9 +31,18 @@ import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.SleepUtil;
import static the.bytecode.club.bytecodeviewer.Constants.DEV_MODE;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import javax.swing.*;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* An easier to use version of the BCV API, this is designed for anyone who wants to extend BCV, in any shape
@ -62,7 +60,8 @@ public class BCV
*
* @return the static ClassNodeLoader instance
*/
public static ClassNodeLoader getClassNodeLoader() {
public static ClassNodeLoader getClassNodeLoader()
{
return loader;
}
@ -71,7 +70,8 @@ public class BCV
*
* @return the URLClassLoader instance
*/
public static URLClassLoader getClassLoaderInstance() {
public static URLClassLoader getClassLoaderInstance()
{
return cl;
}
@ -83,7 +83,7 @@ public class BCV
*/
public static Class<?> loadClassIntoClassLoader(ClassNode cn)
{
if(cn == null)
if (cn == null)
return null;
getClassNodeLoader().addClass(cn);
@ -91,11 +91,13 @@ public class BCV
try
{
//TODO this should be rebuilding the class loader each time a new resource has been added or removed
if(cl == null)
if (cl == null)
loadClassesIntoClassLoader();
return cl.loadClass(cn.name);
} catch (Exception classLoadException) {
}
catch (Exception classLoadException)
{
BytecodeViewer.handleException(classLoadException);
}
@ -115,14 +117,16 @@ public class BCV
List<Class<?>> ret = new ArrayList<>();
JarUtils.saveAsJar(BCV.getLoadedClasses(), f.getAbsolutePath());
try (JarFile jarFile = new JarFile("" + f.getAbsolutePath())) {
try (JarFile jarFile = new JarFile("" + f.getAbsolutePath()))
{
Enumeration<JarEntry> e = jarFile.entries();
URL[] urls = {new URL("jar:file:" + "" + f.getAbsolutePath() + "!/")};
cl = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
while (e.hasMoreElements())
{
JarEntry je = e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class"))
@ -131,16 +135,21 @@ public class BCV
String className = je.getName().replace("/", ".").replace(".class", "");
className = className.replace('/', '.');
try {
try
{
ret.add(cl.loadClass(className));
} catch (Exception classLoadException) {
}
catch (Exception classLoadException)
{
BytecodeViewer.handleException(classLoadException);
}
}
}
return ret;
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
return null;
@ -149,7 +158,8 @@ public class BCV
/**
* Creates a new instance of the ClassNode loader.
*/
public static void createNewClassNodeLoaderInstance() {
public static void createNewClassNodeLoaderInstance()
{
loader.clear();
loader = new ClassNodeLoader();
}
@ -159,7 +169,8 @@ public class BCV
*
* @param plugin the file of the plugin
*/
public static void startPlugin(File plugin) {
public static void startPlugin(File plugin)
{
BytecodeViewer.startPlugin(plugin);
}
@ -169,7 +180,8 @@ public class BCV
* @param files an array of the files you want loaded.
* @param recentFiles if it should save to the recent files menu.
*/
public static void openFiles(File[] files, boolean recentFiles) {
public static void openFiles(File[] files, boolean recentFiles)
{
BytecodeViewer.openFiles(files, recentFiles);
}
@ -178,7 +190,8 @@ public class BCV
*
* @return The opened class node or a null if nothing is opened
*/
public static ClassNode getCurrentlyOpenedClassNode() {
public static ClassNode getCurrentlyOpenedClassNode()
{
return BytecodeViewer.getCurrentlyOpenedClassNode();
}
@ -192,14 +205,20 @@ public class BCV
final ClassNode cn = BytecodeViewer.getCurrentlyOpenedClassNode();
final ClassWriter cw = new ClassWriter(0);
try {
try
{
Objects.requireNonNull(cn).accept(cw);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
try {
try
{
Thread.sleep(200);
Objects.requireNonNull(cn).accept(cw);
} catch (InterruptedException ignored) {
}
catch (InterruptedException ignored)
{
}
}
@ -223,7 +242,8 @@ public class BCV
* @param name the full name of the ClassNode
* @return the ClassNode
*/
public static ClassNode getClassNode(String name) {
public static ClassNode getClassNode(String name)
{
return BytecodeViewer.blindlySearchForClassNode(name);
}
@ -232,7 +252,8 @@ public class BCV
*
* @return the loaded classes
*/
public static List<ClassNode> getLoadedClasses() {
public static List<ClassNode> getLoadedClasses()
{
return BytecodeViewer.getLoadedClasses();
}
@ -241,7 +262,8 @@ public class BCV
*
* @param hook
*/
public static void insertHook(BytecodeHook hook) {
public static void insertHook(BytecodeHook hook)
{
EZInjection.hookArray.add(hook);
}
@ -251,7 +273,8 @@ public class BCV
*
* @param ask if it should ask the user about resetting the workspace
*/
public static void resetWorkSpace(boolean ask) {
public static void resetWorkSpace(boolean ask)
{
BytecodeViewer.resetWorkspace(ask);
}
@ -261,7 +284,8 @@ public class BCV
*
* @param busy if it should display the busy icon or not
*/
public static void setBusy(boolean busy) {
public static void setBusy(boolean busy)
{
BytecodeViewer.updateBusyStatus(busy);
}
@ -270,14 +294,16 @@ public class BCV
*
* @param message the message you want to display
*/
public static void showMessage(String message) {
public static void showMessage(String message)
{
BytecodeViewer.showMessage(message);
}
/**
* Asks if the user would like to overwrite the file
*/
public static boolean canOverwriteFile(File file) {
public static boolean canOverwriteFile(File file)
{
return DialogUtils.canOverwriteFile(file);
}
@ -289,7 +315,7 @@ public class BCV
*/
public static void hideFrame(JFrame frame, long milliseconds)
{
new Thread(()->
new Thread(() ->
{
SleepUtil.sleep(milliseconds);
@ -310,7 +336,7 @@ public class BCV
*/
public static void log(boolean devModeOnly, String s)
{
if(!devModeOnly || DEV_MODE)
if (!devModeOnly || DEV_MODE)
System.out.println(s);
}
@ -327,7 +353,7 @@ public class BCV
*/
public static void logE(boolean devModeOnly, String s)
{
if(!devModeOnly || DEV_MODE)
if (!devModeOnly || DEV_MODE)
System.err.println(s);
}
@ -336,7 +362,8 @@ public class BCV
*
* @return The wrapped Krakatau Decompiler instance
*/
public static InternalDecompiler getKrakatauDecompiler() {
public static InternalDecompiler getKrakatauDecompiler()
{
return Decompiler.KRAKATAU_DECOMPILER.getDecompiler();
}
@ -345,7 +372,8 @@ public class BCV
*
* @return The wrapped Procyon Decompiler instance
*/
public static InternalDecompiler getProcyonDecompiler() {
public static InternalDecompiler getProcyonDecompiler()
{
return Decompiler.PROCYON_DECOMPILER.getDecompiler();
}
@ -354,7 +382,8 @@ public class BCV
*
* @return The wrapped CFR Decompiler instance
*/
public static InternalDecompiler getCFRDecompiler() {
public static InternalDecompiler getCFRDecompiler()
{
return Decompiler.CFR_DECOMPILER.getDecompiler();
}
@ -363,7 +392,8 @@ public class BCV
*
* @return The wrapped FernFlower Decompiler instance
*/
public static InternalDecompiler getFernFlowerDecompiler() {
public static InternalDecompiler getFernFlowerDecompiler()
{
return Decompiler.FERNFLOWER_DECOMPILER.getDecompiler();
}
@ -372,7 +402,8 @@ public class BCV
*
* @return The wrapped Krakatau Disassembler instance
*/
public static InternalDecompiler getKrakatauDisassembler() {
public static InternalDecompiler getKrakatauDisassembler()
{
return Decompiler.KRAKATAU_DISASSEMBLER.getDecompiler();
}
@ -381,7 +412,8 @@ public class BCV
*
* @return The wrapped JD-GUI Decompiler instance
*/
public static InternalDecompiler getDJGUIDecompiler() {
public static InternalDecompiler getDJGUIDecompiler()
{
return Decompiler.JD_DECOMPILER.getDecompiler();
}
@ -390,7 +422,8 @@ public class BCV
*
* @return The wrapped JADX Decompiler instance
*/
public static InternalDecompiler getJADXDecompiler() {
public static InternalDecompiler getJADXDecompiler()
{
return Decompiler.JADX_DECOMPILER.getDecompiler();
}
@ -399,7 +432,8 @@ public class BCV
*
* @return The wrapped Java Compiler instance
*/
public static InternalCompiler getJavaCompiler() {
public static InternalCompiler getJavaCompiler()
{
return Compiler.JAVA_COMPILER.getCompiler();
}
@ -408,7 +442,8 @@ public class BCV
*
* @return The wrapped Krakatau Assembler instance
*/
public static InternalCompiler getKrakatauCompiler() {
public static InternalCompiler getKrakatauCompiler()
{
return Compiler.KRAKATAU_ASSEMBLER.getCompiler();
}
@ -417,7 +452,8 @@ public class BCV
*
* @return The wrapped Smali Assembler instance
*/
public static InternalCompiler getSmaliCompiler() {
public static InternalCompiler getSmaliCompiler()
{
return Compiler.SMALI_ASSEMBLER.getCompiler();
}
}

View File

@ -18,18 +18,15 @@
package the.bytecode.club.bytecodeviewer.api;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import java.util.*;
/**
* @author Demmonic
@ -44,7 +41,8 @@ public final class ClassNodeLoader extends ClassLoader
*
* @param cn The class
*/
public void addClass(ClassNode cn) {
public void addClass(ClassNode cn)
{
classes.put(cn.name.replace("/", "."), cn);
}
@ -52,33 +50,41 @@ public final class ClassNodeLoader extends ClassLoader
* @param name The name of the class
* @return If this class loader contains the provided class node
*/
public boolean contains(String name) {
public boolean contains(String name)
{
return (classes.get(name) != null);
}
/**
* @return All class nodes in this loader
*/
public Collection<ClassNode> getAll() {
public Collection<ClassNode> getAll()
{
return classes.values();
}
/**
* Clears out all class nodes
*/
public void clear() {
public void clear()
{
classes.clear();
}
/**
* @return All classes in this loader
*/
public Collection<Class<?>> getAllClasses() {
public Collection<Class<?>> getAllClasses()
{
List<Class<?>> classes = new ArrayList<>();
for (String s : this.classes.keySet()) {
try {
for (String s : this.classes.keySet())
{
try
{
classes.add(loadClass(s));
} catch (ClassNotFoundException e) {
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
@ -90,20 +96,26 @@ public final class ClassNodeLoader extends ClassLoader
* @param name The name of the class
* @return The class node with the provided name
*/
public ClassNode get(String name) {
public ClassNode get(String name)
{
return classes.get(name);
}
@Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
public Class<?> loadClass(String className) throws ClassNotFoundException
{
return findClass(className);
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
if (classes.containsKey(name)) {
public Class<?> findClass(String name) throws ClassNotFoundException
{
if (classes.containsKey(name))
{
return nodeToClass(classes.get(name));
} else {
}
else
{
return super.loadClass(name);
}
}
@ -120,21 +132,24 @@ public final class ClassNodeLoader extends ClassLoader
return findLoadedClass(node.name.replace("/", "."));
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
try {
try
{
node.accept(cw);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
byte[] b = cw.toByteArray();
return defineClass(node.name.replaceAll("/", "."), b, 0, b.length,
getDomain());
return defineClass(node.name.replaceAll("/", "."), b, 0, b.length, getDomain());
}
/**
* @return This class loader's protection domain
*/
private ProtectionDomain getDomain() {
private ProtectionDomain getDomain()
{
CodeSource code = new CodeSource(null, (Certificate[]) null);
return new ProtectionDomain(code, getPermissions());
}
@ -142,7 +157,8 @@ public final class ClassNodeLoader extends ClassLoader
/**
* @return This class loader's permissions
*/
private Permissions getPermissions() {
private Permissions getPermissions()
{
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
return permissions;

View File

@ -18,11 +18,6 @@
package the.bytecode.club.bytecodeviewer.api;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsole;
@ -30,9 +25,12 @@ import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import static the.bytecode.club.bytecodeviewer.Constants.FAT_JAR;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import java.awt.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* A simple class designed to show exceptions in the UI.
@ -49,14 +47,16 @@ public class ExceptionUI extends JFrameConsole
/**
* @param e The exception to be shown
*/
public ExceptionUI(Throwable e) {
public ExceptionUI(Throwable e)
{
setupException(e, KONLOCH);
}
/**
* @param e The exception to be shown
*/
public ExceptionUI(String e) {
public ExceptionUI(String e)
{
setupFrame(e, KONLOCH);
}
@ -64,7 +64,8 @@ public class ExceptionUI extends JFrameConsole
* @param e The exception to be shown
* @param author the author of the plugin throwing this exception.
*/
public ExceptionUI(Throwable e, String author) {
public ExceptionUI(Throwable e, String author)
{
setupException(e, author);
}
@ -72,7 +73,8 @@ public class ExceptionUI extends JFrameConsole
* @param e The exception to be shown
* @param author the author of the plugin throwing this exception.
*/
public ExceptionUI(String e, String author) {
public ExceptionUI(String e, String author)
{
setupFrame(e, author);
}
@ -82,23 +84,25 @@ public class ExceptionUI extends JFrameConsole
private void setupException(Throwable error, String author)
{
//exceptions are completely hidden
if(Configuration.silenceExceptionGUI > 0)
if (Configuration.silenceExceptionGUI > 0)
return;
//exception GUI is disabled but printstack is still enabled
if(Configuration.pauseExceptionGUI > 0)
if (Configuration.pauseExceptionGUI > 0)
{
error.printStackTrace();
return;
}
try (StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw)) {
try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw))
{
error.printStackTrace(pw);
error.printStackTrace();
setupFrame(sw.toString(), author);
} catch (IOException ignored) {
}
catch (IOException ignored)
{
}
}
@ -116,7 +120,7 @@ public class ExceptionUI extends JFrameConsole
getTextArea().setCaretPosition(0);
//embed error log as a new tab
if(Configuration.errorLogsAsNewTab)
if (Configuration.errorLogsAsNewTab)
PluginManager.addExceptionUI(this);
//pop open a new window frame
@ -134,11 +138,7 @@ public class ExceptionUI extends JFrameConsole
{
String fatJar = FAT_JAR ? " [Fat Jar]" : "";
return TranslatedStrings.PLEASE_SEND_THIS_ERROR_LOG_TO + " " + author +
"\n" + TranslatedStrings.PLEASE_SEND_RESOURCES +
"\nBytecode Viewer Version: " + VERSION + fatJar +
", OS: " + System.getProperty("os.name") +
", Java: " + System.getProperty("java.version");
return TranslatedStrings.PLEASE_SEND_THIS_ERROR_LOG_TO + " " + author + "\n" + TranslatedStrings.PLEASE_SEND_RESOURCES + "\nBytecode Viewer Version: " + VERSION + fatJar + ", OS: " + System.getProperty("os.name") + ", Java: " + System.getProperty("java.version");
}
private static final long serialVersionUID = -5230501978224926296L;

View File

@ -18,12 +18,13 @@
package the.bytecode.club.bytecodeviewer.api;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import java.util.ArrayList;
import java.util.List;
/**
* A simple plugin class, it will run the plugin in a background thread.
*
@ -47,9 +48,13 @@ public abstract class Plugin extends Thread
return;
executeContainer();
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
} finally {
}
finally
{
finished = true;
BytecodeViewer.updateBusyStatus(false);
}
@ -62,7 +67,8 @@ public abstract class Plugin extends Thread
*
* @return true if the plugin is finished executing
*/
public boolean isFinished() {
public boolean isFinished()
{
return finished;
}
@ -71,7 +77,8 @@ public abstract class Plugin extends Thread
* still be considered finished (EZ-Injection), you can call this function
* and it will set the finished boolean to true.
*/
public void setFinished() {
public void setFinished()
{
finished = true;
}
@ -80,7 +87,8 @@ public abstract class Plugin extends Thread
*/
public void executeContainer()
{
BytecodeViewer.getResourceContainers().forEach(container -> {
BytecodeViewer.getResourceContainers().forEach(container ->
{
//set the active container
activeContainer = container;

View File

@ -37,21 +37,20 @@ public class PluginConsole extends SystemConsole
public PluginConsole(String pluginName)
{
super(Configuration.pluginConsoleAsNewTab ? (pluginName + " Output")
: (TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName));
super(Configuration.pluginConsoleAsNewTab ? (pluginName + " Output") : (TranslatedStrings.PLUGIN_CONSOLE_TITLE + " - " + pluginName));
}
@Override
public void setVisible(boolean visible)
{
if(!added && visible)
if (!added && visible)
{
added = true;
PluginManager.addConsole(this);
}
//do nothing
if(!showWindow)
if (!showWindow)
return;
super.setVisible(visible);

View File

@ -18,15 +18,6 @@
package the.bytecode.club.bytecodeviewer.bootloader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import com.konloch.httprequest.HTTPRequest;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -40,18 +31,24 @@ import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalRes
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.ZipUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.getBCVDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauVersion;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import javax.swing.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* @author Konloch
* @author Bibl (don't ban me pls)
* @since 19 Jul 2015 03:22:37
*/
public class Boot {
public class Boot
{
/*flags*/
public static boolean globalstop = false;
@ -63,7 +60,8 @@ public class Boot {
private static final List<String> libsFileList = new ArrayList<>();
private static final List<String> urlList = new ArrayList<>();
public static void boot(String[] args, boolean CLI) throws Exception {
public static void boot(String[] args, boolean CLI) throws Exception
{
bootstrap();
ILoader<?> loader = findLoader();
@ -77,27 +75,30 @@ public class Boot {
SwingUtilities.invokeLater(() -> screen.setVisible(false));
}
public static void hide() {
public static void hide()
{
SwingUtilities.invokeLater(() -> screen.setVisible(false));
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static void create(ILoader<?> loader, boolean clean) throws Exception {
private static void create(ILoader<?> loader, boolean clean) throws Exception
{
setState("Bytecode Viewer Boot Screen - Checking Libraries...");
final File libsDirectory = libsDir();
populateUrlList();
if (globalstop) {
while (true) {
if (globalstop)
{
while (true)
{
Thread.sleep(100);//just keep this thread halted.
}
}
if (urlList.isEmpty()) {
JOptionPane.showMessageDialog(null, "Bytecode Viewer ran into an issue, for some reason github is not "
+ "returning what we're expecting. Please try rebooting, if this issue persists please contact "
+ "@Konloch.", "Error", JOptionPane.ERROR_MESSAGE);
if (urlList.isEmpty())
{
JOptionPane.showMessageDialog(null, "Bytecode Viewer ran into an issue, for some reason github is not " + "returning what we're expecting. Please try rebooting, if this issue persists please contact " + "@Konloch.", "Error", JOptionPane.ERROR_MESSAGE);
return;
}
@ -113,46 +114,52 @@ public class Boot {
int completedCheck = 0;
for (String s : urlList) {
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length()
);
for (String s : urlList)
{
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length());
File file = new File(libsDirectory, fileName);
boolean passed = false;
while (!passed) {
if (!libsList.contains(fileName)) {
while (!passed)
{
if (!libsList.contains(fileName))
{
downloading = true;
setState("Bytecode Viewer Boot Screen - Downloading " + fileName + "...");
System.out.println("Downloading " + fileName);
try (InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName)
.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(file)) {
try (InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName).openConnection().getInputStream(); FileOutputStream fos = new FileOutputStream(file))
{
System.out.println("Downloading from " + s);
byte[] buffer = new byte[8192];
int len;
int downloaded = 0;
boolean flag = false;
while ((len = is.read(buffer)) > 0) {
while ((len = is.read(buffer)) > 0)
{
fos.write(buffer, 0, len);
fos.flush();
downloaded += 8192;
int mbs = downloaded / 1048576;
if (mbs % 5 == 0 && mbs != 0) {
if (mbs % 5 == 0 && mbs != 0)
{
if (!flag)
System.out.println("Downloaded " + mbs + "MBs so far");
flag = true;
} else
}
else
flag = false;
}
}
try {
try
{
setState("Bytecode Viewer Boot Screen - Verifying " + fileName + "...");
System.out.println("Verifying " + fileName + "...");
File f = new File(Constants.tempDirectory, "temp");
if (!f.exists()) {
if (!f.exists())
{
f.getParentFile().mkdirs();
}
ZipUtils.zipFile(file, f);
@ -161,13 +168,18 @@ public class Boot {
libsFileList.add(file.getAbsolutePath());
System.out.println("Download finished!");
passed = true;
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Jar or Zip" + file.getAbsolutePath() + " is corrupt, redownloading.");
file.delete();
}
} else if (Configuration.verifyCorruptedStateOnBoot) { //verify its not corrupt each boot (adds 3 seconds boot time)
try {
}
else if (Configuration.verifyCorruptedStateOnBoot)
{ //verify its not corrupt each boot (adds 3 seconds boot time)
try
{
setState("Bytecode Viewer Boot Screen - Verifying " + fileName + "...");
System.out.println("Verifying " + fileName + "...");
@ -176,13 +188,17 @@ public class Boot {
f.delete();
passed = true;
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Jar or Zip" + file.getAbsolutePath() + " is corrupt, redownloading.");
libsFileList.remove(file.getAbsolutePath());
file.delete();
}
} else {
}
else
{
passed = true;
}
}
@ -193,17 +209,18 @@ public class Boot {
setState("Bytecode Viewer Boot Screen - Checking & Deleting Foreign/Outdated Libraries...");
System.out.println("Checking & Deleting foreign/outdated libraries");
for (String s : libsFileList) {
for (String s : libsFileList)
{
File f = new File(s);
boolean delete = true;
for (String urlS : urlList) {
String fileName =
urlS.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length()
);
for (String urlS : urlList)
{
String fileName = urlS.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length());
if (fileName.equals(f.getName()))
delete = false;
}
if (delete) {
if (delete)
{
f.delete();
System.out.println("Detected & Deleted Foreign/Outdated Jar/File: " + f.getName());
}
@ -212,23 +229,27 @@ public class Boot {
setState("Bytecode Viewer Boot Screen - Loading Libraries...");
System.out.println("Loading libraries...");
for (String s : libsFileList) {
if (s.endsWith(".jar")) {
for (String s : libsFileList)
{
if (s.endsWith(".jar"))
{
File f = new File(s);
if (f.exists()) {
if (f.exists())
{
setState("Bytecode Viewer Boot Screen - Loading Library " + f.getName());
System.out.println("Loading library " + f.getName());
try {
try
{
ExternalResource res = new EmptyExternalResource<>(f.toURI().toURL());
loader.bind(res);
System.out.println("Successfully loaded " + f.getName());
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
f.delete();
JOptionPane.showMessageDialog(null, "Error, Library " + f.getName() + " is corrupt, please "
+ "restart to redownload it.",
"Error", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null, "Error, Library " + f.getName() + " is corrupt, please " + "restart to redownload it.", "Error", JOptionPane.ERROR_MESSAGE);
}
}
@ -249,7 +270,8 @@ public class Boot {
completedboot = true;
}
public static File libsDir() {
public static File libsDir()
{
File dir = new File(System.getProperty("user.home"), ".Bytecode-Viewer/libs");
while (!dir.exists())
dir.mkdirs();
@ -263,7 +285,8 @@ public class Boot {
screen.setTitle(s);
}
public static ILoader<?> findLoader() {
public static ILoader<?> findLoader()
{
// TODO: Find from providers
// return new LibraryClassLoader();
@ -271,32 +294,39 @@ public class Boot {
return AbstractLoaderFactory.find().spawnLoader();
}
private static void bootstrap() {
private static void bootstrap()
{
AbstractLoaderFactory.register(ClassPathLoader::new);
}
public static void populateUrlList() throws Exception {
public static void populateUrlList() throws Exception
{
HTTPRequest req = new HTTPRequest(new URL("https://github.com/Konloch/bytecode-viewer/tree/master/libs"));
for (String s : req.read())
if (s.contains("href=\"/Konloch/bytecode-viewer/blob/master/libs/")) {
if (s.contains("href=\"/Konloch/bytecode-viewer/blob/master/libs/"))
{
urlList.add("https://github.com" + s.split("href=")[1].split("\"")[1]);
}
}
public static void populateLibsDirectory() {
public static void populateLibsDirectory()
{
File libsDir = libsDir();
if (libsDir.exists())
for (File f : MiscUtils.listFiles(libsDir)) {
for (File f : MiscUtils.listFiles(libsDir))
{
libsList.add(f.getName());
libsFileList.add(f.getAbsolutePath());
}
}
public static void dropKrakatau() {
public static void dropKrakatau()
{
File temp = new File(getBCVDirectory() + fs + "krakatau_" + krakatauVersion + ".zip");
File krakatauDirectory = new File(krakatauWorkingDirectory);
krakatauWorkingDirectory += fs + "Krakatau-master";
if (!krakatauDirectory.exists() || temp.exists()) {
if (!krakatauDirectory.exists() || temp.exists())
{
if (temp.exists())
temp.delete();
@ -306,30 +336,34 @@ public class Boot {
while (temp.exists())
temp.delete();
try (InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("Krakatau-"
+ krakatauVersion + ".zip");
FileOutputStream baos = new FileOutputStream(temp)) {
try (InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("Krakatau-" + krakatauVersion + ".zip"); FileOutputStream baos = new FileOutputStream(temp))
{
int r;
byte[] buffer = new byte[8192];
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0) {
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0)
{
baos.write(buffer, 0, r);
}
ZipUtils.unzipFilesToPath(temp.getAbsolutePath(), krakatauDirectory.getAbsolutePath());
temp.delete();
System.out.println("Successfully extracted Krakatau");
} catch (Exception e) {
}
catch (Exception e)
{
setState("Bytecode Viewer Boot Screen - ERROR, please contact @Konloch with your stacktrace.");
BytecodeViewer.handleException(e);
}
}
}
public static void dropEnjarify() {
public static void dropEnjarify()
{
File temp = new File(getBCVDirectory() + fs + "enjarify" + Constants.enjarifyVersion + ".zip");
File enjarifyDirectory = new File(Constants.enjarifyWorkingDirectory);
Constants.enjarifyWorkingDirectory += fs + "enjarify-master";
if (!enjarifyDirectory.exists() || temp.exists()) {
if (!enjarifyDirectory.exists() || temp.exists())
{
if (temp.exists())
temp.delete();
@ -339,63 +373,73 @@ public class Boot {
while (temp.exists())
temp.delete();
try (InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("enjarify-" +
Constants.enjarifyVersion + ".zip");
FileOutputStream baos = new FileOutputStream(temp)) {
try (InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("enjarify-" + Constants.enjarifyVersion + ".zip"); FileOutputStream baos = new FileOutputStream(temp))
{
int r;
byte[] buffer = new byte[8192];
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0) {
while ((r = Objects.requireNonNull(is).read(buffer)) >= 0)
{
baos.write(buffer, 0, r);
}
ZipUtils.unzipFilesToPath(temp.getAbsolutePath(), enjarifyDirectory.getAbsolutePath());
temp.delete();
System.out.println("Successfully extracted Enjarify");
} catch (Exception e) {
}
catch (Exception e)
{
setState("Bytecode Viewer Boot Screen - ERROR, please contact @Konloch with your stacktrace.");
BytecodeViewer.handleException(e);
}
}
}
public static void downloadZipsOnly() {
for (String s : urlList) {
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length()
);
public static void downloadZipsOnly()
{
for (String s : urlList)
{
String fileName = s.substring("https://github.com/Konloch/bytecode-viewer/blob/master/libs/".length());
File file = new File(libsDir(), fileName);
boolean passed = false;
while (!passed) {
if (!libsList.contains(fileName) && fileName.endsWith(".zip")) {
while (!passed)
{
if (!libsList.contains(fileName) && fileName.endsWith(".zip"))
{
downloading = true;
setState("Bytecode Viewer Boot Screen - Downloading " + fileName + "...");
System.out.println("Downloading " + fileName);
try (InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName)
.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(file)) {
try (InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/raw/master/libs/" + fileName).openConnection().getInputStream(); FileOutputStream fos = new FileOutputStream(file))
{
System.out.println("Downloading from " + s);
byte[] buffer = new byte[8192];
int len;
int downloaded = 0;
boolean flag = false;
while ((len = is.read(buffer)) > 0) {
while ((len = is.read(buffer)) > 0)
{
fos.write(buffer, 0, len);
fos.flush();
downloaded += 8192;
int mbs = downloaded / 1048576;
if (mbs % 5 == 0 && mbs != 0) {
if (mbs % 5 == 0 && mbs != 0)
{
if (!flag)
System.out.println("Downloaded " + mbs + "MBs so far");
flag = true;
} else
}
else
flag = false;
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
try {
try
{
setState("Bytecode Viewer Boot Screen - Verifying " + fileName + "...");
System.out.println("Verifying " + fileName + "...");
@ -406,35 +450,46 @@ public class Boot {
libsFileList.add(file.getAbsolutePath());
System.out.println("Download finished!");
passed = true;
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
System.out.println("Jar or Zip" + file.getAbsolutePath() + " is corrupt, redownloading.");
file.delete();
}
} else
}
else
passed = true;
}
}
}
public static void checkEnjarify() {
public static void checkEnjarify()
{
setState("Bytecode Viewer Boot Screen - Checking Enjarify...");
System.out.println("Checking enjarify");
File enjarifyZip = null;
for (File f : MiscUtils.listFiles(new File(Constants.libsDirectory))) {
if (f.getName().toLowerCase().startsWith("enjarify-")) {
for (File f : MiscUtils.listFiles(new File(Constants.libsDirectory)))
{
if (f.getName().toLowerCase().startsWith("enjarify-"))
{
Constants.enjarifyVersion = f.getName().split("-")[1].split("\\.")[0];
enjarifyZip = f;
}
}
for (File f : MiscUtils.listFiles(new File(getBCVDirectory()))) {
if (f.getName().toLowerCase().startsWith("enjarify_") && !f.getName().split("_")[1].split("\\.")[0].equals(Constants.enjarifyVersion)) {
for (File f : MiscUtils.listFiles(new File(getBCVDirectory())))
{
if (f.getName().toLowerCase().startsWith("enjarify_") && !f.getName().split("_")[1].split("\\.")[0].equals(Constants.enjarifyVersion))
{
setState("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
System.out.println("Removing oudated " + f.getName());
try {
try
{
FileUtils.deleteDirectory(f);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}
@ -442,16 +497,17 @@ public class Boot {
Constants.enjarifyWorkingDirectory = getBCVDirectory() + fs + "enjarify_" + Constants.enjarifyVersion + fs + "enjarify-master";
File enjarifyDirectory = new File(getBCVDirectory() + fs + "enjarify_" + Constants.enjarifyVersion);
if (!enjarifyDirectory.exists()) {
try {
if (!enjarifyDirectory.exists())
{
try
{
setState("Bytecode Viewer Boot Screen - Updating to " + enjarifyDirectory.getName() + "...");
ZipUtils.unzipFilesToPath(Objects.requireNonNull(enjarifyZip).getAbsolutePath(),
enjarifyDirectory.getAbsolutePath());
ZipUtils.unzipFilesToPath(Objects.requireNonNull(enjarifyZip).getAbsolutePath(), enjarifyDirectory.getAbsolutePath());
System.out.println("Updated to enjarify v" + Constants.enjarifyVersion);
} catch (Exception e) {
BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart "
+ "BCV." + nl +
"If the error persists contact @Konloch.");
}
catch (Exception e)
{
BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart " + "BCV." + nl + "If the error persists contact @Konloch.");
BytecodeViewer.handleException(e);
Objects.requireNonNull(enjarifyZip).delete();
}
@ -459,26 +515,34 @@ public class Boot {
}
public static void checkKrakatau() {
public static void checkKrakatau()
{
setState("Bytecode Viewer Boot Screen - Checking Krakatau...");
System.out.println("Checking krakatau");
File krakatauZip = null;
for (File f : MiscUtils.listFiles(new File(Constants.libsDirectory))) {
if (f.getName().toLowerCase().startsWith("krakatau-")) {
for (File f : MiscUtils.listFiles(new File(Constants.libsDirectory)))
{
if (f.getName().toLowerCase().startsWith("krakatau-"))
{
//System.out.println(f.getName());
Constants.krakatauVersion = f.getName().split("-")[1].split("\\.")[0];
krakatauZip = f;
}
}
for (File f : MiscUtils.listFiles(new File(getBCVDirectory()))) {
if (f.getName().toLowerCase().startsWith("krakatau_") && !f.getName().split("_")[1].split("\\.")[0].equals(Constants.krakatauVersion)) {
for (File f : MiscUtils.listFiles(new File(getBCVDirectory())))
{
if (f.getName().toLowerCase().startsWith("krakatau_") && !f.getName().split("_")[1].split("\\.")[0].equals(Constants.krakatauVersion))
{
setState("Bytecode Viewer Boot Screen - Removing Outdated " + f.getName() + "...");
System.out.println("Removing oudated " + f.getName());
try {
try
{
FileUtils.deleteDirectory(f);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}
@ -487,16 +551,17 @@ public class Boot {
Constants.krakatauWorkingDirectory = getBCVDirectory() + fs + "krakatau_" + Constants.krakatauVersion + fs + "Krakatau-master";
File krakatauDirectory = new File(getBCVDirectory() + fs + "krakatau_" + Constants.krakatauVersion);
if (!krakatauDirectory.exists()) {
try {
if (!krakatauDirectory.exists())
{
try
{
setState("Bytecode Viewer Boot Screen - Updating to " + krakatauDirectory.getName() + "...");
ZipUtils.unzipFilesToPath(Objects.requireNonNull(krakatauZip).getAbsolutePath(),
krakatauDirectory.getAbsolutePath());
ZipUtils.unzipFilesToPath(Objects.requireNonNull(krakatauZip).getAbsolutePath(), krakatauDirectory.getAbsolutePath());
System.out.println("Updated to krakatau v" + Constants.krakatauVersion);
} catch (Exception e) {
BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly "
+ "corrupt). Restart BCV." + nl +
"If the error persists contact @Konloch.");
}
catch (Exception e)
{
BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly " + "corrupt). Restart BCV." + nl + "If the error persists contact @Konloch.");
BytecodeViewer.handleException(e);
Objects.requireNonNull(krakatauZip).delete();
}

View File

@ -25,7 +25,5 @@ package the.bytecode.club.bytecodeviewer.bootloader;
public enum BootState
{
START_UP,
SETTINGS_LOADED,
GUI_SHOWING,
START_UP, SETTINGS_LOADED, GUI_SHOWING,
}

View File

@ -18,21 +18,16 @@
package the.bytecode.club.bytecodeviewer.bootloader;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.components.HTMLPane;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import static the.bytecode.club.bytecodeviewer.Configuration.language;
/**
@ -47,9 +42,11 @@ public class InitialBootScreen extends JFrame
public InitialBootScreen() throws IOException
{
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e) {
public void windowClosing(WindowEvent e)
{
Configuration.canExit = true;
System.exit(0);
}
@ -98,7 +95,8 @@ public class InitialBootScreen extends JFrame
return Toolkit.getDefaultToolkit().getScreenSize();
}
public JProgressBar getProgressBar() {
public JProgressBar getProgressBar()
{
return progressBar;
}

View File

@ -22,7 +22,7 @@ import static the.bytecode.club.bytecodeviewer.Constants.AUTOMATIC_LIBRARY_UPDAT
/**
* Downloads & installs the krakatau & enjarify zips
*
* <p>
* Alternatively if OFFLINE_MODE is enabled it will drop the Krakatau and Enjarify versions supplied with BCV
*
* @author Konloch

View File

@ -18,17 +18,8 @@
package the.bytecode.club.bytecodeviewer.bootloader;
import de.skuzzle.semantic.Version;
import java.awt.Desktop;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import javax.swing.JFileChooser;
import com.konloch.httprequest.HTTPRequest;
import de.skuzzle.semantic.Version;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.api.BCV;
@ -36,6 +27,12 @@ import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URI;
import java.net.URL;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
@ -46,8 +43,7 @@ public class UpdateCheck implements Runnable
{
//just brute force download the url path
//one of these works for every single version of BCV
public static final String[] remoteGithubReleases = new String[]
{
public static final String[] remoteGithubReleases = new String[]{
//current url scheme since v2.9.12
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.jar",
//for v2.9.10 and v2.9.11
@ -63,31 +59,13 @@ public class UpdateCheck implements Runnable
//for v1.0
"https://github.com/Konloch/bytecode-viewer/releases/download/B{VERSION}/BytecodeViewer.jar",
//zip variant of current url scheme since v2.9.12 (not currently used but incase it ever does)
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.zip",
};
"https://github.com/Konloch/bytecode-viewer/releases/download/v{VERSION}/Bytecode-Viewer-{VERSION}.zip",};
//a list of all of the released versions of BCV
public static final String[] versions = new String[]
{
public static final String[] versions = new String[]{
//"2.11.0",
//"2.10.15",
"2.10.14",
"2.10.13",
"2.10.12",
"2.10.11",
"2.9.22",
"2.9.21",
"2.9.20",
"2.9.19",
"2.9.18",
"2.9.17",
"2.9.16",
"2.9.15",
"2.9.14",
"2.9.13",
"2.9.12",
"2.9.11",
"2.9.10", //broken due to repo change
"2.10.14", "2.10.13", "2.10.12", "2.10.11", "2.9.22", "2.9.21", "2.9.20", "2.9.19", "2.9.18", "2.9.17", "2.9.16", "2.9.15", "2.9.14", "2.9.13", "2.9.12", "2.9.11", "2.9.10", //broken due to repo change
"2.9.8", //broken due to repo change & zip
"2.9.7", //broken due to repo change & zip
"2.9.6", //zip
@ -101,48 +79,28 @@ public class UpdateCheck implements Runnable
"2.8.0", //zip
"2.7.1", //zip
"2.7.0", //zip
"2.6.0",
"2.5.2",
"2.5.1",
"2.5.0",
"2.4.0",
"2.3.0",
"2.2.1",
"2.2.0",
"2.1.1",
"2.1.0",
"2.0.1",
"2.0",
"1.5.3",
"1.5.2",
"1.5.1",
"1.5",
"1.4",
"1.3.1",
"1.3",
"1.2",
"1.1",
"1.0",
};
"2.6.0", "2.5.2", "2.5.1", "2.5.0", "2.4.0", "2.3.0", "2.2.1", "2.2.0", "2.1.1", "2.1.0", "2.0.1", "2.0", "1.5.3", "1.5.2", "1.5.1", "1.5", "1.4", "1.3.1", "1.3", "1.2", "1.1", "1.0",};
@Override
public void run()
{
try {
try
{
HTTPRequest r = new HTTPRequest(new URL("https://raw.githubusercontent.com/Konloch/bytecode-viewer/master/VERSION"));
final Version version = Version.parseVersion(r.readSingle());
final Version localVersion = Version.parseVersion(VERSION);
try {
try
{
//developer version
if (Version.compare(localVersion, version) > 0)
return;
} catch (Exception ignored) { }
}
catch (Exception ignored)
{
}
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version",
"Your version: " + localVersion + ", latest version: " + version + nl +
"What would you like to do?",
new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing (And Don't Ask Again)"});
MultipleChoiceDialog outdatedDialog = new MultipleChoiceDialog("Bytecode Viewer - Outdated Version", "Your version: " + localVersion + ", latest version: " + version + nl + "What would you like to do?", new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing (And Don't Ask Again)"});
int result = outdatedDialog.promptChoice();
@ -151,34 +109,35 @@ public class UpdateCheck implements Runnable
if (Desktop.isDesktopSupported())
Desktop.getDesktop().browse(new URI("https://github.com/Konloch/bytecode-viewer/releases"));
else
BytecodeViewer.showMessage("Cannot open the page, please manually type it."
+ nl + "https://github.com/Konloch/bytecode-viewer/releases");
BytecodeViewer.showMessage("Cannot open the page, please manually type it." + nl + "https://github.com/Konloch/bytecode-viewer/releases");
}
else if (result == 1)
{
//TODO move this to after the file extension has been found
final File file = promptFileSave("Jar Archives", "jar");
if(file != null)
if (file != null)
{
Thread downloadThread = new Thread(() ->
downloadBCV(version.toString(), file, ()->{}, ()->{}), "Downloader");
Thread downloadThread = new Thread(() -> downloadBCV(version.toString(), file, () ->
{}, () ->
{}), "Downloader");
downloadThread.start();
}
}
else if(result == 2)
else if (result == 2)
{
//TODO save version into a hashset called doNotPrompt
}
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static File promptFileSave(String description, String extension) throws IOException
{
JFileChooser fc = new FileChooser(new File("./").getCanonicalFile(),
"Select Save File", description, extension);
JFileChooser fc = new FileChooser(new File("./").getCanonicalFile(), "Select Save File", description, extension);
int returnVal = fc.showSaveDialog(BytecodeViewer.viewer);
File file = null;
@ -193,9 +152,7 @@ public class UpdateCheck implements Runnable
if (file.exists())
{
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File",
"The file " + file + " exists, would you like to overwrite it?",
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
MultipleChoiceDialog overwriteDialog = new MultipleChoiceDialog("Bytecode Viewer - Overwrite File", "The file " + file + " exists, would you like to overwrite it?", new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
if (overwriteDialog.promptChoice() != 0)
return null;
@ -223,28 +180,32 @@ public class UpdateCheck implements Runnable
private static void downloadBCV(String version, File saveTo, Runnable onFinish, Runnable onFail)
{
boolean found = false;
for(String urlAttempt : remoteGithubReleases)
for (String urlAttempt : remoteGithubReleases)
{
try
{
String url = urlAttempt.replace("{VERSION}", version);
if(validURl(url))
if (validURl(url))
{
download(url, saveTo, onFinish);
found = true;
break;
}
} catch (FileNotFoundException ex) {
}
catch (FileNotFoundException ex)
{
//ignore 404s
} catch (Exception e) {
}
catch (Exception e)
{
//print network errors but don't alert user
e.printStackTrace();
}
}
if(!found)
if (!found)
{
BCV.logE("Failed to download BCV v" + version);
BytecodeViewer.showMessage("Unable to download BCV v" + version + ", please let Konloch know.");
@ -262,11 +223,10 @@ public class UpdateCheck implements Runnable
private static void download(String url, File saveTo, Runnable onFinish) throws Exception
{
BCV.log("Downloading from: " + url);
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box."
+ nl + nl + "Expect this to take several minutes.");
BytecodeViewer.showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box." + nl + nl + "Expect this to take several minutes.");
try (InputStream is = new URL(url).openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(saveTo)) {
try (InputStream is = new URL(url).openConnection().getInputStream(); FileOutputStream fos = new FileOutputStream(saveTo))
{
byte[] buffer = new byte[8192];
int len;
int downloaded = 0;
@ -284,7 +244,8 @@ public class UpdateCheck implements Runnable
if (!flag)
System.out.println("Downloaded " + mbs + "MBs so far");
flag = true;
} else
}
else
flag = false;
}
}

View File

@ -18,32 +18,38 @@
package the.bytecode.club.bytecodeviewer.bootloader.classtree;
import org.objectweb.asm.tree.ClassNode;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.tree.ClassNode;
/**
* @author Bibl (don't ban me pls)
* @since 25 May 2015 (actually before this)
*/
public class ClassHelper {
public class ClassHelper
{
public static Map<String, ClassNode> convertToMap(Collection<ClassNode> classes) {
public static Map<String, ClassNode> convertToMap(Collection<ClassNode> classes)
{
Map<String, ClassNode> map = new HashMap<>();
for (ClassNode cn : classes) {
for (ClassNode cn : classes)
{
map.put(cn.name, cn);
}
return map;
}
public static <T, K> Map<T, K> copyOf(Map<T, K> src) {
public static <T, K> Map<T, K> copyOf(Map<T, K> src)
{
Map<T, K> dst = new HashMap<>();
copy(src, dst);
return dst;
}
public static <T, K> void copy(Map<T, K> src, Map<T, K> dst) {
public static <T, K> void copy(Map<T, K> src, Map<T, K> dst)
{
dst.putAll(src);
}
}

View File

@ -18,17 +18,13 @@
package the.bytecode.club.bytecodeviewer.bootloader.classtree;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap.NullPermeableHashMap;
import the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashmap.SetCreator;
import java.util.*;
import static the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassHelper.convertToMap;
import static the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassHelper.copyOf;
@ -36,24 +32,28 @@ import static the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassHelper.
* @author Bibl (don't ban me pls)
* @since 25 May 2015 (actually before this)
*/
public class ClassTree {
public class ClassTree
{
private static final SetCreator<ClassNode> SET_CREATOR = new SetCreator<>();
private final Map<String, ClassNode> classes;
private final NullPermeableHashMap<ClassNode, Set<ClassNode>> supers;
private final NullPermeableHashMap<ClassNode, Set<ClassNode>> delgates;
public ClassTree() {
public ClassTree()
{
classes = new HashMap<>();
supers = new NullPermeableHashMap<>(SET_CREATOR);
delgates = new NullPermeableHashMap<>(SET_CREATOR);
}
public ClassTree(Collection<ClassNode> classes) {
public ClassTree(Collection<ClassNode> classes)
{
this(convertToMap(classes));
}
public ClassTree(Map<String, ClassNode> classes_) {
public ClassTree(Map<String, ClassNode> classes_)
{
classes = copyOf(classes_);
supers = new NullPermeableHashMap<>(SET_CREATOR);
delgates = new NullPermeableHashMap<>(SET_CREATOR);
@ -62,9 +62,12 @@ public class ClassTree {
}
// TODO: optimise
public void build(Map<String, ClassNode> classes) {
for (ClassNode node : classes.values()) {
for (String iface : node.interfaces) {
public void build(Map<String, ClassNode> classes)
{
for (ClassNode node : classes.values())
{
for (String iface : node.interfaces)
{
ClassNode ifacecs = classes.get(iface);
if (ifacecs == null)
continue;
@ -77,10 +80,12 @@ public class ClassTree {
getSupers0(node).addAll(superinterfaces);
}
ClassNode currentSuper = classes.get(node.superName);
while (currentSuper != null) {
while (currentSuper != null)
{
getDelegates0(currentSuper).add(node);
getSupers0(node).add(currentSuper);
for (String iface : currentSuper.interfaces) {
for (String iface : currentSuper.interfaces)
{
ClassNode ifacecs = classes.get(iface);
if (ifacecs == null)
continue;
@ -98,8 +103,10 @@ public class ClassTree {
}
}
public void build(ClassNode node) {
for (String iface : node.interfaces) {
public void build(ClassNode node)
{
for (String iface : node.interfaces)
{
ClassNode ifacecs = classes.get(iface);
if (ifacecs == null)
continue;
@ -112,10 +119,12 @@ public class ClassTree {
getSupers0(node).addAll(superinterfaces);
}
ClassNode currentSuper = classes.get(node.superName);
while (currentSuper != null) {
while (currentSuper != null)
{
getDelegates0(currentSuper).add(node);
getSupers0(node).add(currentSuper);
for (String iface : currentSuper.interfaces) {
for (String iface : currentSuper.interfaces)
{
ClassNode ifacecs = classes.get(iface);
if (ifacecs == null)
continue;
@ -134,12 +143,14 @@ public class ClassTree {
classes.put(node.name, node);
}
private void buildSubTree(Map<String, ClassNode> classes, Collection<ClassNode> superinterfaces,
ClassNode current) {
private void buildSubTree(Map<String, ClassNode> classes, Collection<ClassNode> superinterfaces, ClassNode current)
{
superinterfaces.add(current);
for (String iface : current.interfaces) {
for (String iface : current.interfaces)
{
ClassNode cs = classes.get(iface);
if (cs != null) {
if (cs != null)
{
getDelegates0(cs).add(current);
buildSubTree(classes, superinterfaces, cs);
} /*else {
@ -148,11 +159,15 @@ public class ClassTree {
}
}
public Set<MethodNode> getMethodsFromSuper(ClassNode node, String name, String desc) {
public Set<MethodNode> getMethodsFromSuper(ClassNode node, String name, String desc)
{
Set<MethodNode> methods = new HashSet<>();
for (ClassNode super_ : getSupers(node)) {
for (MethodNode mn : super_.methods) {
if (mn.name.equals(name) && mn.desc.equals(desc)) {
for (ClassNode super_ : getSupers(node))
{
for (MethodNode mn : super_.methods)
{
if (mn.name.equals(name) && mn.desc.equals(desc))
{
methods.add(mn);
}
}
@ -160,11 +175,15 @@ public class ClassTree {
return methods;
}
public Set<MethodNode> getMethodsFromDelegates(ClassNode node, String name, String desc) {
public Set<MethodNode> getMethodsFromDelegates(ClassNode node, String name, String desc)
{
Set<MethodNode> methods = new HashSet<>();
for (ClassNode delegate : getDelegates(node)) {
for (MethodNode mn : delegate.methods) {
if (mn.name.equals(name) && mn.desc.equals(desc)) {
for (ClassNode delegate : getDelegates(node))
{
for (MethodNode mn : delegate.methods)
{
if (mn.name.equals(name) && mn.desc.equals(desc))
{
methods.add(mn);
}
}
@ -172,10 +191,14 @@ public class ClassTree {
return methods;
}
public MethodNode getFirstMethodFromSuper(ClassNode node, String name, String desc) {
for (ClassNode super_ : getSupers(node)) {
for (MethodNode mn : super_.methods) {
if (mn.name.equals(name) && mn.desc.equals(desc)) {
public MethodNode getFirstMethodFromSuper(ClassNode node, String name, String desc)
{
for (ClassNode super_ : getSupers(node))
{
for (MethodNode mn : super_.methods)
{
if (mn.name.equals(name) && mn.desc.equals(desc))
{
return mn;
}
}
@ -183,32 +206,39 @@ public class ClassTree {
return null;
}
public ClassNode getClass(String name) {
public ClassNode getClass(String name)
{
return classes.get(name);
}
public boolean isInherited(ClassNode cn, String name, String desc) {
public boolean isInherited(ClassNode cn, String name, String desc)
{
return getFirstMethodFromSuper(cn, name, desc) != null;
}
private Set<ClassNode> getSupers0(ClassNode cn) {
private Set<ClassNode> getSupers0(ClassNode cn)
{
return supers.getNonNull(cn);
}
private Set<ClassNode> getDelegates0(ClassNode cn) {
private Set<ClassNode> getDelegates0(ClassNode cn)
{
return delgates.getNonNull(cn);
}
public Map<String, ClassNode> getClasses() {
public Map<String, ClassNode> getClasses()
{
return classes;
}
public Set<ClassNode> getSupers(ClassNode cn) {
public Set<ClassNode> getSupers(ClassNode cn)
{
return Collections.unmodifiableSet(supers.get(cn));
// return supers.get(cn);
}
public Set<ClassNode> getDelegates(ClassNode cn) {
public Set<ClassNode> getDelegates(ClassNode cn)
{
return Collections.unmodifiableSet(delgates.get(cn));
// return delgates.get(cn);
}

View File

@ -22,10 +22,12 @@ package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashma
* @author Bibl (don't ban me pls)
* @since ages ago
*/
public class NullCreator<V> implements ValueCreator<V> {
public class NullCreator<V> implements ValueCreator<V>
{
@Override
public V create() {
public V create()
{
return null;
}
}

View File

@ -24,23 +24,28 @@ import java.util.HashMap;
* @author Bibl (don't ban me pls)
* @since ages ago
*/
public class NullPermeableHashMap<K, V> extends HashMap<K, V> {
public class NullPermeableHashMap<K, V> extends HashMap<K, V>
{
private static final long serialVersionUID = 1L;
private final ValueCreator<V> creator;
public NullPermeableHashMap(ValueCreator<V> creator) {
public NullPermeableHashMap(ValueCreator<V> creator)
{
this.creator = creator;
}
public NullPermeableHashMap() {
public NullPermeableHashMap()
{
this(new NullCreator<>());
}
public V getNonNull(K k) {
public V getNonNull(K k)
{
V val = get(k);
if (val == null) {
if (val == null)
{
val = creator.create();
put(k, val);
}

View File

@ -25,10 +25,12 @@ import java.util.Set;
* @author Bibl (don't ban me pls)
* @since 25 May 2015 (actually before this)
*/
public class SetCreator<T> implements ValueCreator<Set<T>> {
public class SetCreator<T> implements ValueCreator<Set<T>>
{
@Override
public Set<T> create() {
public Set<T> create()
{
return new HashSet<>();
}
}

View File

@ -22,7 +22,8 @@ package the.bytecode.club.bytecodeviewer.bootloader.classtree.nullpermablehashma
* @author Bibl (don't ban me pls)
* @since ages ago
*/
public interface ValueCreator<V> {
public interface ValueCreator<V>
{
V create();
}

View File

@ -18,58 +18,71 @@
package the.bytecode.club.bytecodeviewer.bootloader.loader;
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
import java.util.HashMap;
import java.util.Map;
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
/**
* @author Bibl (don't ban me pls)
* @since 21 Jul 2015 00:18:07
*/
public final class AbstractLoaderFactory {
public final class AbstractLoaderFactory
{
private static final String DEFAULT_KEY = "default-factory";
private static final Map<String, LoaderFactory<?>> FACTORY_CACHE = new HashMap<>();
public static void register(LoaderFactory<?> factory) {
public static void register(LoaderFactory<?> factory)
{
register(DEFAULT_KEY, factory);
}
public static void register(String key, LoaderFactory<?> factory) {
if (key == null || factory == null) {
public static void register(String key, LoaderFactory<?> factory)
{
if (key == null || factory == null)
{
throw new IllegalArgumentException("null key or factory");
}
if (FACTORY_CACHE.containsKey(key)) {
if (FACTORY_CACHE.containsKey(key))
{
throw new IllegalArgumentException("factory already registered with key: " + key);
}
FACTORY_CACHE.put(key, factory);
}
public static void unregister(String key) {
if (key == null) {
public static void unregister(String key)
{
if (key == null)
{
throw new IllegalArgumentException("null key");
}
if (!FACTORY_CACHE.containsKey(key)) {
if (!FACTORY_CACHE.containsKey(key))
{
throw new IllegalArgumentException("factory doesn't key for key: " + key);
}
FACTORY_CACHE.remove(key);
}
public static <T extends ExternalResource<?>> LoaderFactory<T> find() {
public static <T extends ExternalResource<?>> LoaderFactory<T> find()
{
return find(DEFAULT_KEY);
}
@SuppressWarnings("unchecked")
public static <T extends ExternalResource<?>> LoaderFactory<T> find(String key) {
if (key == null) {
public static <T extends ExternalResource<?>> LoaderFactory<T> find(String key)
{
if (key == null)
{
throw new IllegalArgumentException("null key");
}
if (!FACTORY_CACHE.containsKey(key)) {
if (!FACTORY_CACHE.containsKey(key))
{
throw new IllegalArgumentException("factory doesn't key for key: " + key);
}

View File

@ -18,21 +18,22 @@
package the.bytecode.club.bytecodeviewer.bootloader.loader;
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
/**
* @author Bibl (don't ban me pls)
* @since 21 Jul 2015 00:09:53
*/
public class ClassPathLoader implements ILoader<Object> {
public class ClassPathLoader implements ILoader<Object>
{
void extendClassPath(URL url) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
void extendClassPath(URL url) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> urlClass = URLClassLoader.class;
Method method = urlClass.getDeclaredMethod("addURL", URL.class);
@ -46,18 +47,24 @@ public class ClassPathLoader implements ILoader<Object> {
* @see the.bytecode.club.bootloader.ILoader#bind(the.bytecode.club.bootloader .resource.ExternalResource)
*/
@Override
public void bind(ExternalResource<Object> resource) {
try {
if (resource != null) {
public void bind(ExternalResource<Object> resource)
{
try
{
if (resource != null)
{
URL url = resource.getLocation();
if (url != null) {
if (url != null)
{
extendClassPath(url);
}
}
}/* catch (IOException e) {
System.err.println("Error loading resource.");
e.printStackTrace();
}*/ catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
}*/
catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
System.err.println("Error reflecting URLClassLoader.addURL(URL) ?");
e.printStackTrace();
}
@ -69,7 +76,8 @@ public class ClassPathLoader implements ILoader<Object> {
* @see the.bytecode.club.bootloader.ILoader#findClass(java.lang.String)
*/
@Override
public Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError {
public Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError
{
return Class.forName(name);
}
@ -79,7 +87,8 @@ public class ClassPathLoader implements ILoader<Object> {
* @see the.bytecode.club.bootloader.ILoader#loadClass(java.lang.String)
*/
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException, NoClassDefFoundError {
public Class<?> loadClass(String name) throws ClassNotFoundException, NoClassDefFoundError
{
return findClass(name);
}
}

View File

@ -24,7 +24,8 @@ import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalRes
* @author Bibl (don't ban me pls)
* @since 19 Jul 2015 02:29:43
*/
public interface ILoader<T> {
public interface ILoader<T>
{
void bind(ExternalResource<T> resource);

View File

@ -18,12 +18,6 @@
package the.bytecode.club.bytecodeviewer.bootloader.loader;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
@ -31,20 +25,29 @@ import the.bytecode.club.bytecodeviewer.bootloader.classtree.ClassTree;
import the.bytecode.club.bytecodeviewer.bootloader.resource.external.ExternalResource;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents.JarContents;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author Bibl (don't ban me pls)
* @since 19 Jul 2015 02:48:41
*
* <p>
* TODO: Resource loading
*/
@Deprecated
public class LibraryClassLoader extends ClassLoader implements ILoader<JarContents<ClassNode>> {
public class LibraryClassLoader extends ClassLoader implements ILoader<JarContents<ClassNode>>
{
private final Set<JarContents<ClassNode>> binded;
private final Map<String, Class<?>> classCache;
private final ClassTree tree;
public LibraryClassLoader() {
public LibraryClassLoader()
{
binded = new HashSet<>();
classCache = new HashMap<>();
tree = new ClassTree();
@ -55,16 +58,23 @@ public class LibraryClassLoader extends ClassLoader implements ILoader<JarConten
* .ExternalResource)
*/
@Override
public void bind(ExternalResource<JarContents<ClassNode>> resource) {
try {
public void bind(ExternalResource<JarContents<ClassNode>> resource)
{
try
{
JarContents<ClassNode> contents = resource.load();
if (contents != null) {
if (contents != null)
{
binded.add(contents);
tree.build(contents.getClassContents().namedMap());
} else {
}
else
{
System.err.println("Null contents?");
}
} catch (IOException e) {
}
catch (IOException e)
{
e.printStackTrace();
}
}
@ -73,21 +83,25 @@ public class LibraryClassLoader extends ClassLoader implements ILoader<JarConten
* @see the.bytecode.club.bytecodeviewer.loadermodel.ILoader#loadClass(java.lang.String)
*/
@Override
public Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError {
public Class<?> findClass(String name) throws ClassNotFoundException, NoClassDefFoundError
{
String byte_name = name.replace(".", "/");
if (classCache.containsKey(byte_name))
return classCache.get(byte_name);
ClassNode cn = null;
for (JarContents<ClassNode> contents : binded) {
for (JarContents<ClassNode> contents : binded)
{
cn = contents.getClassContents().namedMap().get(byte_name);
if (cn != null)
break;
}
if (cn != null) {
if (cn != null)
{
Class<?> klass = define(cn);
if (klass != null) {
if (klass != null)
{
classCache.put(byte_name, klass);
return klass;
}
@ -96,39 +110,46 @@ public class LibraryClassLoader extends ClassLoader implements ILoader<JarConten
return super.loadClass(name);
}
protected Class<?> define(ClassNode cn) {
protected Class<?> define(ClassNode cn)
{
ClassWriter writer = new ResolvingClassWriter(tree);
cn.accept(cn);
byte[] bytes = writer.toByteArray();
return defineClass(bytes, 0, bytes.length);
}
public static class ResolvingClassWriter extends ClassWriter {
public static class ResolvingClassWriter extends ClassWriter
{
private final ClassTree classTree;
public ResolvingClassWriter(ClassTree classTree) {
public ResolvingClassWriter(ClassTree classTree)
{
super(ClassWriter.COMPUTE_FRAMES);
this.classTree = classTree;
}
@Deprecated
void update(Map<String, ClassNode> classes) {
void update(Map<String, ClassNode> classes)
{
classTree.build(classes);
}
@Override
protected String getCommonSuperClass(String type1, String type2) {
protected String getCommonSuperClass(String type1, String type2)
{
ClassNode ccn = classTree.getClass(type1);
ClassNode dcn = classTree.getClass(type2);
//System.out.println(type1 + " " + type2);
if (ccn == null) {
if (ccn == null)
{
classTree.build(createQuick(type1));
return getCommonSuperClass(type1, type2);
}
if (dcn == null) {
if (dcn == null)
{
classTree.build(createQuick(type2));
return getCommonSuperClass(type1, type2);
}
@ -142,10 +163,14 @@ public class LibraryClassLoader extends ClassLoader implements ILoader<JarConten
if (d.contains(ccn))
return type2;
if (Modifier.isInterface(ccn.access) || Modifier.isInterface(dcn.access)) {
if (Modifier.isInterface(ccn.access) || Modifier.isInterface(dcn.access))
{
return "java/lang/Object";
} else {
do {
}
else
{
do
{
ClassNode nccn = classTree.getClass(ccn.superName);
if (nccn == null)
break;
@ -156,13 +181,17 @@ public class LibraryClassLoader extends ClassLoader implements ILoader<JarConten
}
}
public ClassNode createQuick(String name) {
try {
public ClassNode createQuick(String name)
{
try
{
ClassReader cr = new ClassReader(name);
ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
return cn;
} catch (IOException e) {
}
catch (IOException e)
{
e.printStackTrace();
return null;
}

View File

@ -22,7 +22,8 @@ package the.bytecode.club.bytecodeviewer.bootloader.loader;
* @author Bibl (don't ban me pls)
* @since 21 Jul 2015 00:14:53
*/
public interface LoaderFactory<T> {
public interface LoaderFactory<T>
{
ILoader<T> spawnLoader();
}

View File

@ -26,19 +26,23 @@ import java.util.Map;
* @author Bibl (don't ban me pls)
* @since 21 Jul 2013
*/
public abstract class DataContainer<T> extends ArrayList<T> {
public abstract class DataContainer<T> extends ArrayList<T>
{
private static final long serialVersionUID = -9022506488647444546L;
public DataContainer() {
public DataContainer()
{
this(16);
}
public DataContainer(int cap) {
public DataContainer(int cap)
{
super(cap);
}
public DataContainer(Collection<T> data) {
public DataContainer(Collection<T> data)
{
addAll(data);
}

View File

@ -24,12 +24,14 @@ import java.net.URL;
* @author Bibl (don't ban me pls)
* @since 21 Jul 2015 00:29:11
*/
public class EmptyExternalResource<T> extends ExternalResource<T> {
public class EmptyExternalResource<T> extends ExternalResource<T>
{
/**
* @param location
*/
public EmptyExternalResource(URL location) {
public EmptyExternalResource(URL location)
{
super(location);
}
@ -37,7 +39,8 @@ public class EmptyExternalResource<T> extends ExternalResource<T> {
* @see the.bytecode.club.bootloader.resource.ExternalResource#load()
*/
@Override
public T load() {
public T load()
{
throw new UnsupportedOperationException();
}
}

View File

@ -18,6 +18,12 @@
package the.bytecode.club.bytecodeviewer.bootloader.resource.external;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarInfo;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarResource;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents.JarContents;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@ -27,43 +33,47 @@ import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarInfo;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarResource;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents.JarContents;
/**
* @author Bibl (don't ban me pls)
* @since 19 Jul 2015 02:33:23
*/
public class ExternalLibrary extends ExternalResource<JarContents<ClassNode>> {
public class ExternalLibrary extends ExternalResource<JarContents<ClassNode>>
{
/**
* @param location
*/
public ExternalLibrary(URL location) {
public ExternalLibrary(URL location)
{
super(location);
}
/**
* @param jar
*/
public ExternalLibrary(JarInfo jar) {
public ExternalLibrary(JarInfo jar)
{
super(createJarURL(jar));
}
public static URL createJarURL(JarInfo jar) {
try {
public static URL createJarURL(JarInfo jar)
{
try
{
return jar.formattedURL();
} catch (MalformedURLException e) {
}
catch (MalformedURLException e)
{
e.printStackTrace();
return null;
}
}
public static byte[] read(InputStream in) throws IOException {
try (ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream()) {
public static byte[] read(InputStream in) throws IOException
{
try (ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream())
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1)
@ -72,7 +82,8 @@ public class ExternalLibrary extends ExternalResource<JarContents<ClassNode>> {
}
}
protected ClassNode create(byte[] b) {
protected ClassNode create(byte[] b)
{
ClassReader cr = new ClassReader(b);
ClassNode cn = new ClassNode();
cr.accept(cn, 0);
@ -83,21 +94,27 @@ public class ExternalLibrary extends ExternalResource<JarContents<ClassNode>> {
* @see the.bytecode.club.bytecodeviewer.loadermodel.ExternalResource#load()
*/
@Override
public JarContents<ClassNode> load() throws IOException {
public JarContents<ClassNode> load() throws IOException
{
JarContents<ClassNode> contents = new JarContents<>();
JarURLConnection con = (JarURLConnection) getLocation().openConnection();
JarFile jar = con.getJarFile();
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
while (entries.hasMoreElements())
{
JarEntry entry = entries.nextElement();
try (InputStream is = jar.getInputStream(entry)) {
try (InputStream is = jar.getInputStream(entry))
{
byte[] bytes = read(is);
if (entry.getName().endsWith(".class")) {
if (entry.getName().endsWith(".class"))
{
ClassNode cn = create(bytes);
contents.getClassContents().add(cn);
} else {
}
else
{
JarResource resource = new JarResource(entry.getName(), bytes);
contents.getResourceContents().add(resource);
}

View File

@ -25,24 +25,28 @@ import java.net.URL;
* @author Bibl (don't ban me pls)
* @since 19 Jul 2015 02:30:30
*/
public abstract class ExternalResource<T> {
public abstract class ExternalResource<T>
{
private final URL location;
public ExternalResource(URL location) {
public ExternalResource(URL location)
{
if (location == null)
throw new IllegalArgumentException();
this.location = location;
}
public URL getLocation() {
public URL getLocation()
{
return location;
}
public abstract T load() throws IOException;
@Override
public int hashCode() {
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + location.hashCode();
@ -50,7 +54,8 @@ public abstract class ExternalResource<T> {
}
@Override
public boolean equals(Object obj) {
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
@ -62,7 +67,8 @@ public abstract class ExternalResource<T> {
}
@Override
public String toString() {
public String toString()
{
return "Library @" + location.toExternalForm();
}
}

View File

@ -29,7 +29,8 @@ import java.net.URL;
* @author Bibl
* @since 19 Jul 2013
*/
public class JarInfo {
public class JarInfo
{
private final String path;
private final JarType type;
@ -39,7 +40,8 @@ public class JarInfo {
*
* @param path Path to jar.
*/
public JarInfo(File path) {
public JarInfo(File path)
{
this(path.getAbsolutePath(), JarType.FILE);
}
@ -49,7 +51,8 @@ public class JarInfo {
* @param path Path to jar.
* @param type Type of jar.
*/
public JarInfo(String path, JarType type) {
public JarInfo(String path, JarType type)
{
this.path = path;
this.type = type;
}
@ -59,18 +62,21 @@ public class JarInfo {
*
* @param url URL to jar.
*/
public JarInfo(URL url) {
public JarInfo(URL url)
{
this(url.toExternalForm(), JarType.WEB);
}
/**
* @return Real path to JarFile.
*/
public final String getPath() {
public final String getPath()
{
return path;
}
public final JarType getType() {
public final JarType getType()
{
return type;
}
@ -80,9 +86,11 @@ public class JarInfo {
* @return The formatted url.
* @throws MalformedURLException
*/
public URL formattedURL() throws MalformedURLException {
public URL formattedURL() throws MalformedURLException
{
StringBuilder sb = new StringBuilder().append("jar:").append(type.prefix()).append(path);
if (type.equals(JarType.FILE) && !path.endsWith(".jar")) {
if (type.equals(JarType.FILE) && !path.endsWith(".jar"))
{
File file = new File(path);
if (!file.exists())
sb.append(".jar");
@ -92,7 +100,8 @@ public class JarInfo {
}
@Override
public int hashCode() {
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + ((path == null) ? 0 : path.hashCode());
@ -101,7 +110,8 @@ public class JarInfo {
}
@Override
public boolean equals(Object obj) {
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
@ -109,10 +119,12 @@ public class JarInfo {
if (getClass() != obj.getClass())
return false;
JarInfo other = (JarInfo) obj;
if (path == null) {
if (path == null)
{
if (other.path != null)
return false;
} else if (!path.equals(other.path))
}
else if (!path.equals(other.path))
return false;
return type == other.type;
}

View File

@ -24,26 +24,31 @@ import java.util.Arrays;
* @author Bibl (don't ban me pls)
* @since 19 Jul 2013
*/
public class JarResource {
public class JarResource
{
private final String name;
private final byte[] data;
public JarResource(String name, byte[] data) {
public JarResource(String name, byte[] data)
{
this.name = name;
this.data = data;
}
public String getName() {
public String getName()
{
return name;
}
public byte[] getData() {
public byte[] getData()
{
return data;
}
@Override
public int hashCode() {
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + Arrays.hashCode(data);
@ -52,7 +57,8 @@ public class JarResource {
}
@Override
public boolean equals(Object obj) {
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
@ -62,8 +68,11 @@ public class JarResource {
JarResource other = (JarResource) obj;
if (!Arrays.equals(data, other.data))
return false;
if (name == null) {
if (name == null)
{
return other.name == null;
} else return name.equals(other.name);
}
else
return name.equals(other.name);
}
}

View File

@ -24,7 +24,8 @@ package the.bytecode.club.bytecodeviewer.bootloader.resource.jar;
* @author Bibl
* @since 19 Jul 2013
*/
public enum JarType {
public enum JarType
{
/**
* Local file
@ -37,14 +38,16 @@ public enum JarType {
private final String prefix;
JarType(String prefix) {
JarType(String prefix)
{
this.prefix = prefix;
}
/**
* Gets the prefix for the JarURLConnection.
**/
public String prefix() {
public String prefix()
{
return prefix;
}
}

View File

@ -18,49 +18,52 @@
package the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.bootloader.resource.DataContainer;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarResource;
import java.util.*;
/**
* @author Bibl (don't ban me pls)
* @since 19 Jul 2013
*/
public class JarContents<C extends ClassNode> {
public class JarContents<C extends ClassNode>
{
private final DataContainer<C> classContents;
private final DataContainer<JarResource> resourceContents;
public JarContents() {
public JarContents()
{
classContents = new ClassNodeContainer<>();
resourceContents = new ResourceContainer();
}
public JarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents) {
public JarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents)
{
this.classContents = classContents == null ? new ClassNodeContainer<>() : classContents;
this.resourceContents = resourceContents == null ? new ResourceContainer() : resourceContents;
}
public final DataContainer<C> getClassContents() {
public final DataContainer<C> getClassContents()
{
return classContents;
}
public final DataContainer<JarResource> getResourceContents() {
public final DataContainer<JarResource> getResourceContents()
{
return resourceContents;
}
public void merge(JarContents<C> contents) {
public void merge(JarContents<C> contents)
{
classContents.addAll(contents.classContents);
resourceContents.addAll(contents.resourceContents);
}
public JarContents<C> add(JarContents<C> contents) {
public JarContents<C> add(JarContents<C> contents)
{
List<C> c1 = classContents;
List<C> c2 = contents.classContents;
@ -78,53 +81,66 @@ public class JarContents<C extends ClassNode> {
return new JarContents<>(new ClassNodeContainer<>(c3), new ResourceContainer(r3));
}
public static class ClassNodeContainer<C extends ClassNode> extends DataContainer<C> {
public static class ClassNodeContainer<C extends ClassNode> extends DataContainer<C>
{
private static final long serialVersionUID = -6169578803641192235L;
private Map<String, C> lastMap = new HashMap<>();
private boolean invalidated;
public ClassNodeContainer() {
public ClassNodeContainer()
{
this(16);
}
public ClassNodeContainer(int cap) {
public ClassNodeContainer(int cap)
{
super(cap);
}
public ClassNodeContainer(Collection<C> data) {
public ClassNodeContainer(Collection<C> data)
{
super(data);
}
@Override
public boolean add(C c) {
public boolean add(C c)
{
invalidated = true;
return super.add(c);
}
@Override
public boolean addAll(Collection<? extends C> c) {
public boolean addAll(Collection<? extends C> c)
{
invalidated = true;
return super.addAll(c);
}
@Override
public boolean remove(Object c) {
public boolean remove(Object c)
{
invalidated = true;
return super.remove(c);
}
@Override
public Map<String, C> namedMap() {
if (invalidated) {
public Map<String, C> namedMap()
{
if (invalidated)
{
invalidated = false;
Map<String, C> nodeMap = new HashMap<>();
Iterator<C> it = iterator();
while (it.hasNext()) {
while (it.hasNext())
{
C cn = it.next();
if (nodeMap.containsKey(cn.name)) {
if (nodeMap.containsKey(cn.name))
{
it.remove();
} else {
}
else
{
nodeMap.put(cn.name, cn);
}
}
@ -134,25 +150,31 @@ public class JarContents<C extends ClassNode> {
}
}
public static class ResourceContainer extends DataContainer<JarResource> {
public static class ResourceContainer extends DataContainer<JarResource>
{
private static final long serialVersionUID = -6169578803641192235L;
public ResourceContainer() {
public ResourceContainer()
{
this(16);
}
public ResourceContainer(int cap) {
public ResourceContainer(int cap)
{
super(cap);
}
public ResourceContainer(List<JarResource> data) {
public ResourceContainer(List<JarResource> data)
{
addAll(data);
}
@Override
public Map<String, JarResource> namedMap() {
public Map<String, JarResource> namedMap()
{
Map<String, JarResource> map = new HashMap<>();
for (JarResource resource : this) {
for (JarResource resource : this)
{
map.put(resource.getName(), resource);
}
return map;

View File

@ -18,31 +18,35 @@
package the.bytecode.club.bytecodeviewer.bootloader.resource.jar.contents;
import java.net.URL;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.bootloader.resource.DataContainer;
import the.bytecode.club.bytecodeviewer.bootloader.resource.jar.JarResource;
import java.net.URL;
/**
* @author Bibl (don't ban me pls)
* @since 19 Jul 2013
*/
public class LocateableJarContents<C extends ClassNode> extends JarContents<C> {
public class LocateableJarContents<C extends ClassNode> extends JarContents<C>
{
private final URL[] jarUrls;
public LocateableJarContents(URL... jarUrls) {
public LocateableJarContents(URL... jarUrls)
{
super();
this.jarUrls = jarUrls;
}
public LocateableJarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents,
URL... jarUrls) {
public LocateableJarContents(DataContainer<C> classContents, DataContainer<JarResource> resourceContents, URL... jarUrls)
{
super(classContents, resourceContents);
this.jarUrls = jarUrls;
}
public URL[] getJarUrls() {
public URL[] getJarUrls()
{
return jarUrls;
}
}

View File

@ -29,14 +29,15 @@ import the.bytecode.club.bytecodeviewer.compilers.impl.SmaliAssembler;
*/
public enum Compiler
{
KRAKATAU_ASSEMBLER(new KrakatauAssembler()),
SMALI_ASSEMBLER(new SmaliAssembler()),
JAVA_COMPILER(new JavaCompiler()),
KRAKATAU_ASSEMBLER(new KrakatauAssembler()), SMALI_ASSEMBLER(new SmaliAssembler()), JAVA_COMPILER(new JavaCompiler()),
;
private final InternalCompiler compiler;
Compiler(InternalCompiler compiler) {this.compiler = compiler;}
Compiler(InternalCompiler compiler)
{
this.compiler = compiler;
}
public InternalCompiler getCompiler()
{

View File

@ -18,11 +18,6 @@
package the.bytecode.club.bytecodeviewer.compilers.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
@ -33,9 +28,9 @@ import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.SleepUtil;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import java.io.*;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* Java Compiler
@ -58,12 +53,14 @@ public class JavaCompiler extends InternalCompiler
tempD.mkdirs();
new File(fileStart2).mkdirs();
if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists()) {
if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists())
{
BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded." + nl + "(C:/Program Files/Java/JDK_xx/bin/javac.exe)");
ExternalResources.getSingleton().selectJavac();
}
if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists()) {
if (Configuration.javac.isEmpty() || !new File(Configuration.javac).exists())
{
BytecodeViewer.showMessage("You need to set Javac!");
return null;
}
@ -72,25 +69,18 @@ public class JavaCompiler extends InternalCompiler
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), cp.getAbsolutePath());
boolean cont = true;
try {
try
{
StringBuilder log = new StringBuilder();
ProcessBuilder pb;
if (Configuration.library.isEmpty()) {
pb = new ProcessBuilder(
Configuration.javac,
"-d", fileStart2,
"-classpath", cp.getAbsolutePath(),
java.getAbsolutePath()
);
} else {
pb = new ProcessBuilder(
Configuration.javac,
"-d", fileStart2,
"-classpath",
cp.getAbsolutePath() + System.getProperty("path.separator") + Configuration.library,
java.getAbsolutePath()
);
if (Configuration.library.isEmpty())
{
pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2, "-classpath", cp.getAbsolutePath(), java.getAbsolutePath());
}
else
{
pb = new ProcessBuilder(Configuration.javac, "-d", fileStart2, "-classpath", cp.getAbsolutePath() + System.getProperty("path.separator") + Configuration.library, java.getAbsolutePath());
}
Process process = pb.start();
@ -112,18 +102,16 @@ public class JavaCompiler extends InternalCompiler
int exitValue = process.waitFor();
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null)
log.append(nl).append(line);
}
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getErrorStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null)
log.append(nl).append(line);
@ -134,7 +122,9 @@ public class JavaCompiler extends InternalCompiler
if (!clazz.exists())
throw new Exception(log.toString());
} catch (Exception e) {
}
catch (Exception e)
{
cont = false;
e.printStackTrace();
}
@ -142,9 +132,12 @@ public class JavaCompiler extends InternalCompiler
cp.delete();
if (cont)
try {
try
{
return org.apache.commons.io.FileUtils.readFileToByteArray(clazz);
} catch (IOException e) {
}
catch (IOException e)
{
e.printStackTrace();
//BytecodeViewer.handleException(e);
}

View File

@ -18,11 +18,6 @@
package the.bytecode.club.bytecodeviewer.compilers.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Objects;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
@ -35,9 +30,13 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Objects;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* Krakatau Java assembler, requires Python 2.7
@ -49,7 +48,7 @@ public class KrakatauAssembler extends InternalCompiler
@Override
public byte[] compile(String contents, String fullyQualifiedName)
{
if(!ExternalResources.getSingleton().hasSetPython2Command())
if (!ExternalResources.getSingleton().hasSetPython2Command())
return null;
File tempD = new File(Constants.tempDirectory + fs + MiscUtils.randomString(32) + fs);
@ -69,34 +68,26 @@ public class KrakatauAssembler extends InternalCompiler
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "assemble.py",
"-out",
tempDirectory.getAbsolutePath(),
tempJ.getAbsolutePath()
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "assemble.py", "-out", tempDirectory.getAbsolutePath(), tempJ.getAbsolutePath()));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null)
log.append(nl).append(line);
}
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getErrorStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null)
log.append(nl).append(line);
@ -106,12 +97,13 @@ public class KrakatauAssembler extends InternalCompiler
log.append(nl).append(nl).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue);
System.err.println(log);
byte[] b = FileUtils.readFileToByteArray(Objects.requireNonNull(
ExternalResources.getSingleton().findFile(tempDirectory, ".class")));
byte[] b = FileUtils.readFileToByteArray(Objects.requireNonNull(ExternalResources.getSingleton().findFile(tempDirectory, ".class")));
tempDirectory.delete();
tempJar.delete();
return b;
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
//BytecodeViewer.handleException(log.toString());
}

View File

@ -18,8 +18,6 @@
package the.bytecode.club.bytecodeviewer.compilers.impl;
import java.io.File;
import java.util.Objects;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -29,6 +27,9 @@ import the.bytecode.club.bytecodeviewer.util.Enjarify;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.ZipUtils;
import java.io.File;
import java.util.Objects;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
@ -54,17 +55,22 @@ public class SmaliAssembler extends InternalCompiler
File tempJar = new File(fileStart + fileNumber + ".jar");
File tempJarFolder = new File(fileStart + fileNumber + "-jar" + fs);
try {
try
{
DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
//BytecodeViewer.handleException(e);
}
try {
com.googlecode.d2j.smali.SmaliCmd.main(tempSmaliFolder.getAbsolutePath(),
"-o", tempDex.getAbsolutePath());
} catch (Exception e) {
try
{
com.googlecode.d2j.smali.SmaliCmd.main(tempSmaliFolder.getAbsolutePath(), "-o", tempDex.getAbsolutePath());
}
catch (Exception e)
{
e.printStackTrace();
//BytecodeViewer.handleException(e);
}
@ -77,14 +83,16 @@ public class SmaliAssembler extends InternalCompiler
System.out.println("Temporary dex: " + tempDex.getAbsolutePath());
try {
try
{
System.out.println("Unzipping to " + tempJarFolder.getAbsolutePath());
ZipUtils.unzipFilesToPath(tempJar.getAbsolutePath(), tempJarFolder.getAbsolutePath());
File outputClass = null;
boolean found = false;
File current = tempJarFolder;
try {
try
{
while (!found)
{
File f = Objects.requireNonNull(current.listFiles())[0];
@ -100,8 +108,13 @@ public class SmaliAssembler extends InternalCompiler
System.out.println("Saved as: " + outputClass.getAbsolutePath());
return FileUtils.readFileToByteArray(outputClass);
} catch (java.lang.NullPointerException ignored) { }
} catch (Exception e) {
}
catch (java.lang.NullPointerException ignored)
{
}
}
catch (Exception e)
{
e.printStackTrace();
//BytecodeViewer.handleException(e);
}

View File

@ -29,20 +29,7 @@ public enum Decompiler
{
//TODO WARNING: do not change the decompiler order, when adding a new decompiler just add it to the end
// enum ordinal is used for settings serialization instead of the enum name
NONE("None", "", null),
PROCYON_DECOMPILER("Procyon Decompiler", "proycon", new ProcyonDecompiler()),
CFR_DECOMPILER("CFR Decompiler", "cfr", new CFRDecompiler()),
FERNFLOWER_DECOMPILER("FernFlower Decompiler", "fernflower", new FernFlowerDecompiler()),
BYTECODE_DISASSEMBLER("Bytecode Disassembler", "bcvbd", new BytecodeDisassembler()),
HEXCODE_VIEWER("Hexcode Viewer", "bcvhex", null),
SMALI_DISASSEMBLER("Smali Disassembler", "smali", new SmaliDisassembler()),
KRAKATAU_DECOMPILER("Krakatau Decompiler", "krakatau", new KrakatauDecompiler()),
KRAKATAU_DISASSEMBLER("Krakatau Disassembler", "krakataud", new KrakatauDisassembler()),
JD_DECOMPILER("JD-GUI Decompiler", "jdgui", new JDGUIDecompiler()),
JADX_DECOMPILER("JADX Decompiler", "jadx", new JADXDecompiler()),
ASM_TEXTIFY_DISASSEMBLER("ASM Disassembler", "asm", new ASMTextifierDisassembler()),
ASMIFIER_DECOMPILER("ASMifier Generator", "asmifier", new ASMifierGenerator()),
JAVAP_DISASSEMBLER("Javap Disassembler", "javap", new JavapDisassembler()),
NONE("None", "", null), PROCYON_DECOMPILER("Procyon Decompiler", "proycon", new ProcyonDecompiler()), CFR_DECOMPILER("CFR Decompiler", "cfr", new CFRDecompiler()), FERNFLOWER_DECOMPILER("FernFlower Decompiler", "fernflower", new FernFlowerDecompiler()), BYTECODE_DISASSEMBLER("Bytecode Disassembler", "bcvbd", new BytecodeDisassembler()), HEXCODE_VIEWER("Hexcode Viewer", "bcvhex", null), SMALI_DISASSEMBLER("Smali Disassembler", "smali", new SmaliDisassembler()), KRAKATAU_DECOMPILER("Krakatau Decompiler", "krakatau", new KrakatauDecompiler()), KRAKATAU_DISASSEMBLER("Krakatau Disassembler", "krakataud", new KrakatauDisassembler()), JD_DECOMPILER("JD-GUI Decompiler", "jdgui", new JDGUIDecompiler()), JADX_DECOMPILER("JADX Decompiler", "jadx", new JADXDecompiler()), ASM_TEXTIFY_DISASSEMBLER("ASM Disassembler", "asm", new ASMTextifierDisassembler()), ASMIFIER_DECOMPILER("ASMifier Generator", "asmifier", new ASMifierGenerator()), JAVAP_DISASSEMBLER("Javap Disassembler", "javap", new JavapDisassembler()),
;
private final String decompilerName;

View File

@ -18,8 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
@ -28,6 +26,9 @@ import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.util.ArrayList;
import java.util.List;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/**
@ -37,24 +38,26 @@ import static the.bytecode.club.bytecodeviewer.Constants.nl;
public class ClassNodeDecompiler
{
public static PrefixedStringBuilder decompile(
PrefixedStringBuilder sb, List<String> decompiledClasses,
ClassNode cn) {
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, List<String> decompiledClasses, ClassNode cn)
{
List<String> unableToDecompile = new ArrayList<>();
decompiledClasses.add(cn.name);
sb.append(getAccessString(cn.access));
sb.append(" ");
sb.append(cn.name);
if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
if (cn.superName != null && !cn.superName.equals("java/lang/Object"))
{
sb.append(" extends ");
sb.append(cn.superName);
}
int amountOfInterfaces = cn.interfaces.size();
if (amountOfInterfaces > 0) {
if (amountOfInterfaces > 0)
{
sb.append(" implements ");
sb.append(cn.interfaces.get(0));
for (int i = 1; i < amountOfInterfaces; i++) {
for (int i = 1; i < amountOfInterfaces; i++)
{
sb.append(", ");
sb.append(cn.interfaces.get(i));
}
@ -65,66 +68,80 @@ public class ClassNodeDecompiler
sb.append("<ClassVersion=" + cn.version + ">");
sb.append(nl);
if (cn.sourceDebug != null) {
if (cn.sourceDebug != null)
{
sb.append(" ");
sb.append("<SourceDebug=" + cn.sourceDebug + ">");
sb.append(nl);
}
if (cn.sourceFile != null) {
if (cn.sourceFile != null)
{
sb.append(" ");
sb.append("<SourceFile=" + cn.sourceFile + ">");
sb.append(nl);
}
if (cn.signature != null) {
if (cn.signature != null)
{
sb.append(" ");
sb.append("<Sig=" + cn.signature + ">");
}
for (FieldNode fn : cn.fields) {
for (FieldNode fn : cn.fields)
{
sb.append(nl);
sb.append(" ");
FieldNodeDecompiler.decompile(sb, fn);
}
if (cn.fields.size() > 0) {
if (cn.fields.size() > 0)
{
sb.append(nl);
}
for (MethodNode mn : cn.methods) {
for (MethodNode mn : cn.methods)
{
sb.append(nl);
MethodNodeDecompiler.decompile(sb, mn, cn);
}
for (InnerClassNode o : cn.innerClasses) {
for (InnerClassNode o : cn.innerClasses)
{
String innerClassName = o.name;
if ((innerClassName != null)
&& !decompiledClasses.contains(innerClassName)) {
if ((innerClassName != null) && !decompiledClasses.contains(innerClassName))
{
decompiledClasses.add(innerClassName);
ClassNode cn1 = BytecodeViewer.blindlySearchForClassNode(innerClassName);
if (cn1 != null) {
if (cn1 != null)
{
sb.appendPrefix(" ");
sb.append(nl + nl);
sb = decompile(sb, decompiledClasses, cn1);
sb.trimPrefix(5);
sb.append(nl);
} else {
}
else
{
unableToDecompile.add(innerClassName);
}
}
}
if (!unableToDecompile.isEmpty()) {
if (!unableToDecompile.isEmpty())
{
sb.append("// The following inner classes couldn't be decompiled: ");
for (String s : unableToDecompile) {
for (String s : unableToDecompile)
{
sb.append(s);
sb.append(" ");
}
sb.append(nl);
}
if (cn.attrs != null) {
if (cn.attrs != null)
{
sb.append(nl);
for (Attribute attr : cn.attrs) {
for (Attribute attr : cn.attrs)
{
//TODO: finish attributes
sb.append(attr.type + ": ");// + attr.content.toString());
}
@ -137,7 +154,8 @@ public class ClassNodeDecompiler
return sb;
}
public static String getAccessString(int access) {
public static String getAccessString(int access)
{
List<String> tokens = new ArrayList<>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
@ -159,13 +177,13 @@ public class ClassNodeDecompiler
tokens.add("enum");
if ((access & Opcodes.ACC_ANNOTATION) != 0)
tokens.add("annotation");
if (!tokens.contains("interface") && !tokens.contains("enum")
&& !tokens.contains("annotation"))
if (!tokens.contains("interface") && !tokens.contains("enum") && !tokens.contains("annotation"))
tokens.add("class");
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
for (int i = 1; i < tokens.size(); i++)
{
sb.append(" ");
sb.append(tokens.get(i));
}

View File

@ -18,21 +18,23 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.FieldNode;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konloch
* @author Bibl
*/
public class FieldNodeDecompiler {
public class FieldNodeDecompiler
{
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb,
FieldNode f) {
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, FieldNode f)
{
String s = getAccessString(f.access);
sb.append(s);
if (s.length() > 0)
@ -40,13 +42,17 @@ public class FieldNodeDecompiler {
sb.append(Type.getType(f.desc).getClassName());
sb.append(" ");
sb.append(f.name);
if (f.value != null) {
if (f.value != null)
{
sb.append(" = ");
if (f.value instanceof String) {
if (f.value instanceof String)
{
sb.append("\"");
sb.append(f.value);
sb.append("\"");
} else {
}
else
{
sb.append(f.value);
sb.append(" (");
sb.append(f.value.getClass().getCanonicalName());
@ -57,7 +63,8 @@ public class FieldNodeDecompiler {
return sb;
}
private static String getAccessString(int access) {
private static String getAccessString(int access)
{
List<String> tokens = new ArrayList<>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
@ -79,7 +86,8 @@ public class FieldNodeDecompiler {
return "";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
for (int i = 1; i < tokens.size(); i++)
{
sb.append(" ");
sb.append(tokens.get(i));
}

View File

@ -20,35 +20,19 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import eu.bibl.banalysis.filter.InstructionFilter;
import eu.bibl.banalysis.filter.OpcodeFilter;
import eu.bibl.banalysis.filter.insn.FieldInstructionFilter;
import eu.bibl.banalysis.filter.insn.IincInstructionFilter;
import eu.bibl.banalysis.filter.insn.InsnInstructionFilter;
import eu.bibl.banalysis.filter.insn.JumpInstructionFilter;
import eu.bibl.banalysis.filter.insn.LdcInstructionFilter;
import eu.bibl.banalysis.filter.insn.MethodInstructionFilter;
import eu.bibl.banalysis.filter.insn.MultiANewArrayInstructionFilter;
import eu.bibl.banalysis.filter.insn.TypeInstructionFilter;
import eu.bibl.banalysis.filter.insn.VarInstructionFilter;
import java.util.Arrays;
import eu.bibl.banalysis.filter.insn.*;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.tree.*;
import java.util.Arrays;
/**
* Pattern filter holder and stepper.
*
* @author Bibl
*/
public class InstructionPattern implements Opcodes {
public class InstructionPattern implements Opcodes
{
/**
* Last instruction-match position pointer
@ -68,7 +52,8 @@ public class InstructionPattern implements Opcodes {
*
* @param insns {@link AbstractInsnNode} pattern array.
*/
public InstructionPattern(AbstractInsnNode[] insns) {
public InstructionPattern(AbstractInsnNode[] insns)
{
filters = translate(insns);
lastMatch = new AbstractInsnNode[insns.length];
}
@ -78,10 +63,12 @@ public class InstructionPattern implements Opcodes {
*
* @param opcodes Opcodes to convert to {@link OpcodeFilter}s.
*/
public InstructionPattern(int[] opcodes) {
public InstructionPattern(int[] opcodes)
{
filters = new InstructionFilter[opcodes.length];
lastMatch = new AbstractInsnNode[opcodes.length];
for (int i = 0; i < opcodes.length; i++) {
for (int i = 0; i < opcodes.length; i++)
{
filters[i] = new OpcodeFilter(opcodes[i]);
}
}
@ -91,7 +78,8 @@ public class InstructionPattern implements Opcodes {
*
* @param filters User-defined {@link InstructionFilter}s.
*/
public InstructionPattern(InstructionFilter[] filters) {
public InstructionPattern(InstructionFilter[] filters)
{
this.filters = filters;
lastMatch = new AbstractInsnNode[filters.length];
}
@ -103,18 +91,23 @@ public class InstructionPattern implements Opcodes {
* @param ain {@link AbstractInsnNode} to check.
* @return True if this instruction successfully completed the pattern.
*/
public boolean accept(AbstractInsnNode ain) {
public boolean accept(AbstractInsnNode ain)
{
if (pointer >= filters.length)
reset();
InstructionFilter filter = filters[pointer];
if (filter.accept(ain)) {
if (filter.accept(ain))
{
lastMatch[pointer] = ain;
if (pointer >= (filters.length - 1)) {
if (pointer >= (filters.length - 1))
{
return true;
}
pointer++;
} else {
}
else
{
reset();
}
return false;
@ -124,14 +117,16 @@ public class InstructionPattern implements Opcodes {
* @return Last pattern sequence match equivilent from the inputted
* {@link AbstractInsnNode}s.
*/
public AbstractInsnNode[] getLastMatch() {
public AbstractInsnNode[] getLastMatch()
{
return lastMatch;
}
/**
* Resets the instruction pointer and clears the last match cache data.
*/
public void resetMatch() {
public void resetMatch()
{
reset();
AbstractInsnNode[] match = lastMatch;
lastMatch = new AbstractInsnNode[match.length];
@ -140,7 +135,8 @@ public class InstructionPattern implements Opcodes {
/**
* Sets the current instruction pointer to 0 (start of pattern).
*/
public void reset() {
public void reset()
{
pointer = 0;
}
@ -151,9 +147,11 @@ public class InstructionPattern implements Opcodes {
* @param ains {@link AbstractInsnNode}s to convert.
* @return Array of {@link InstructionFilter}s.
*/
public static InstructionFilter[] translate(AbstractInsnNode[] ains) {
public static InstructionFilter[] translate(AbstractInsnNode[] ains)
{
InstructionFilter[] filters = new InstructionFilter[ains.length];
for (int i = 0; i < ains.length; i++) {
for (int i = 0; i < ains.length; i++)
{
filters[i] = translate(ains[i]);
}
return filters;
@ -166,52 +164,64 @@ public class InstructionPattern implements Opcodes {
* @param ain Instruction to convert.
* @return A filter an an equivilent to the inputted instruction.
*/
public static InstructionFilter translate(AbstractInsnNode ain) {
if (ain instanceof LdcInsnNode) {
public static InstructionFilter translate(AbstractInsnNode ain)
{
if (ain instanceof LdcInsnNode)
{
return new LdcInstructionFilter(((LdcInsnNode) ain).cst);
} else if (ain instanceof TypeInsnNode) {
return new TypeInstructionFilter(ain.getOpcode(),
((TypeInsnNode) ain).desc);
} else if (ain instanceof FieldInsnNode) {
return new FieldInstructionFilter(ain.getOpcode(),
((FieldInsnNode) ain).owner, ((FieldInsnNode) ain).name,
((FieldInsnNode) ain).desc);
} else if (ain instanceof MethodInsnNode) {
return new MethodInstructionFilter(ain.getOpcode(),
((MethodInsnNode) ain).owner, ((MethodInsnNode) ain).name,
((MethodInsnNode) ain).desc);
} else if (ain instanceof VarInsnNode) {
return new VarInstructionFilter(ain.getOpcode(),
((VarInsnNode) ain).var);
} else if (ain instanceof InsnNode) {
}
else if (ain instanceof TypeInsnNode)
{
return new TypeInstructionFilter(ain.getOpcode(), ((TypeInsnNode) ain).desc);
}
else if (ain instanceof FieldInsnNode)
{
return new FieldInstructionFilter(ain.getOpcode(), ((FieldInsnNode) ain).owner, ((FieldInsnNode) ain).name, ((FieldInsnNode) ain).desc);
}
else if (ain instanceof MethodInsnNode)
{
return new MethodInstructionFilter(ain.getOpcode(), ((MethodInsnNode) ain).owner, ((MethodInsnNode) ain).name, ((MethodInsnNode) ain).desc);
}
else if (ain instanceof VarInsnNode)
{
return new VarInstructionFilter(ain.getOpcode(), ((VarInsnNode) ain).var);
}
else if (ain instanceof InsnNode)
{
return new InsnInstructionFilter(ain.getOpcode());
} else if (ain instanceof IincInsnNode) {
return new IincInstructionFilter(((IincInsnNode) ain).incr,
((IincInsnNode) ain).var);
} else if (ain instanceof JumpInsnNode) {
}
else if (ain instanceof IincInsnNode)
{
return new IincInstructionFilter(((IincInsnNode) ain).incr, ((IincInsnNode) ain).var);
}
else if (ain instanceof JumpInsnNode)
{
return new JumpInstructionFilter(ain.getOpcode());
} else if (ain instanceof LabelNode) {
}
else if (ain instanceof LabelNode)
{
return InstructionFilter.ACCEPT_ALL; // TODO: Cache labels and
// check. // TODO: That's a
// fucking stupid idea.
} else if (ain instanceof MultiANewArrayInsnNode) {
return new MultiANewArrayInstructionFilter(
((MultiANewArrayInsnNode) ain).desc,
((MultiANewArrayInsnNode) ain).dims);
} else {
}
else if (ain instanceof MultiANewArrayInsnNode)
{
return new MultiANewArrayInstructionFilter(((MultiANewArrayInsnNode) ain).desc, ((MultiANewArrayInsnNode) ain).dims);
}
else
{
return InstructionFilter.ACCEPT_ALL;
}
}
public static void main(String[] args) {
AbstractInsnNode[] ains = new AbstractInsnNode[]{
new LdcInsnNode("ldc"), new VarInsnNode(ASTORE, 0),
new LdcInsnNode("ldc")};
InstructionPattern pattern = new InstructionPattern(
new AbstractInsnNode[]{new LdcInsnNode("ldc"),
new VarInsnNode(-1, -1)});
for (AbstractInsnNode ain : ains) {
if (pattern.accept(ain)) {
public static void main(String[] args)
{
AbstractInsnNode[] ains = new AbstractInsnNode[]{new LdcInsnNode("ldc"), new VarInsnNode(ASTORE, 0), new LdcInsnNode("ldc")};
InstructionPattern pattern = new InstructionPattern(new AbstractInsnNode[]{new LdcInsnNode("ldc"), new VarInsnNode(-1, -1)});
for (AbstractInsnNode ain : ains)
{
if (pattern.accept(ain))
{
System.out.println(Arrays.toString(pattern.getLastMatch()));
}
}

View File

@ -38,7 +38,8 @@ import java.util.stream.Collectors;
* @author Bibl
* @author GraxCode
*/
public class InstructionPrinter implements Opcodes {
public class InstructionPrinter implements Opcodes
{
/**
* The MethodNode to print
@ -54,7 +55,8 @@ public class InstructionPrinter implements Opcodes {
private boolean firstLabel = false;
private final List<String> info = new ArrayList<>();
public InstructionPrinter(MethodNode m, TypeAndName[] args) {
public InstructionPrinter(MethodNode m, TypeAndName[] args)
{
this.args = args;
mNode = m;
labels = new HashMap<>();
@ -64,24 +66,30 @@ public class InstructionPrinter implements Opcodes {
match = false;
}
public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args) {
public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args)
{
this(m, args);
InstructionSearcher searcher = new InstructionSearcher(m.instructions, pattern);
match = searcher.search();
if (match) {
for (AbstractInsnNode[] ains : searcher.getMatches()) {
if (match)
{
for (AbstractInsnNode[] ains : searcher.getMatches())
{
Collections.addAll(matchedInsns, ains);
}
}
}
private void precalculateLabelIndexes(MethodNode m) {
if(m == null)
private void precalculateLabelIndexes(MethodNode m)
{
if (m == null)
return;
int lIdx = 0;
for (AbstractInsnNode ain : m.instructions) {
if (ain.getType() == AbstractInsnNode.LABEL) {
for (AbstractInsnNode ain : m.instructions)
{
if (ain.getType() == AbstractInsnNode.LABEL)
{
labels.put((LabelNode) ain, lIdx++);
}
}
@ -92,90 +100,143 @@ public class InstructionPrinter implements Opcodes {
*
* @return The print as an ArrayList
*/
public List<String> createPrint() {
public List<String> createPrint()
{
firstLabel = false;
info.clear();
for (AbstractInsnNode ain : mNode.instructions) {
for (AbstractInsnNode ain : mNode.instructions)
{
String line = printInstruction(ain);
if (!line.isEmpty()) {
if (match) if (matchedInsns.contains(ain)) line = " -> " + line;
if (!line.isEmpty())
{
if (match)
if (matchedInsns.contains(ain))
line = " -> " + line;
info.add(line);
}
}
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) info.add("}");
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
info.add("}");
return info;
}
public String printInstruction(AbstractInsnNode ain) {
public String printInstruction(AbstractInsnNode ain)
{
String line = "";
if (ain instanceof VarInsnNode) {
if (ain instanceof VarInsnNode)
{
line = printVarInsnNode((VarInsnNode) ain);
} else if (ain instanceof IntInsnNode) {
}
else if (ain instanceof IntInsnNode)
{
line = printIntInsnNode((IntInsnNode) ain);
} else if (ain instanceof FieldInsnNode) {
}
else if (ain instanceof FieldInsnNode)
{
line = printFieldInsnNode((FieldInsnNode) ain);
} else if (ain instanceof MethodInsnNode) {
}
else if (ain instanceof MethodInsnNode)
{
line = printMethodInsnNode((MethodInsnNode) ain);
} else if (ain instanceof LdcInsnNode) {
}
else if (ain instanceof LdcInsnNode)
{
line = printLdcInsnNode((LdcInsnNode) ain);
} else if (ain instanceof InsnNode) {
}
else if (ain instanceof InsnNode)
{
line = printInsnNode((InsnNode) ain);
} else if (ain instanceof JumpInsnNode) {
}
else if (ain instanceof JumpInsnNode)
{
line = printJumpInsnNode((JumpInsnNode) ain);
} else if (ain instanceof LineNumberNode) {
}
else if (ain instanceof LineNumberNode)
{
line = printLineNumberNode((LineNumberNode) ain);
} else if (ain instanceof LabelNode) {
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) info.add("}");
}
else if (ain instanceof LabelNode)
{
if (firstLabel && BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
info.add("}");
LabelNode label = (LabelNode) ain;
if (mNode.tryCatchBlocks != null) {
if (mNode.tryCatchBlocks != null)
{
List<TryCatchBlockNode> tcbs = mNode.tryCatchBlocks;
String starting = tcbs.stream().filter(tcb -> tcb.start == label).map(tcb -> "start TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String ending = tcbs.stream().filter(tcb -> tcb.end == label).map(tcb -> "end TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
String handlers = tcbs.stream().filter(tcb -> tcb.handler == label).map(tcb -> "handle TCB" + tcbs.indexOf(tcb)).collect(Collectors.joining(", "));
if (!ending.isEmpty()) info.add("// " + ending);
if (!starting.isEmpty()) info.add("// " + starting);
if (!handlers.isEmpty()) info.add("// " + handlers);
if (!ending.isEmpty())
info.add("// " + ending);
if (!starting.isEmpty())
info.add("// " + starting);
if (!handlers.isEmpty())
info.add("// " + handlers);
}
line = printLabelNode((LabelNode) ain);
if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected()) {
if (!firstLabel) firstLabel = true;
if (BytecodeViewer.viewer.appendBracketsToLabels.isSelected())
{
if (!firstLabel)
firstLabel = true;
line += " {";
}
} else if (ain instanceof TypeInsnNode) {
}
else if (ain instanceof TypeInsnNode)
{
line = printTypeInsnNode((TypeInsnNode) ain);
} else if (ain instanceof FrameNode) {
}
else if (ain instanceof FrameNode)
{
line = printFrameNode((FrameNode) ain);
} else if (ain instanceof IincInsnNode) {
}
else if (ain instanceof IincInsnNode)
{
line = printIincInsnNode((IincInsnNode) ain);
} else if (ain instanceof TableSwitchInsnNode) {
}
else if (ain instanceof TableSwitchInsnNode)
{
line = printTableSwitchInsnNode((TableSwitchInsnNode) ain);
} else if (ain instanceof LookupSwitchInsnNode) {
}
else if (ain instanceof LookupSwitchInsnNode)
{
line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain);
} else if (ain instanceof InvokeDynamicInsnNode) {
}
else if (ain instanceof InvokeDynamicInsnNode)
{
line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain);
} else if (ain instanceof MultiANewArrayInsnNode) {
}
else if (ain instanceof MultiANewArrayInsnNode)
{
line = printMultiANewArrayInsNode((MultiANewArrayInsnNode) ain);
} else {
}
else
{
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain;
}
return line;
}
protected String printVarInsnNode(VarInsnNode vin) {
protected String printVarInsnNode(VarInsnNode vin)
{
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(vin.getOpcode()));
sb.append(" ");
sb.append(vin.var);
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
if (vin.var == 0 && !Modifier.isStatic(mNode.access)) {
if (BytecodeViewer.viewer.debugHelpers.isSelected())
{
if (vin.var == 0 && !Modifier.isStatic(mNode.access))
{
sb.append(" // reference to self");
} else {
}
else
{
final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1);
if (refIndex >= 0 && refIndex < args.length - 1) {
if (refIndex >= 0 && refIndex < args.length - 1)
{
sb.append(" // reference to ").append(args[refIndex].name);
}
}
@ -184,99 +245,129 @@ public class InstructionPrinter implements Opcodes {
return sb.toString();
}
protected String printIntInsnNode(IntInsnNode iin) {
protected String printIntInsnNode(IntInsnNode iin)
{
return nameOpcode(iin.getOpcode()) + " " + iin.operand;
}
protected String printFieldInsnNode(FieldInsnNode fin) {
protected String printFieldInsnNode(FieldInsnNode fin)
{
String desc = Type.getType(fin.desc).getClassName();
if (desc.equals("null")) desc = fin.desc;
if (desc.equals("null"))
desc = fin.desc;
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name + ":" + desc;
}
protected String printMethodInsnNode(MethodInsnNode min) {
protected String printMethodInsnNode(MethodInsnNode min)
{
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(min.getOpcode())).append(" ").append(min.owner).append(".").append(min.name);
String desc = min.desc;
try {
if (Type.getType(min.desc) != null) desc = Type.getType(min.desc).getClassName();
} catch (java.lang.AssertionError e) {
try
{
if (Type.getType(min.desc) != null)
desc = Type.getType(min.desc).getClassName();
}
catch (java.lang.AssertionError e)
{
//e.printStackTrace();
} catch (java.lang.Exception e) {
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
if (desc == null || desc.equals("null")) desc = min.desc;
if (desc == null || desc.equals("null"))
desc = min.desc;
sb.append(desc);
return sb.toString();
}
protected String printLdcInsnNode(LdcInsnNode ldc) {
protected String printLdcInsnNode(LdcInsnNode ldc)
{
if (ldc.cst instanceof String)
return nameOpcode(ldc.getOpcode()) + " \"" + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" + ldc.cst.getClass().getCanonicalName() + ")";
return nameOpcode(ldc.getOpcode()) + " " + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" + ldc.cst.getClass().getCanonicalName() + ")";
}
protected String printInsnNode(InsnNode in) {
protected String printInsnNode(InsnNode in)
{
return nameOpcode(in.getOpcode());
}
protected String printJumpInsnNode(JumpInsnNode jin) {
protected String printJumpInsnNode(JumpInsnNode jin)
{
return nameOpcode(jin.getOpcode()) + " L" + resolveLabel(jin.label);
}
protected String printLineNumberNode(LineNumberNode lnn) {
if(BytecodeViewer.viewer.printLineNumbers.isSelected())
protected String printLineNumberNode(LineNumberNode lnn)
{
if (BytecodeViewer.viewer.printLineNumbers.isSelected())
return "// line " + lnn.line;
return "";
}
protected String printLabelNode(LabelNode label) {
protected String printLabelNode(LabelNode label)
{
return "L" + resolveLabel(label);
}
protected String printTypeInsnNode(TypeInsnNode tin) {
try {
protected String printTypeInsnNode(TypeInsnNode tin)
{
try
{
String desc = tin.desc;
try {
if (Type.getType(tin.desc) != null) desc = Type.getType(tin.desc).getClassName();
try
{
if (Type.getType(tin.desc) != null)
desc = Type.getType(tin.desc).getClassName();
if (desc.equals("null")) desc = tin.desc;
} catch (java.lang.ArrayIndexOutOfBoundsException ignored) {
if (desc.equals("null"))
desc = tin.desc;
}
catch (java.lang.ArrayIndexOutOfBoundsException ignored)
{
}
return nameOpcode(tin.getOpcode()) + " " + desc;
} catch (Exception e) {
}
catch (Exception e)
{
return nameOpcode(tin.getOpcode()) + " " + tin.desc;
}
}
protected String printIincInsnNode(IincInsnNode iin) {
protected String printIincInsnNode(IincInsnNode iin)
{
return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr;
}
protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) {
protected String printTableSwitchInsnNode(TableSwitchInsnNode tin)
{
StringBuilder line = new StringBuilder(nameOpcode(tin.getOpcode()) + " \n");
List<?> labels = tin.labels;
int count = 0;
for (int i = tin.min; i < tin.max + 1; i++) {
for (int i = tin.min; i < tin.max + 1; i++)
{
line.append(" val: ").append(i).append(" -> ").append("L").append(resolveLabel((LabelNode) labels.get(count++))).append("\n");
}
line.append(" default" + " -> L").append(resolveLabel(tin.dflt));
return line.toString();
}
protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) {
protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin)
{
StringBuilder line = new StringBuilder(nameOpcode(lin.getOpcode()) + ": \n");
List<?> keys = lin.keys;
List<?> labels = lin.labels;
for (int i = 0; i < keys.size(); i++) {
for (int i = 0; i < keys.size(); i++)
{
int key = (Integer) keys.get(i);
LabelNode label = (LabelNode) labels.get(i);
line.append(" val: ").append(key).append(" -> ").append("L").append(resolveLabel(label)).append("\n");
@ -286,12 +377,15 @@ public class InstructionPrinter implements Opcodes {
return line.toString();
}
protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) {
protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin)
{
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(idin.getOpcode())).append(" ").append(idin.bsm.getOwner()).append('.').append(idin.bsm.getName()).append(idin.bsm.getDesc()).append(" : ").append(idin.name).append(idin.desc);
if (idin.bsmArgs != null) {
for (Object o : idin.bsmArgs) {
if (idin.bsmArgs != null)
{
for (Object o : idin.bsmArgs)
{
sb.append(" ");
sb.append(o.toString());
}
@ -300,27 +394,35 @@ public class InstructionPrinter implements Opcodes {
return sb.toString();
}
protected String printMultiANewArrayInsNode(MultiANewArrayInsnNode mana) {
protected String printMultiANewArrayInsNode(MultiANewArrayInsnNode mana)
{
return nameOpcode(mana.getOpcode()) + " " + mana.dims + " : " + mana.desc;
}
private String printFrameNode(FrameNode frame) {
private String printFrameNode(FrameNode frame)
{
StringBuilder sb = new StringBuilder();
sb.append(nameFrameType(frame.type)).append(" ");
sb.append("(Locals");
if (frame.local != null && !frame.local.isEmpty()) {
if (frame.local != null && !frame.local.isEmpty())
{
sb.append("[").append(frame.local.size()).append("]: ");
sb.append(frame.local.stream().map(this::printFrameObject).collect(Collectors.joining(", ")));
} else {
}
else
{
sb.append("[0]");
}
sb.append(") ");
sb.append("(Stack");
if (frame.stack != null && !frame.stack.isEmpty()) {
if (frame.stack != null && !frame.stack.isEmpty())
{
sb.append("[").append(frame.stack.size()).append("]: ");
sb.append(frame.stack.stream().map(this::printFrameObject).collect(Collectors.joining(", ")));
} else {
}
else
{
sb.append("[0]");
}
sb.append(") ");
@ -328,10 +430,14 @@ public class InstructionPrinter implements Opcodes {
return sb.toString();
}
private String printFrameObject(Object obj) {
if (obj instanceof LabelNode) return "label [L" + resolveLabel((LabelNode) obj) + "]";
if (obj instanceof Integer) {
switch ((int) obj) {
private String printFrameObject(Object obj)
{
if (obj instanceof LabelNode)
return "label [L" + resolveLabel((LabelNode) obj) + "]";
if (obj instanceof Integer)
{
switch ((int) obj)
{
case 0:
return "top";
case 1:
@ -350,12 +456,15 @@ public class InstructionPrinter implements Opcodes {
return "unknown";
}
}
if (obj instanceof String) return obj.toString();
if (obj instanceof String)
return obj.toString();
return "unknown [" + obj.toString() + "]";
}
private String nameFrameType(int type) {
switch (type) {
private String nameFrameType(int type)
{
switch (type)
{
case F_NEW:
return " f_new";
case F_FULL:
@ -373,14 +482,19 @@ public class InstructionPrinter implements Opcodes {
}
}
protected String nameOpcode(int opcode) {
protected String nameOpcode(int opcode)
{
return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();
}
protected int resolveLabel(LabelNode label) {
if (labels.containsKey(label)) {
protected int resolveLabel(LabelNode label)
{
if (labels.containsKey(label))
{
return labels.get(label);
} else {
}
else
{
/*int newLabelIndex = labels.size() + 1;
labels.put(label, newLabelIndex);
return newLabelIndex;*/
@ -388,13 +502,18 @@ public class InstructionPrinter implements Opcodes {
}
}
public static void saveTo(File file, InstructionPrinter printer) {
try (FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw)) {
for (String s : printer.createPrint()) {
public static void saveTo(File file, InstructionPrinter printer)
{
try (FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw))
{
for (String s : printer.createPrint())
{
bw.write(s);
bw.newLine();
}
} catch (IOException e) {
}
catch (IOException e)
{
BytecodeViewer.handleException(e);
}
}

View File

@ -18,44 +18,52 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LineNumberNode;
import java.util.ArrayList;
import java.util.List;
/**
* @author Bibl
*/
public class InstructionSearcher implements Opcodes {
public class InstructionSearcher implements Opcodes
{
protected InsnList insns;
protected InstructionPattern pattern;
protected List<AbstractInsnNode[]> matches;
public InstructionSearcher(InsnList insns, int[] opcodes) {
public InstructionSearcher(InsnList insns, int[] opcodes)
{
this(insns, new InstructionPattern(opcodes));
}
public InstructionSearcher(InsnList insns, AbstractInsnNode[] ains) {
public InstructionSearcher(InsnList insns, AbstractInsnNode[] ains)
{
this(insns, new InstructionPattern(ains));
}
public InstructionSearcher(InsnList insns, InstructionPattern pattern) {
public InstructionSearcher(InsnList insns, InstructionPattern pattern)
{
this.insns = insns;
this.pattern = pattern;
matches = new ArrayList<>();
}
public boolean search() {
for (AbstractInsnNode ain : insns.toArray()) {
public boolean search()
{
for (AbstractInsnNode ain : insns.toArray())
{
if (ain instanceof LineNumberNode || ain instanceof FrameNode)
continue;
if (pattern.accept(ain)) {
if (pattern.accept(ain))
{
matches.add(pattern.getLastMatch());
pattern.resetMatch();
}
@ -63,11 +71,13 @@ public class InstructionSearcher implements Opcodes {
return size() != 0;
}
public List<AbstractInsnNode[]> getMatches() {
public List<AbstractInsnNode[]> getMatches()
{
return matches;
}
public int size() {
public int size()
{
return matches.size();
}
}

View File

@ -18,17 +18,14 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.*;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
@ -37,14 +34,18 @@ import static the.bytecode.club.bytecodeviewer.Constants.nl;
* @author Bibl
*/
public class MethodNodeDecompiler {
public class MethodNodeDecompiler
{
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb,
MethodNode m, ClassNode cn) {
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNode m, ClassNode cn)
{
String class_;
if (cn.name.contains("/")) {
if (cn.name.contains("/"))
{
class_ = cn.name.substring(cn.name.lastIndexOf("/") + 1);
} else {
}
else
{
class_ = cn.name;
}
@ -54,9 +55,12 @@ public class MethodNodeDecompiler {
if (s.length() > 0)
sb.append(" ");
if (m.name.equals("<init>")) {
if (m.name.equals("<init>"))
{
sb.append(class_);
} else if (!m.name.equals("<clinit>")) {
}
else if (!m.name.equals("<clinit>"))
{
Type returnType = Type.getReturnType(m.desc);
sb.append(returnType.getClassName());
sb.append(" ");
@ -65,13 +69,15 @@ public class MethodNodeDecompiler {
TypeAndName[] args = new TypeAndName[0];
if (!m.name.equals("<clinit>")) {
if (!m.name.equals("<clinit>"))
{
sb.append("(");
final Type[] argTypes = Type.getArgumentTypes(m.desc);
args = new TypeAndName[argTypes.length];
for (int i = 0; i < argTypes.length; i++) {
for (int i = 0; i < argTypes.length; i++)
{
final Type type = argTypes[i];
final TypeAndName tan = new TypeAndName();
@ -82,33 +88,38 @@ public class MethodNodeDecompiler {
args[i] = tan;
sb.append(type.getClassName() + " " + argName
+ (i < argTypes.length - 1 ? ", " : ""));
sb.append(type.getClassName() + " " + argName + (i < argTypes.length - 1 ? ", " : ""));
}
sb.append(")");
}
int amountOfThrows = m.exceptions.size();
if (amountOfThrows > 0) {
if (amountOfThrows > 0)
{
sb.append(" throws ");
sb.append(m.exceptions.get(0));// exceptions is list<string>
for (int i = 1; i < amountOfThrows; i++) {
for (int i = 1; i < amountOfThrows; i++)
{
sb.append(", ");
sb.append(m.exceptions.get(i));
}
}
if (s.contains("abstract")) {
if (s.contains("abstract"))
{
sb.append(" {}");
sb.append(" //");
sb.append(m.desc);
sb.append(nl);
} else {
}
else
{
sb.append(" {");
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
if (BytecodeViewer.viewer.debugHelpers.isSelected())
{
if (m.name.equals("<clinit>"))
sb.append(" // <clinit>");
else if (m.name.equals("<init>"))
@ -120,12 +131,14 @@ public class MethodNodeDecompiler {
sb.append(nl);
if (m.signature != null) {
if (m.signature != null)
{
sb.append(" <sig:").append(m.signature).append(">");
sb.append(nl);
}
if (m.annotationDefault != null) {
if (m.annotationDefault != null)
{
sb.append(m.annotationDefault);
sb.append(nl);
}
@ -134,19 +147,16 @@ public class MethodNodeDecompiler {
addAttrList(m.attrs, "attr", sb, insnPrinter);
addAttrList(m.invisibleAnnotations, "invisAnno", sb, insnPrinter);
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb,
insnPrinter);
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
insnPrinter);
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb, insnPrinter);
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb, insnPrinter);
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
sb, insnPrinter);
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb,
insnPrinter);
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno", sb, insnPrinter);
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb, insnPrinter);
List<TryCatchBlockNode> tryCatchBlocks = m.tryCatchBlocks;
for (int i = 0; i < tryCatchBlocks.size(); i++) {
for (int i = 0; i < tryCatchBlocks.size(); i++)
{
TryCatchBlockNode o = tryCatchBlocks.get(i);
sb.append(" ");
sb.append("TryCatch").append(i).append(": L");
@ -162,7 +172,8 @@ public class MethodNodeDecompiler {
sb.append("Type is null.");
sb.append(nl);
}
for (String insn : insnPrinter.createPrint()) {
for (String insn : insnPrinter.createPrint())
{
sb.append(" ");
sb.append(insn);
sb.append(nl);
@ -172,12 +183,14 @@ public class MethodNodeDecompiler {
return sb;
}
private static void addAttrList(List<?> list, String name,
PrefixedStringBuilder sb, InstructionPrinter insnPrinter) {
private static void addAttrList(List<?> list, String name, PrefixedStringBuilder sb, InstructionPrinter insnPrinter)
{
if (list == null)
return;
if (list.size() > 0) {
for (Object o : list) {
if (list.size() > 0)
{
for (Object o : list)
{
sb.append(" <");
sb.append(name);
sb.append(":");
@ -189,22 +202,26 @@ public class MethodNodeDecompiler {
}
}
private static String printAttr(Object o, InstructionPrinter insnPrinter) {
if (o instanceof LocalVariableNode) {
private static String printAttr(Object o, InstructionPrinter insnPrinter)
{
if (o instanceof LocalVariableNode)
{
LocalVariableNode lvn = (LocalVariableNode) o;
return "index=" + lvn.index + " , name=" + lvn.name + " , desc="
+ lvn.desc + ", sig=" + lvn.signature + ", start=L"
+ insnPrinter.resolveLabel(lvn.start) + ", end=L"
+ insnPrinter.resolveLabel(lvn.end);
} else if (o instanceof AnnotationNode) {
return "index=" + lvn.index + " , name=" + lvn.name + " , desc=" + lvn.desc + ", sig=" + lvn.signature + ", start=L" + insnPrinter.resolveLabel(lvn.start) + ", end=L" + insnPrinter.resolveLabel(lvn.end);
}
else if (o instanceof AnnotationNode)
{
AnnotationNode an = (AnnotationNode) o;
StringBuilder sb = new StringBuilder();
sb.append("desc = ");
sb.append(an.desc);
sb.append(" , values = ");
if (an.values != null) {
if (an.values != null)
{
sb.append(Arrays.toString(an.values.toArray()));
} else {
}
else
{
sb.append("[]");
}
return sb.toString();
@ -214,7 +231,8 @@ public class MethodNodeDecompiler {
return o.toString();
}
private static String getAccessString(int access) {
private static String getAccessString(int access)
{
// public, protected, private, abstract, static,
// final, synchronized, native & strictfp are permitted
List<String> tokens = new ArrayList<>();
@ -246,7 +264,8 @@ public class MethodNodeDecompiler {
return "";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
for (int i = 1; i < tokens.size(); i++)
{
sb.append(" ");
sb.append(tokens.get(i));
}

View File

@ -22,16 +22,19 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
* @author Bibl
*/
public class PrefixedStringBuilder {
public class PrefixedStringBuilder
{
protected StringBuilder sb;
protected String prefix;
public PrefixedStringBuilder() {
public PrefixedStringBuilder()
{
sb = new StringBuilder();
}
public PrefixedStringBuilder append(String s) {
public PrefixedStringBuilder append(String s)
{
sb.append(s);
if (s.contains("\n") && (prefix != null) && (prefix.length() > 0))// insert
// the
@ -45,15 +48,18 @@ public class PrefixedStringBuilder {
return this;
}
public PrefixedStringBuilder append(Object o) {
public PrefixedStringBuilder append(Object o)
{
return append(o.toString());
}
public void setPrefix(String prefix) {
public void setPrefix(String prefix)
{
this.prefix = prefix;
}
public void trimPrefix(int amount) {
public void trimPrefix(int amount)
{
if (prefix == null)
return;
if (prefix.length() < amount)
@ -61,18 +67,21 @@ public class PrefixedStringBuilder {
prefix = prefix.substring(0, prefix.length() - amount);
}
public void appendPrefix(String s) {
public void appendPrefix(String s)
{
if (prefix == null)
prefix = "";
prefix += s;
}
public String getPrefix() {
public String getPrefix()
{
return prefix;
}
@Override
public String toString() {
public String toString()
{
return sb.toString();
}
}

View File

@ -27,7 +27,8 @@ import org.objectweb.asm.Type;
* @author Waterwolf
* @since 10/02/2011
*/
public class TypeAndName {
public class TypeAndName
{
public Type type = null;
public String name = null;
}

View File

@ -18,13 +18,14 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* Objectweb ASM Textifier output
*
@ -33,14 +34,16 @@ import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
public class ASMTextifierDisassembler extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b)
{
StringWriter writer = new StringWriter();
cn.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(writer)));
return writer.toString();
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -20,7 +20,6 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
@ -35,13 +34,15 @@ import java.io.StringWriter;
public class ASMifierGenerator extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b)
{
StringWriter writer = new StringWriter();
cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer)));
return writer.toString();
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -18,12 +18,13 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.util.ArrayList;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.PrefixedStringBuilder;
import java.util.ArrayList;
/**
* @author Konloch
* @since 7/3/2021
@ -31,12 +32,13 @@ import the.bytecode.club.bytecodeviewer.decompilers.bytecode.PrefixedStringBuild
public class BytecodeDisassembler extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(),
new ArrayList<>(), cn).toString();
public String decompileClassNode(ClassNode cn, byte[] b)
{
return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(), new ArrayList<>(), cn).toString();
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -18,27 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.IOUtils;
import org.benf.cfr.reader.api.CfrDriver;
import org.benf.cfr.reader.api.ClassFileSource;
@ -55,6 +34,15 @@ import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.CFR;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
@ -65,17 +53,21 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERR
* @author GraxCode
* Taken mostly out of Threadtear.
*/
public class CFRDecompiler extends InternalDecompiler {
public class CFRDecompiler extends InternalDecompiler
{
private static final String CLASS_SUFFIX = ".class";
@Override
public String decompileClassNode(ClassNode cn, byte[] content) {
public String decompileClassNode(ClassNode cn, byte[] content)
{
return decompile(cn, cn.name, content);
}
private String decompile(ClassNode cn, String name, byte[] content) {
try {
private String decompile(ClassNode cn, String name, byte[] content)
{
try
{
String classPath = name + (name.endsWith(CLASS_SUFFIX) ? "" : CLASS_SUFFIX);
StringBuilder builder = new StringBuilder();
@ -83,79 +75,93 @@ public class CFRDecompiler extends InternalDecompiler {
Options options = generateOptions();
ClassFileSource source = new BCVDataSource(options, cn, classPath, content);
CfrDriver driver = new CfrDriver.Builder()
.withClassFileSource(source)
.withBuiltOptions(options)
.withOutputSink(new BCVOutputSinkFactory(dumpDecompiled))
.build();
CfrDriver driver = new CfrDriver.Builder().withClassFileSource(source).withBuiltOptions(options).withOutputSink(new BCVOutputSinkFactory(dumpDecompiled)).build();
driver.analyse(Collections.singletonList(name));
return builder.toString();
} catch (Throwable t) {
}
catch (Throwable t)
{
t.printStackTrace();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + sw;
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + sw;
}
}
@Override
public void decompileToZip(String sourceJar, String outJar) {
try (JarFile jfile = new JarFile(new File(sourceJar));
FileOutputStream dest = new FileOutputStream(outJar);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest)) {
public void decompileToZip(String sourceJar, String outJar)
{
try (JarFile jfile = new JarFile(new File(sourceJar)); FileOutputStream dest = new FileOutputStream(outJar); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest))
{
byte[] data = new byte[1024];
Enumeration<JarEntry> ent = jfile.entries();
Set<JarEntry> history = new HashSet<>();
while (ent.hasMoreElements()) {
while (ent.hasMoreElements())
{
JarEntry entry = ent.nextElement();
if (entry.getName().endsWith(CLASS_SUFFIX)) {
if (entry.getName().endsWith(CLASS_SUFFIX))
{
JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java"));
if (history.add(etn)) {
if (history.add(etn))
{
out.putNextEntry(etn);
try {
IOUtils.write(decompile(null, entry.getName(),
IOUtils.toByteArray(jfile.getInputStream(entry))),
out, StandardCharsets.UTF_8);
} finally {
try
{
IOUtils.write(decompile(null, entry.getName(), IOUtils.toByteArray(jfile.getInputStream(entry))), out, StandardCharsets.UTF_8);
}
finally
{
out.closeEntry();
}
}
} else {
try {
}
else
{
try
{
JarEntry etn = new JarEntry(entry.getName());
if (history.add(etn)) continue;
if (history.add(etn))
continue;
history.add(etn);
out.putNextEntry(etn);
try (InputStream in = jfile.getInputStream(entry)) {
if (in != null) {
try (InputStream in = jfile.getInputStream(entry))
{
if (in != null)
{
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
while ((count = in.read(data, 0, 1024)) != -1)
{
out.write(data, 0, count);
}
}
} finally {
}
finally
{
out.closeEntry();
}
} catch (ZipException ze) {
}
catch (ZipException ze)
{
// some jars contain duplicate pom.xml entries: ignore it
if (!ze.getMessage().contains("duplicate")) {
if (!ze.getMessage().contains("duplicate"))
{
throw ze;
}
}
}
}
} catch (StackOverflowError | Exception e) {
}
catch (StackOverflowError | Exception e)
{
BytecodeViewer.handleException(e);
}
}
public Options generateOptions() {
public Options generateOptions()
{
Map<String, String> options = new HashMap<>();
options.put("decodeenumswitch", String.valueOf(BytecodeViewer.viewer.decodeEnumSwitch.isSelected()));
options.put("sugarenums", String.valueOf(BytecodeViewer.viewer.sugarEnums.isSelected()));
@ -164,8 +170,7 @@ public class CFRDecompiler extends InternalDecompiler {
options.put("collectioniter", String.valueOf(BytecodeViewer.viewer.collectioniter.isSelected()));
options.put("innerclasses", String.valueOf(BytecodeViewer.viewer.innerClasses.isSelected()));
options.put("removeboilerplate", String.valueOf(BytecodeViewer.viewer.removeBoilerPlate.isSelected()));
options.put("removeinnerclasssynthetics",
String.valueOf(BytecodeViewer.viewer.removeInnerClassSynthetics.isSelected()));
options.put("removeinnerclasssynthetics", String.valueOf(BytecodeViewer.viewer.removeInnerClassSynthetics.isSelected()));
options.put("decodelambdas", String.valueOf(BytecodeViewer.viewer.decodeLambdas.isSelected()));
options.put("hidebridgemethods", String.valueOf(BytecodeViewer.viewer.hideBridgeMethods.isSelected()));
options.put("liftconstructorinit", String.valueOf(BytecodeViewer.viewer.liftConstructorInit.isSelected()));
@ -201,51 +206,61 @@ public class CFRDecompiler extends InternalDecompiler {
return new OptionsImpl(options);
}
private static class BCVDataSource extends ClassFileSourceImpl {
private static class BCVDataSource extends ClassFileSourceImpl
{
private final ResourceContainer container;
private final String classFilePath;
private final byte[] content;
private BCVDataSource(Options options, ClassNode cn, String classFilePath, byte[] content) {
private BCVDataSource(Options options, ClassNode cn, String classFilePath, byte[] content)
{
super(options);
this.container = BytecodeViewer.getResourceContainers().stream()
.filter(rc -> rc.resourceClasses.containsValue(cn))
.findFirst().orElse(null);
this.container = BytecodeViewer.getResourceContainers().stream().filter(rc -> rc.resourceClasses.containsValue(cn)).findFirst().orElse(null);
this.classFilePath = classFilePath;
this.content = content;
}
@Override
public Pair<byte[], String> getClassFileContent(String classFilePath) throws IOException {
if (classFilePath.equals(this.classFilePath) && content != null) return Pair.make(content, classFilePath);
if (container == null) return super.getClassFileContent(classFilePath);
public Pair<byte[], String> getClassFileContent(String classFilePath) throws IOException
{
if (classFilePath.equals(this.classFilePath) && content != null)
return Pair.make(content, classFilePath);
if (container == null)
return super.getClassFileContent(classFilePath);
byte[] data = container.resourceClassBytes.get(classFilePath);
if (data == null) return super.getClassFileContent(classFilePath);
if (data == null)
return super.getClassFileContent(classFilePath);
return Pair.make(data, classFilePath);
}
}
private static class BCVOutputSinkFactory implements OutputSinkFactory {
private static class BCVOutputSinkFactory implements OutputSinkFactory
{
private final Consumer<SinkReturns.Decompiled> dumpDecompiled;
private BCVOutputSinkFactory(Consumer<SinkReturns.Decompiled> dumpDecompiled) {
private BCVOutputSinkFactory(Consumer<SinkReturns.Decompiled> dumpDecompiled)
{
this.dumpDecompiled = dumpDecompiled;
}
@Override
public List<SinkClass> getSupportedSinks(SinkType sinkType, Collection<SinkClass> available) {
public List<SinkClass> getSupportedSinks(SinkType sinkType, Collection<SinkClass> available)
{
return Collections.singletonList(SinkClass.DECOMPILED);
}
@Override
public <T> Sink<T> getSink(SinkType sinkType, SinkClass sinkClass) {
if (sinkType == SinkType.JAVA && sinkClass == SinkClass.DECOMPILED) {
public <T> Sink<T> getSink(SinkType sinkType, SinkClass sinkClass)
{
if (sinkType == SinkType.JAVA && sinkClass == SinkClass.DECOMPILED)
{
return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x);
}
return ignore -> {
return ignore ->
{
};
}

View File

@ -18,11 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -31,10 +26,9 @@ import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.LAUNCH_DECOMPILERS_IN_NEW_PROCESS;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import java.io.*;
import static the.bytecode.club.bytecodeviewer.Constants.*;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.FERNFLOWER;
@ -55,9 +49,13 @@ public class FernFlowerDecompiler extends InternalDecompiler
File f = new File(tempDirectory + fs + "temp" + fs);
f.mkdir();
try {
try
{
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempZip.getAbsolutePath(), tempDirectory + "./temp/"));
} catch (StackOverflowError | Exception ignored) { }
}
catch (StackOverflowError | Exception ignored)
{
}
File tempZip2 = new File(tempDirectory + fs + "temp" + fs + tempZip.getName());
if (tempZip2.exists())
@ -74,9 +72,12 @@ public class FernFlowerDecompiler extends InternalDecompiler
final File tempClass = new File(start + ".class");
String exception = "";
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
try (FileOutputStream fos = new FileOutputStream(tempClass))
{
fos.write(b);
} catch (IOException e) {
}
catch (IOException e)
{
StringWriter exceptionWriter = new StringWriter();
e.printStackTrace(new PrintWriter(exceptionWriter));
e.printStackTrace();
@ -105,10 +106,12 @@ public class FernFlowerDecompiler extends InternalDecompiler
}
else
{
try {
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(
generateMainMethod(tempClass.getAbsolutePath(), new File(tempDirectory).getAbsolutePath()));
} catch (Throwable e) {
try
{
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), new File(tempDirectory).getAbsolutePath()));
}
catch (Throwable e)
{
StringWriter exceptionWriter = new StringWriter();
e.printStackTrace(new PrintWriter(exceptionWriter));
e.printStackTrace();
@ -119,20 +122,25 @@ public class FernFlowerDecompiler extends InternalDecompiler
tempClass.delete();
String javaDir = start;
if (BytecodeViewer.viewer.ren.isSelected()) {
if (BytecodeViewer.viewer.ren.isSelected())
{
javaDir = tempDirectory + "class_0";
}
final File outputJava = new File(javaDir + ".java");
if (outputJava.exists()) {
if (outputJava.exists())
{
String s;
try {
try
{
s = DiskReader.loadAsString(outputJava.getAbsolutePath());
outputJava.delete();
return s;
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter exceptionWriter = new StringWriter();
e.printStackTrace(new PrintWriter(exceptionWriter));
e.printStackTrace();
@ -141,39 +149,22 @@ public class FernFlowerDecompiler extends InternalDecompiler
}
}
return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
private String[] generateMainMethod(String className, String folder) {
return new String[]{
"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()),
"-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()),
"-din=" + r(BytecodeViewer.viewer.din.isSelected()),
"-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()),
"-das=" + r(BytecodeViewer.viewer.das.isSelected()),
"-hes=" + r(BytecodeViewer.viewer.hes.isSelected()),
"-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()),
"-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()),
"-ner=" + r(BytecodeViewer.viewer.ner.isSelected()),
"-den=" + r(BytecodeViewer.viewer.den.isSelected()),
"-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()),
"-bto=" + r(BytecodeViewer.viewer.bto.isSelected()),
"-nns=" + r(BytecodeViewer.viewer.nns.isSelected()),
"-uto=" + r(BytecodeViewer.viewer.uto.isSelected()),
"-udv=" + r(BytecodeViewer.viewer.udv.isSelected()),
"-rer=" + r(BytecodeViewer.viewer.rer.isSelected()),
"-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()),
"-asc=" + r(BytecodeViewer.viewer.asc.isSelected()),
"-ren=" + r(BytecodeViewer.viewer.ren.isSelected()), className,
folder};
private String[] generateMainMethod(String className, String folder)
{
return new String[]{"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()), "-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()), "-din=" + r(BytecodeViewer.viewer.din.isSelected()), "-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()), "-das=" + r(BytecodeViewer.viewer.das.isSelected()), "-hes=" + r(BytecodeViewer.viewer.hes.isSelected()), "-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()), "-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()), "-ner=" + r(BytecodeViewer.viewer.ner.isSelected()), "-den=" + r(BytecodeViewer.viewer.den.isSelected()), "-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()), "-bto=" + r(BytecodeViewer.viewer.bto.isSelected()), "-nns=" + r(BytecodeViewer.viewer.nns.isSelected()), "-uto=" + r(BytecodeViewer.viewer.uto.isSelected()), "-udv=" + r(BytecodeViewer.viewer.udv.isSelected()), "-rer=" + r(BytecodeViewer.viewer.rer.isSelected()), "-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()), "-asc=" + r(BytecodeViewer.viewer.asc.isSelected()), "-ren=" + r(BytecodeViewer.viewer.ren.isSelected()), className, folder};
}
private String r(boolean b) {
if (b) {
private String r(boolean b)
{
if (b)
{
return "1";
} else {
}
else
{
return "0";
}
}

View File

@ -20,12 +20,6 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl;
import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Random;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -34,9 +28,10 @@ import the.bytecode.club.bytecodeviewer.decompilers.InternalDecompiler;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import java.io.*;
import java.util.Random;
import static the.bytecode.club.bytecodeviewer.Constants.*;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.JADX;
@ -50,22 +45,27 @@ public class JADXDecompiler extends InternalDecompiler
private final Random r = new Random();
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b)
{
String fileStart = tempDirectory + fs;
String exception = "";
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
try (FileOutputStream fos = new FileOutputStream(tempClass))
{
fos.write(b);
} catch (IOException e) {
}
catch (IOException e)
{
BytecodeViewer.handleException(e);
}
File fuckery = new File(fuckery(fileStart));
fuckery.mkdirs();
try {
try
{
JadxArgs args = new JadxArgs();
args.setInputFile(tempClass);
args.setOutDir(fuckery);
@ -75,7 +75,9 @@ public class JADXDecompiler extends InternalDecompiler
JadxDecompiler jadx = new JadxDecompiler(args);
jadx.load();
jadx.saveSources();
} catch (StackOverflowError | Exception e) {
}
catch (StackOverflowError | Exception e)
{
StringWriter exceptionWriter = new StringWriter();
e.printStackTrace(new PrintWriter(exceptionWriter));
e.printStackTrace();
@ -87,12 +89,10 @@ public class JADXDecompiler extends InternalDecompiler
if (fuckery.exists())
return findFile(MiscUtils.listFiles(fuckery));
if(exception.isEmpty())
if (exception.isEmpty())
exception = "Decompiled source file not found!";
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
//TODO remove
@ -109,32 +109,37 @@ public class JADXDecompiler extends InternalDecompiler
return null;
}
public String findFile(File[] fA) {
for (File f : fA) {
public String findFile(File[] fA)
{
for (File f : fA)
{
if (f.isDirectory())
return findFile(MiscUtils.listFiles(f));
else {
else
{
String s;
try {
try
{
s = DiskReader.loadAsString(f.getAbsolutePath());
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
String exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
return s;
}
}
return "JADX error!" +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR;
return "JADX error!" + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR;
}
@Override
public void decompileToZip(String sourceJar, String zipName) { }
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -18,12 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.jd.core.v1.ClassFileToJavaSourceDecompiler;
import org.objectweb.asm.tree.ClassNode;
@ -38,6 +32,8 @@ import the.bytecode.club.bytecodeviewer.decompilers.jdgui.PlainTextPrinter;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import java.io.*;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
@ -54,28 +50,35 @@ public class JDGUIDecompiler extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b)
{
String exception;
try {
try
{
final File tempDirectory = new File(Constants.tempDirectory + fs + MiscUtils.randomString(32) + fs);
tempDirectory.mkdir();
final File tempClass = new File(tempDirectory.getAbsolutePath() + fs + cn.name + ".class");
final File tempJava = new File(tempDirectory.getAbsolutePath() + fs + cn.name + ".java");
if (cn.name.contains("/")) {
if (cn.name.contains("/"))
{
String[] raw = cn.name.split("/");
String path = tempDirectory.getAbsolutePath() + fs;
for (int i = 0; i < raw.length - 1; i++) {
for (int i = 0; i < raw.length - 1; i++)
{
path += raw[i] + fs;
File f = new File(path);
f.mkdir();
}
}
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
try (FileOutputStream fos = new FileOutputStream(tempClass))
{
fos.write(b);
} catch (IOException e) {
}
catch (IOException e)
{
BytecodeViewer.handleException(e);
}
@ -84,14 +87,17 @@ public class JDGUIDecompiler extends InternalDecompiler
String directoryPath = JDGUIClassFileUtil.ExtractDirectoryPath(pathToClass);
String internalPath = JDGUIClassFileUtil.ExtractInternalPath(directoryPath, pathToClass);
CommonPreferences preferences = new CommonPreferences() {
CommonPreferences preferences = new CommonPreferences()
{
@Override
public boolean isShowLineNumbers() {
public boolean isShowLineNumbers()
{
return false;
}
@Override
public boolean isMergeEmptyLines() {
public boolean isMergeEmptyLines()
{
return true;
}
};
@ -102,13 +108,15 @@ public class JDGUIDecompiler extends InternalDecompiler
//HtmlPrinter printer = new HtmlPrinter(ps);
org.jd.core.v1.api.Decompiler decompiler = new ClassFileToJavaSourceDecompiler();
try (PrintStream ps = new PrintStream(tempJava.getAbsolutePath());
PlainTextPrinter printer = new PlainTextPrinter(preferences, ps)) {
try (PrintStream ps = new PrintStream(tempJava.getAbsolutePath()); PlainTextPrinter printer = new PlainTextPrinter(preferences, ps))
{
decompiler.decompile(loader, printer, internalPath, preferences.getPreferences());
}
return DiskReader.loadAsString(tempJava.getAbsolutePath());
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -116,12 +124,11 @@ public class JDGUIDecompiler extends InternalDecompiler
exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
}
return JDGUI + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return JDGUI + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -18,10 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import me.konloch.kontainer.io.DiskWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
@ -33,12 +29,17 @@ import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.api.ExceptionUI.SEND_STACKTRACE_TO;
/**
* Javap disassembler
*
* <p>
* https://github.com/Konloch/bytecode-viewer/issues/93
*
* @author Konloch
@ -50,7 +51,7 @@ public class JavapDisassembler extends InternalDecompiler
@Override
public String decompileClassNode(ClassNode cn, byte[] b)
{
if(!ExternalResources.getSingleton().hasJavaToolsSet())
if (!ExternalResources.getSingleton().hasJavaToolsSet())
return "Set Java Tools Path!";
return synchronizedDecompilation(cn, b);
@ -68,10 +69,7 @@ public class JavapDisassembler extends InternalDecompiler
try
{
//load java tools into a temporary classloader
URLClassLoader child = new URLClassLoader(
new URL[] {new File(Configuration.javaTools).toURI().toURL()},
this.getClass().getClassLoader()
);
URLClassLoader child = new URLClassLoader(new URL[]{new File(Configuration.javaTools).toURI().toURL()}, this.getClass().getClassLoader());
//setup reflection
Class<?> javap = child.loadClass("com.sun.tools.javap.Main");
@ -84,8 +82,7 @@ public class JavapDisassembler extends InternalDecompiler
BytecodeViewer.sm.silenceExec(true);
//invoke Javap
main.invoke(null, (Object) new String[]{
"-p", //Shows all classes and members
main.invoke(null, (Object) new String[]{"-p", //Shows all classes and members
"-c", //Prints out disassembled code
//"-l", //Prints out line and local variable tables
"-constants", //Shows static final constants
@ -105,7 +102,7 @@ public class JavapDisassembler extends InternalDecompiler
tempClass.delete();
}
if(sysOutBuffer != null)
if (sysOutBuffer != null)
{
sysOutBuffer.finished();
return sysOutBuffer.getTextAreaOutputStreamOut().getBuffer().toString();
@ -115,5 +112,7 @@ public class JavapDisassembler extends InternalDecompiler
}
@Override
public void decompileToZip(String sourceJar, String zipName) { }
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -18,14 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.stream.Collectors;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.lang3.ArrayUtils;
import org.objectweb.asm.tree.ClassNode;
@ -40,9 +32,11 @@ import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.ZipUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import java.io.*;
import java.util.Arrays;
import java.util.stream.Collectors;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* Krakatau Java Decompiler Wrapper, requires Python 2.7
@ -67,50 +61,38 @@ public class KrakatauDecompiler extends InternalDecompiler
if (files == null || files.length == 0)
return "";
return ";" + Arrays.stream(files).filter(File::isFile)
.map(File::getAbsolutePath).collect(Collectors.joining(";"));
return ";" + Arrays.stream(files).filter(File::isFile).map(File::getAbsolutePath).collect(Collectors.joining(";"));
}
public String decompileClassNode(File krakatauTempJar, File krakatauTempDir, ClassNode cn)
{
if(!ExternalResources.getSingleton().hasSetPython2Command())
if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
ExternalResources.getSingleton().rtCheck();
if (Configuration.rt.isEmpty())
{
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
ExternalResources.getSingleton().selectJRERTLibrary();
}
if (Configuration.rt.isEmpty())
{
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
+ " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B;
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B;
}
String s = ExceptionUI.SEND_STACKTRACE_TO_NL;
try {
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py",
"-skip", //love you storyyeller <3
"-nauto",
"-path",
Configuration.rt + ";" + krakatauTempJar.getAbsolutePath() + buildCLIArguments(),
"-out",
krakatauTempDir.getAbsolutePath(),
cn.name + ".class"
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Configuration.rt + ";" + krakatauTempJar.getAbsolutePath() + buildCLIArguments(), "-out", krakatauTempDir.getAbsolutePath(), cn.name + ".class"));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
@ -118,22 +100,22 @@ public class KrakatauDecompiler extends InternalDecompiler
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + nl + nl);
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getErrorStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
@ -144,7 +126,9 @@ public class KrakatauDecompiler extends InternalDecompiler
//if the motherfucker failed this'll fail, aka wont set.
s = DiskReader.loadAsString(krakatauTempDir.getAbsolutePath() + fs + cn.name + ".java");
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -159,16 +143,17 @@ public class KrakatauDecompiler extends InternalDecompiler
{
//TODO look into transforming through krakatau as a zip rather than direct classfile
if(!ExternalResources.getSingleton().hasSetPython2Command())
if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
if (Configuration.rt.isEmpty()) {
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
if (Configuration.rt.isEmpty())
{
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
ExternalResources.getSingleton().selectJRERTLibrary();
}
if (Configuration.rt.isEmpty()) {
if (Configuration.rt.isEmpty())
{
BytecodeViewer.showMessage("You need to set RT.jar!");
return "Set your paths";
}
@ -181,23 +166,15 @@ public class KrakatauDecompiler extends InternalDecompiler
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
try {
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py",
"-skip", //love you storyyeller <3
"-nauto",
"-path",
Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(),
"-out",
tempDirectory.getAbsolutePath(),
cn.name + ".class"
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(), "-out", tempDirectory.getAbsolutePath(), cn.name + ".class"));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
@ -205,22 +182,22 @@ public class KrakatauDecompiler extends InternalDecompiler
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + nl + nl);
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getErrorStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
@ -233,7 +210,9 @@ public class KrakatauDecompiler extends InternalDecompiler
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + fs + cn.name + ".java");
tempDirectory.delete();
tempJar.delete();
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -244,14 +223,15 @@ public class KrakatauDecompiler extends InternalDecompiler
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
if(!ExternalResources.getSingleton().hasSetPython2Command())
public void decompileToZip(String sourceJar, String zipName)
{
if (!ExternalResources.getSingleton().hasSetPython2Command())
return;
ExternalResources.getSingleton().rtCheck();
if (Configuration.rt.isEmpty()) {
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A
+ "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
if (Configuration.rt.isEmpty())
{
BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B);
ExternalResources.getSingleton().selectJRERTLibrary();
}
@ -261,23 +241,15 @@ public class KrakatauDecompiler extends InternalDecompiler
final File tempJar = new File(sourceJar);
try {
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py",
"-skip", //love you storyyeller <3
"-nauto",
"-path",
Configuration.rt + ";" + tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
tempJar.getAbsolutePath()
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath()));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
@ -285,7 +257,9 @@ public class KrakatauDecompiler extends InternalDecompiler
MiscUtils.printProcess(process);
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}

View File

@ -18,12 +18,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.lang3.ArrayUtils;
import org.objectweb.asm.tree.ClassNode;
@ -38,9 +32,9 @@ import the.bytecode.club.bytecodeviewer.util.JarUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.ZipUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import java.io.*;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* Krakatau Java Disassembler Wrapper, requires Python 2.7
@ -51,8 +45,9 @@ import static the.bytecode.club.bytecodeviewer.Constants.nl;
public class KrakatauDisassembler extends InternalDecompiler
{
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
if(!ExternalResources.getSingleton().hasSetPython2Command())
public String decompileClassNode(ClassNode cn, byte[] b)
{
if (!ExternalResources.getSingleton().hasSetPython2Command())
return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString();
String s = ExceptionUI.SEND_STACKTRACE_TO_NL;
@ -62,21 +57,14 @@ public class KrakatauDisassembler extends InternalDecompiler
final File tempJar = new File(Constants.tempDirectory + fs + "temp" + MiscUtils.randomString(32) + ".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
try {
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "disassemble.py",
"-path",
tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
cn.name + ".class"
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "disassemble.py", "-path", tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), cn.name + ".class"));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
@ -84,22 +72,22 @@ public class KrakatauDisassembler extends InternalDecompiler
StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + nl + nl);
//Read out dir output
try (InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
log.append(nl).append(nl).append(TranslatedStrings.ERROR2).append(nl).append(nl);
try (InputStream is = process.getErrorStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr)) {
try (InputStream is = process.getErrorStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr))
{
String line;
while ((line = br.readLine()) != null) {
while ((line = br.readLine()) != null)
{
log.append(nl).append(line);
}
}
@ -110,7 +98,9 @@ public class KrakatauDisassembler extends InternalDecompiler
// if the motherfucker failed this'll fail, aka won't set.
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + fs + cn.name + ".j");
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -120,8 +110,9 @@ public class KrakatauDisassembler extends InternalDecompiler
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
if(!ExternalResources.getSingleton().hasSetPython2Command())
public void decompileToZip(String sourceJar, String zipName)
{
if (!ExternalResources.getSingleton().hasSetPython2Command())
return;
String ran = MiscUtils.randomString(32);
@ -130,28 +121,23 @@ public class KrakatauDisassembler extends InternalDecompiler
final File tempJar = new File(sourceJar);
try {
try
{
String[] pythonCommands = new String[]{Configuration.python2};
if(Configuration.python2Extra)
if (Configuration.python2Extra)
pythonCommands = ArrayUtils.addAll(pythonCommands, "-2");
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(
pythonCommands,
"-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "disassemble.py",
"-path",
Configuration.rt + ";" + tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
tempJar.getAbsolutePath()
));
ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3
krakatauWorkingDirectory + fs + "disassemble.py", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath()));
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
process.waitFor();
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
} catch (Exception e) {
}
catch (Exception e)
{
BytecodeViewer.handleException(e);
}
}

View File

@ -19,35 +19,12 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import com.strobel.assembler.InputTypeLoader;
import com.strobel.assembler.metadata.Buffer;
import com.strobel.assembler.metadata.ITypeLoader;
import com.strobel.assembler.metadata.JarTypeLoader;
import com.strobel.assembler.metadata.MetadataSystem;
import com.strobel.assembler.metadata.TypeDefinition;
import com.strobel.assembler.metadata.TypeReference;
import com.strobel.assembler.metadata.*;
import com.strobel.core.StringUtilities;
import com.strobel.decompiler.DecompilationOptions;
import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput;
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
@ -56,9 +33,14 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.EncodeUtils;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import java.io.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import static the.bytecode.club.bytecodeviewer.Constants.*;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PROCYON;
@ -68,9 +50,11 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PRO
* @author Konloch
* @author DeathMarine
*/
public class ProcyonDecompiler extends InternalDecompiler {
public class ProcyonDecompiler extends InternalDecompiler
{
public DecompilerSettings getDecompilerSettings() {
public DecompilerSettings getDecompilerSettings()
{
DecompilerSettings settings = new DecompilerSettings();
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.alwaysGenerateExceptionVars.isSelected());
settings.setExcludeNestedTypes(BytecodeViewer.viewer.excludeNestedTypes.isSelected());
@ -91,16 +75,21 @@ public class ProcyonDecompiler extends InternalDecompiler {
}
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b)
{
String exception;
try {
try
{
String fileStart = tempDirectory + fs + "temp";
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
try (FileOutputStream fos = new FileOutputStream(tempClass))
{
fos.write(b);
} catch (IOException e) {
}
catch (IOException e)
{
BytecodeViewer.handleException(e);
}
@ -122,7 +111,9 @@ public class ProcyonDecompiler extends InternalDecompiler {
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions);
return EncodeUtils.unicodeToString(stringwriter.toString());
} catch (StackOverflowError | Exception e) {
}
catch (StackOverflowError | Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -130,16 +121,18 @@ public class ProcyonDecompiler extends InternalDecompiler {
exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
}
return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
try {
public void decompileToZip(String sourceJar, String zipName)
{
try
{
doSaveJarDecompiled(new File(sourceJar), new File(zipName));
} catch (StackOverflowError | Exception e) {
}
catch (StackOverflowError | Exception e)
{
BytecodeViewer.handleException(e);
}
}
@ -147,12 +140,10 @@ public class ProcyonDecompiler extends InternalDecompiler {
/**
* @author DeathMarine
*/
private void doSaveJarDecompiled(File inFile, File outFile)
throws Exception {
try (JarFile jfile = new JarFile(inFile);
FileOutputStream dest = new FileOutputStream(outFile);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest)) {
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception
{
try (JarFile jfile = new JarFile(inFile); FileOutputStream dest = new FileOutputStream(outFile); BufferedOutputStream buffDest = new BufferedOutputStream(dest); ZipOutputStream out = new ZipOutputStream(buffDest))
{
byte[] data = new byte[1024];
DecompilerSettings settings = getDecompilerSettings();
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
@ -166,52 +157,64 @@ public class ProcyonDecompiler extends InternalDecompiler {
Enumeration<JarEntry> ent = jfile.entries();
Set<JarEntry> history = new HashSet<>();
while (ent.hasMoreElements()) {
while (ent.hasMoreElements())
{
JarEntry entry = ent.nextElement();
if (entry.getName().endsWith(".class")) {
JarEntry etn = new JarEntry(entry.getName().replace(
".class", ".java"));
if (history.add(etn)) {
if (entry.getName().endsWith(".class"))
{
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
if (history.add(etn))
{
out.putNextEntry(etn);
try {
String internalName = StringUtilities.removeRight(
entry.getName(), ".class");
TypeReference type = metadataSystem
.lookupType(internalName);
try
{
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
TypeReference type = metadataSystem.lookupType(internalName);
TypeDefinition resolvedType;
if ((type == null)
|| ((resolvedType = type.resolve()) == null)) {
if ((type == null) || ((resolvedType = type.resolve()) == null))
{
throw new Exception("Unable to resolve type.");
}
Writer writer = new OutputStreamWriter(out);
settings.getLanguage().decompileType(resolvedType,
new PlainTextOutput(writer),
decompilationOptions);
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
writer.flush();
} finally {
}
finally
{
out.closeEntry();
}
}
} else {
try {
}
else
{
try
{
JarEntry etn = new JarEntry(entry.getName());
if (history.add(etn))
continue;
history.add(etn);
out.putNextEntry(etn);
try (InputStream in = jfile.getInputStream(entry)) {
if (in != null) {
try (InputStream in = jfile.getInputStream(entry))
{
if (in != null)
{
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
while ((count = in.read(data, 0, 1024)) != -1)
{
out.write(data, 0, count);
}
}
} finally {
}
finally
{
out.closeEntry();
}
} catch (ZipException ze) {
}
catch (ZipException ze)
{
// some jars contain duplicate pom.xml entries: ignore it
if (!ze.getMessage().contains("duplicate")) {
if (!ze.getMessage().contains("duplicate"))
{
throw ze;
}
}
@ -223,23 +226,29 @@ public class ProcyonDecompiler extends InternalDecompiler {
/**
* @author DeathMarine
*/
public static final class LuytenTypeLoader implements ITypeLoader {
public static final class LuytenTypeLoader implements ITypeLoader
{
private final List<ITypeLoader> _typeLoaders;
public LuytenTypeLoader() {
public LuytenTypeLoader()
{
_typeLoaders = new ArrayList<>();
_typeLoaders.add(new InputTypeLoader());
}
public List<ITypeLoader> getTypeLoaders() {
public List<ITypeLoader> getTypeLoaders()
{
return _typeLoaders;
}
@Override
public boolean tryLoadType(String internalName, Buffer buffer) {
for (ITypeLoader typeLoader : _typeLoaders) {
if (typeLoader.tryLoadType(internalName, buffer)) {
public boolean tryLoadType(String internalName, Buffer buffer)
{
for (ITypeLoader typeLoader : _typeLoaders)
{
if (typeLoader.tryLoadType(internalName, buffer))
{
return true;
}

View File

@ -19,12 +19,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.impl;
import com.googlecode.d2j.smali.BaksmaliCmd;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Objects;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.io.FileUtils;
import org.objectweb.asm.tree.ClassNode;
@ -35,12 +29,11 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import the.bytecode.club.bytecodeviewer.util.Dex2Jar;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import static the.bytecode.club.bytecodeviewer.Constants.fs;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DISASSEMBLER;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.SMALI;
import java.io.*;
import java.util.Objects;
import static the.bytecode.club.bytecodeviewer.Constants.*;
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*;
/**
* Smali Disassembler Wrapper
@ -63,9 +56,12 @@ public class SmaliDisassembler extends InternalDecompiler
final File tempDexOut = new File(start + "-out");
final File tempSmali = new File(start + "-smali"); //output directory
try (FileOutputStream fos = new FileOutputStream(tempClass)) {
try (FileOutputStream fos = new FileOutputStream(tempClass))
{
fos.write(b);
} catch (IOException e) {
}
catch (IOException e)
{
BytecodeViewer.handleException(e);
}
@ -73,10 +69,12 @@ public class SmaliDisassembler extends InternalDecompiler
Dex2Jar.saveAsDex(tempClass, tempDex, true);
try {
BaksmaliCmd.main(tempDex.getAbsolutePath(),
"-o", tempDexOut.getAbsolutePath());
} catch (Exception e) {
try
{
BaksmaliCmd.main(tempDex.getAbsolutePath(), "-o", tempDexOut.getAbsolutePath());
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -84,9 +82,12 @@ public class SmaliDisassembler extends InternalDecompiler
exception += ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
}
try {
try
{
FileUtils.moveDirectory(tempDexOut, tempSmali);
} catch (IOException e) {
}
catch (IOException e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -98,19 +99,24 @@ public class SmaliDisassembler extends InternalDecompiler
boolean found = false;
File current = tempSmali;
while (!found) {
while (!found)
{
File f = Objects.requireNonNull(current.listFiles())[0];
if (f.isDirectory())
current = f;
else {
else
{
outputSmali = f;
found = true;
}
}
try {
try
{
return DiskReader.loadAsString(outputSmali.getAbsolutePath());
} catch (Exception e) {
}
catch (Exception e)
{
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
@ -118,13 +124,12 @@ public class SmaliDisassembler extends InternalDecompiler
exception += ExceptionUI.SEND_STACKTRACE_TO_NL + sw;
}
return SMALI + " " + DISASSEMBLER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO +
nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR +
nl + nl + exception;
return SMALI + " " + DISASSEMBLER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + nl + nl + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + nl + nl + exception;
}
@Override
public void decompileToZip(String sourceJar, String zipName) {
public void decompileToZip(String sourceJar, String zipName)
{
}
}

View File

@ -21,7 +21,8 @@ package the.bytecode.club.bytecodeviewer.decompilers.jdgui;
import java.util.HashMap;
import java.util.Map;
public class CommonPreferences {
public class CommonPreferences
{
private final Map<String, Object> preferences;
protected boolean showDefaultConstructor;
protected boolean realignmentLineNumber;
@ -30,7 +31,8 @@ public class CommonPreferences {
protected boolean unicodeEscape;
protected boolean showLineNumbers;
public CommonPreferences() {
public CommonPreferences()
{
this.showPrefixThis = true;
this.mergeEmptyLines = false;
this.unicodeEscape = false;
@ -38,10 +40,8 @@ public class CommonPreferences {
this.preferences = new HashMap<>();
}
public CommonPreferences(
boolean showDefaultConstructor, boolean realignmentLineNumber,
boolean showPrefixThis, boolean mergeEmptyLines,
boolean unicodeEscape, boolean showLineNumbers) {
public CommonPreferences(boolean showDefaultConstructor, boolean realignmentLineNumber, boolean showPrefixThis, boolean mergeEmptyLines, boolean unicodeEscape, boolean showLineNumbers)
{
this.showDefaultConstructor = showDefaultConstructor;
this.realignmentLineNumber = realignmentLineNumber;
this.showPrefixThis = showPrefixThis;
@ -51,31 +51,38 @@ public class CommonPreferences {
this.preferences = new HashMap<>();
}
public boolean isShowDefaultConstructor() {
public boolean isShowDefaultConstructor()
{
return showDefaultConstructor;
}
public boolean isRealignmentLineNumber() {
public boolean isRealignmentLineNumber()
{
return realignmentLineNumber;
}
public boolean isShowPrefixThis() {
public boolean isShowPrefixThis()
{
return showPrefixThis;
}
public boolean isMergeEmptyLines() {
public boolean isMergeEmptyLines()
{
return mergeEmptyLines;
}
public boolean isUnicodeEscape() {
public boolean isUnicodeEscape()
{
return unicodeEscape;
}
public boolean isShowLineNumbers() {
public boolean isShowLineNumbers()
{
return showLineNumbers;
}
public Map<String, Object> getPreferences() {
public Map<String, Object> getPreferences()
{
return preferences;
}
}

View File

@ -18,13 +18,14 @@
package the.bytecode.club.bytecodeviewer.decompilers.jdgui;
import org.apache.commons.io.IOUtils;
import org.jd.core.v1.api.loader.Loader;
import org.jd.core.v1.api.loader.LoaderException;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.jd.core.v1.api.loader.Loader;
import org.jd.core.v1.api.loader.LoaderException;
public class DirectoryLoader implements Loader
{
@ -43,21 +44,23 @@ public class DirectoryLoader implements Loader
}
@Override
public byte[] load(String internalPath)
throws LoaderException {
public byte[] load(String internalPath) throws LoaderException
{
File file = new File(this.codebase, internalPath);
try (FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis)) {
try (FileInputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis))
{
return IOUtils.toByteArray(bis);
} catch (IOException e) {
throw new LoaderException(
"'" + file.getAbsolutePath() + "' not found.");
}
catch (IOException e)
{
throw new LoaderException("'" + file.getAbsolutePath() + "' not found.");
}
}
@Override
public boolean canLoad(String internalPath) {
public boolean canLoad(String internalPath)
{
File file = new File(this.codebase, internalPath);
return file.exists() && file.isFile();
}

View File

@ -18,17 +18,14 @@
package the.bytecode.club.bytecodeviewer.decompilers.jdgui;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import org.jd.core.v1.model.classfile.constant.Constant;
import org.jd.core.v1.model.classfile.constant.ConstantClass;
import org.jd.core.v1.model.classfile.constant.ConstantUtf8;
import org.jd.core.v1.service.deserializer.classfile.ClassFileFormatException;
import org.jd.core.v1.service.deserializer.classfile.ClassFileReader;
import java.io.*;
public class JDGUIClassFileUtil
{
@ -39,14 +36,15 @@ public class JDGUIClassFileUtil
* Lecture rapide de la structure de la classe et extraction du nom du
* repoertoire de base.
*/
public static String ExtractDirectoryPath(String pathToClass) {
public static String ExtractDirectoryPath(String pathToClass)
{
String directoryPath;
try (FileInputStream fis = new FileInputStream(pathToClass);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis)) {
try (FileInputStream fis = new FileInputStream(pathToClass); BufferedInputStream bis = new BufferedInputStream(fis); DataInputStream dis = new DataInputStream(bis))
{
int magic = dis.readInt();
if (magic != ClassFileReader.JAVA_MAGIC_NUMBER) {
if (magic != ClassFileReader.JAVA_MAGIC_NUMBER)
{
throw new ClassFileFormatException("Invalid Java .class file");
}
@ -61,32 +59,36 @@ public class JDGUIClassFileUtil
dis.readUnsignedShort();
int this_class = dis.readUnsignedShort();
if (this_class > constants.length) {
if (this_class > constants.length)
{
throw new ClassFileFormatException("Unknown Java structure");
}
Constant c = constants[this_class];
if ((c == null) || (c.getTag() != Constant.CONSTANT_Class)) {
if ((c == null) || (c.getTag() != Constant.CONSTANT_Class))
{
throw new ClassFileFormatException("Invalid constant pool");
}
c = constants[((ConstantClass) c).getNameIndex()];
if ((c == null) || (c.getTag() != Constant.CONSTANT_Utf8)) {
if ((c == null) || (c.getTag() != Constant.CONSTANT_Utf8))
{
throw new ClassFileFormatException("Invalid constant pool");
}
String internalClassName = ((ConstantUtf8) c).getValue();
String pathSuffix = internalClassName.replace(
INTERNAL_PACKAGE_SEPARATOR, File.separatorChar) +
CLASS_FILE_SUFFIX;
String pathSuffix = internalClassName.replace(INTERNAL_PACKAGE_SEPARATOR, File.separatorChar) + CLASS_FILE_SUFFIX;
int index = pathToClass.indexOf(pathSuffix);
if (index < 0) {
if (index < 0)
{
throw new ClassFileFormatException("Invalid internal class name");
}
directoryPath = pathToClass.substring(0, index);
} catch (IOException e) {
}
catch (IOException e)
{
directoryPath = null;
e.printStackTrace();
}
@ -94,10 +96,9 @@ public class JDGUIClassFileUtil
return directoryPath;
}
public static String ExtractInternalPath(
String directoryPath, String pathToClass) {
if ((directoryPath == null) || (pathToClass == null) ||
!pathToClass.startsWith(directoryPath))
public static String ExtractInternalPath(String directoryPath, String pathToClass)
{
if ((directoryPath == null) || (pathToClass == null) || !pathToClass.startsWith(directoryPath))
return null;
String s = pathToClass.substring(directoryPath.length());
@ -105,15 +106,17 @@ public class JDGUIClassFileUtil
return s.replace(File.separatorChar, INTERNAL_PACKAGE_SEPARATOR);
}
private static Constant[] DeserializeConstants(DataInputStream dis)
throws IOException {
private static Constant[] DeserializeConstants(DataInputStream dis) throws IOException
{
int count = dis.readUnsignedShort();
Constant[] constants = new Constant[count];
for (int i = 1; i < count; i++) {
for (int i = 1; i < count; i++)
{
byte tag = dis.readByte();
switch (tag) {
switch (tag)
{
case Constant.CONSTANT_Class:
constants[i] = new ConstantClass(dis.readUnsignedShort());
break;

View File

@ -18,11 +18,13 @@
package the.bytecode.club.bytecodeviewer.decompilers.jdgui;
import java.io.Closeable;
import java.io.PrintStream;
import org.jd.core.v1.api.printer.Printer;
public class PlainTextPrinter implements Printer, Closeable {
import java.io.Closeable;
import java.io.PrintStream;
public class PlainTextPrinter implements Printer, Closeable
{
protected static final String TAB = " ";
protected static final String NEWLINE = "\n";
@ -38,8 +40,8 @@ public class PlainTextPrinter implements Printer, Closeable {
protected int indentationCount;
protected boolean display;
public PlainTextPrinter(
CommonPreferences preferences, PrintStream printStream) {
public PlainTextPrinter(CommonPreferences preferences, PrintStream printStream)
{
this.preferences = preferences;
this.printStream = printStream;
this.maxLineNumber = 0;
@ -48,49 +50,57 @@ public class PlainTextPrinter implements Printer, Closeable {
this.indentationCount = 0;
}
public int getMajorVersion() {
public int getMajorVersion()
{
return majorVersion;
}
public int getMinorVersion() {
public int getMinorVersion()
{
return minorVersion;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
@Override
public void printKeyword(String s) {
public void printKeyword(String s)
{
if (this.display)
this.printStream.append(s);
}
@Override
public void printDeclaration(int type, String internalTypeName, String name, String descriptor) {
public void printDeclaration(int type, String internalTypeName, String name, String descriptor)
{
this.printStream.append(name);
}
@Override
public void printReference(int type, String internalTypeName, String name, String descriptor,
String ownerInternalName) {
public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName)
{
this.printStream.append(name);
}
@Override
public void start(int maxLineNumber, int majorVersion, int minorVersion) {
public void start(int maxLineNumber, int majorVersion, int minorVersion)
{
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
this.indentationCount = 0;
this.display = true;
if (this.preferences.isShowLineNumbers()) {
if (this.preferences.isShowLineNumbers())
{
this.maxLineNumber = maxLineNumber;
if (maxLineNumber > 0) {
if (maxLineNumber > 0)
{
this.digitCount = 1;
StringBuilder unknownLineNumberPrefixBuilder = new StringBuilder(" ");
int maximum = 9;
while (maximum < maxLineNumber) {
while (maximum < maxLineNumber)
{
this.digitCount++;
unknownLineNumberPrefixBuilder.append(' ');
maximum = maximum * 10 + 9;
@ -99,12 +109,16 @@ public class PlainTextPrinter implements Printer, Closeable {
this.unknownLineNumberPrefix = unknownLineNumberPrefixBuilder.toString();
this.lineNumberBeginPrefix = "/* ";
this.lineNumberEndPrefix = " */ ";
} else {
}
else
{
this.unknownLineNumberPrefix = "";
this.lineNumberBeginPrefix = "";
this.lineNumberEndPrefix = "";
}
} else {
}
else
{
this.maxLineNumber = 0;
this.unknownLineNumberPrefix = "";
this.lineNumberBeginPrefix = "";
@ -113,44 +127,55 @@ public class PlainTextPrinter implements Printer, Closeable {
}
@Override
public void end() {
public void end()
{
}
@Override
public void printText(String s) {
public void printText(String s)
{
if (this.display)
printEscape(s);
}
@Override
public void printNumericConstant(String s) {
public void printNumericConstant(String s)
{
this.printStream.append(s);
}
@Override
public void printStringConstant(String s, String s1) {
public void printStringConstant(String s, String s1)
{
this.printStream.append(s);
}
@Override
public void indent() {
public void indent()
{
this.indentationCount++;
}
@Override
public void unindent() {
public void unindent()
{
if (this.indentationCount > 0)
this.indentationCount--;
}
@Override
public void startLine(int lineNumber) {
if (this.maxLineNumber > 0) {
public void startLine(int lineNumber)
{
if (this.maxLineNumber > 0)
{
this.printStream.append(this.lineNumberBeginPrefix);
if (lineNumber == UNKNOWN_LINE_NUMBER) {
if (lineNumber == UNKNOWN_LINE_NUMBER)
{
this.printStream.append(this.unknownLineNumberPrefix);
} else {
}
else
{
int left = 0;
left = printDigit(5, lineNumber, 10000, left);
@ -168,15 +193,20 @@ public class PlainTextPrinter implements Printer, Closeable {
}
@Override
public void endLine() {
public void endLine()
{
this.printStream.append(NEWLINE);
}
@Override
public void extraLine(int count) {
if (!this.preferences.isMergeEmptyLines()) {
while (count-- > 0) {
if (this.maxLineNumber > 0) {
public void extraLine(int count)
{
if (!this.preferences.isMergeEmptyLines())
{
while (count-- > 0)
{
if (this.maxLineNumber > 0)
{
this.printStream.append(this.lineNumberBeginPrefix);
this.printStream.append(this.unknownLineNumberPrefix);
this.printStream.append(this.lineNumberEndPrefix);
@ -188,30 +218,40 @@ public class PlainTextPrinter implements Printer, Closeable {
}
@Override
public void startMarker(int i) {
public void startMarker(int i)
{
}
@Override
public void endMarker(int i) {
public void endMarker(int i)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
protected void printEscape(String s) {
if (this.preferences.isUnicodeEscape()) {
protected void printEscape(String s)
{
if (this.preferences.isUnicodeEscape())
{
int length = s.length();
for (int i = 0; i < length; i++) {
for (int i = 0; i < length; i++)
{
char c = s.charAt(i);
if (c == '\t') {
if (c == '\t')
{
this.printStream.append('\t');
} else if (c < 32) {
}
else if (c < 32)
{
// Write octal format
this.printStream.append("\\0");
this.printStream.append((char) ('0' + (c >> 3)));
this.printStream.append((char) ('0' + (c & 0x7)));
} else if (c > 127) {
}
else if (c > 127)
{
// Write octal format
this.printStream.append("\\u");
@ -223,20 +263,29 @@ public class PlainTextPrinter implements Printer, Closeable {
this.printStream.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
z = (c & 0xF);
this.printStream.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
} else {
}
else
{
this.printStream.append(c);
}
}
} else {
}
else
{
this.printStream.append(s);
}
}
protected int printDigit(int dcv, int lineNumber, int divisor, int left) {
if (this.digitCount >= dcv) {
if (lineNumber < divisor) {
protected int printDigit(int dcv, int lineNumber, int divisor, int left)
{
if (this.digitCount >= dcv)
{
if (lineNumber < divisor)
{
this.printStream.append(' ');
} else {
}
else
{
int e = (lineNumber - left) / divisor;
this.printStream.append((char) ('0' + e));
left += e * divisor;
@ -247,7 +296,8 @@ public class PlainTextPrinter implements Printer, Closeable {
}
@Override
public void close() {
public void close()
{
if (this.printStream != null)
this.printStream.close();
}

View File

@ -18,25 +18,11 @@
package the.bytecode.club.bytecodeviewer.gui;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.Constants;
import the.bytecode.club.bytecodeviewer.SettingsSerializer;
import the.bytecode.club.bytecodeviewer.gui.components.AboutWindow;
import the.bytecode.club.bytecodeviewer.gui.components.FileChooser;
import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog;
import the.bytecode.club.bytecodeviewer.gui.components.RunOptions;
import the.bytecode.club.bytecodeviewer.gui.components.SettingsDialog;
import the.bytecode.club.bytecodeviewer.gui.components.VisibleComponent;
import the.bytecode.club.bytecodeviewer.gui.components.WaitBusyIcon;
import the.bytecode.club.bytecodeviewer.gui.components.*;
import the.bytecode.club.bytecodeviewer.gui.plugins.MaliciousCodeScannerOptions;
import the.bytecode.club.bytecodeviewer.gui.plugins.ReplaceStringsOptions;
import the.bytecode.club.bytecodeviewer.gui.resourcelist.ResourceListPane;
@ -52,16 +38,7 @@ import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameFields;
import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameMethods;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.PluginTemplate;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ChangeClassFileVersions;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.CodeSequenceDiagram;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ShowAllStrings;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ShowMainMethods;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.StackFramesRemover;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ViewAPKAndroidPermissions;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ViewManifest;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZKMStringDecrypter;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZStringArrayDecrypter;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.*;
import the.bytecode.club.bytecodeviewer.resources.ExternalResources;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
@ -74,12 +51,15 @@ import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckB
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenu;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJMenuItem;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem;
import the.bytecode.club.bytecodeviewer.util.DialogUtils;
import the.bytecode.club.bytecodeviewer.util.KeyEventDispatch;
import the.bytecode.club.bytecodeviewer.util.LazyNameUtil;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import the.bytecode.club.bytecodeviewer.util.WindowClosingAdapter;
import the.bytecode.club.bytecodeviewer.util.WindowStateChangeAdapter;
import the.bytecode.club.bytecodeviewer.util.*;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static the.bytecode.club.bytecodeviewer.Configuration.useNewSettingsDialog;
import static the.bytecode.club.bytecodeviewer.Constants.VERSION;
@ -451,10 +431,12 @@ public class MainViewerGUI extends JFrame
fontSpinner.setPreferredSize(new Dimension(60, 24));
fontSpinner.setMinimumSize(new Dimension(60, 24));
fontSpinner.setModel(new SpinnerNumberModel(12, 1, null, 1));
fontSpinner.addChangeListener(e -> {
fontSpinner.addChangeListener(e ->
{
JSpinner spinner = (JSpinner) e.getSource();
Font font = UIManager.getFont("defaultFont");
if (font == null) {
if (font == null)
{
font = UIManager.getFont("Label.font");
}
@ -473,7 +455,7 @@ public class MainViewerGUI extends JFrame
apkConversionGroup.add(apkConversionEnjarify);
apkConversionGroup.setSelected(apkConversionDex.getModel(), true);
//apkConversionSettingsDialog = new SettingsDialogue(apkConversionSecondaryMenu, new JPanel());
apkConversionSettings.addActionListener((e)-> apkConversionSettingsDialog.showDialog());
apkConversionSettings.addActionListener((e) -> apkConversionSettingsDialog.showDialog());
ButtonGroup rstaGroup = new ButtonGroup();
for (RSTATheme t : RSTATheme.values())
@ -497,7 +479,7 @@ public class MainViewerGUI extends JFrame
}
rstaThemeSettingsDialog = new SettingsDialog(rstaTheme, new JPanel());
rstaThemeSettings.addActionListener((e)-> rstaThemeSettingsDialog.showDialog());
rstaThemeSettings.addActionListener((e) -> rstaThemeSettingsDialog.showDialog());
ButtonGroup lafGroup = new ButtonGroup();
for (LAFTheme theme : LAFTheme.values())
@ -532,7 +514,7 @@ public class MainViewerGUI extends JFrame
}
lafThemeSettingsDialog = new SettingsDialog(lafTheme, new JPanel());
lafThemeSettings.addActionListener((e)-> lafThemeSettingsDialog.showDialog());
lafThemeSettings.addActionListener((e) -> lafThemeSettingsDialog.showDialog());
ButtonGroup languageGroup = new ButtonGroup();
for (Language l : Language.values())
@ -554,7 +536,7 @@ public class MainViewerGUI extends JFrame
}
languageSettingsDialog = new SettingsDialog(language, new JPanel());
languageSettings.addActionListener((e)-> languageSettingsDialog.showDialog());
languageSettings.addActionListener((e) -> languageSettingsDialog.showDialog());
visualSettings.add(useNewSettingsDialog ? lafThemeSettings : lafTheme);
visualSettings.add(useNewSettingsDialog ? rstaThemeSettings : rstaTheme);
@ -582,7 +564,7 @@ public class MainViewerGUI extends JFrame
procyonSettingsSecondaryMenu.add(retainRedunantCasts);
procyonSettingsSecondaryMenu.add(unicodeOutputEnabled);
procyonSettingsDialog = new SettingsDialog(procyonSettingsSecondaryMenu, new JPanel());
procyonSettings.addActionListener((e)-> procyonSettingsDialog.showDialog());
procyonSettings.addActionListener((e) -> procyonSettingsDialog.showDialog());
//CFR SETTINGS
settingsMainMenu.add(useNewSettingsDialog ? cfrSettings : cfrSettingsSecondaryMenu);
@ -631,7 +613,7 @@ public class MainViewerGUI extends JFrame
cfrSettingsSecondaryMenu.add(forceTurningIFs);
cfrSettingsSecondaryMenu.add(forLoopAGGCapture);
cfrSettingsDialog = new SettingsDialog(cfrSettingsSecondaryMenu, new JPanel());
cfrSettings.addActionListener((e)-> cfrSettingsDialog.showDialog());
cfrSettings.addActionListener((e) -> cfrSettingsDialog.showDialog());
//FERNFLOWER SETTINGS
settingsMainMenu.add(useNewSettingsDialog ? fernFlowerSettings : fernFlowerSettingsSecondaryMenu);
@ -655,7 +637,7 @@ public class MainViewerGUI extends JFrame
fernFlowerSettingsSecondaryMenu.add(fdi);
fernFlowerSettingsSecondaryMenu.add(asc);
fernFlowerSettingsDialog = new SettingsDialog(fernFlowerSettingsSecondaryMenu, new JPanel());
fernFlowerSettings.addActionListener((e)-> fernFlowerSettingsDialog.showDialog());
fernFlowerSettings.addActionListener((e) -> fernFlowerSettingsDialog.showDialog());
//CFIDE SETTINGS
settingsMainMenu.add(useNewSettingsDialog ? bytecodeDecompilerSettings : bytecodeDecompilerSettingsSecondaryMenu);
@ -663,7 +645,7 @@ public class MainViewerGUI extends JFrame
bytecodeDecompilerSettingsSecondaryMenu.add(appendBracketsToLabels);
bytecodeDecompilerSettingsSecondaryMenu.add(printLineNumbers);
bytecodeDecompilerSettingsDialog = new SettingsDialog(bytecodeDecompilerSettingsSecondaryMenu, new JPanel());
bytecodeDecompilerSettings.addActionListener((e)-> bytecodeDecompilerSettingsDialog.showDialog());
bytecodeDecompilerSettings.addActionListener((e) -> bytecodeDecompilerSettingsDialog.showDialog());
deleteForeignOutdatedLibs.addActionListener(arg0 -> showForeignLibraryWarning());
forcePureAsciiAsText.addActionListener(arg0 -> SettingsSerializer.saveSettingsAsync());
@ -672,12 +654,14 @@ public class MainViewerGUI extends JFrame
setPython3.addActionListener(arg0 -> ExternalResources.getSingleton().selectPython3());
setOptionalLibrary.addActionListener(arg0 -> ExternalResources.getSingleton().selectOptionalLibraryFolder());
setJavac.addActionListener(arg0 -> ExternalResources.getSingleton().selectJavac());
showFileInTabTitle.addActionListener(arg0 -> {
showFileInTabTitle.addActionListener(arg0 ->
{
Configuration.displayParentInTab = BytecodeViewer.viewer.showFileInTabTitle.isSelected();
SettingsSerializer.saveSettingsAsync();
BytecodeViewer.refreshAllTabTitles();
});
simplifyNameInTabTitle.addActionListener(arg0 -> {
simplifyNameInTabTitle.addActionListener(arg0 ->
{
Configuration.simplifiedTabNames = BytecodeViewer.viewer.simplifyNameInTabTitle.isSelected();
SettingsSerializer.saveSettingsAsync();
BytecodeViewer.refreshAllTabTitles();
@ -844,7 +828,8 @@ public class MainViewerGUI extends JFrame
printLineNumbers.setSelected(false);
}
public void calledAfterLoad() {
public void calledAfterLoad()
{
deleteForeignOutdatedLibs.setSelected(Configuration.deleteForeignLibraries);
}
@ -860,7 +845,7 @@ public class MainViewerGUI extends JFrame
public synchronized void clearBusyStatus()
{
SwingUtilities.invokeLater(()->
SwingUtilities.invokeLater(() ->
{
int length = waitIcons.size();
for (int i = 0; i < length; i++)
@ -881,7 +866,7 @@ public class MainViewerGUI extends JFrame
}
else
{
if(waitIcons.isEmpty())
if (waitIcons.isEmpty())
return;
JMenuItem waitIcon = waitIcons.get(0);
@ -889,7 +874,7 @@ public class MainViewerGUI extends JFrame
rootMenu.remove(waitIcon);
//re-enable the Refresh Button incase it gets stuck
if(waitIcons.isEmpty() && !workPane.refreshClass.isEnabled())
if (waitIcons.isEmpty() && !workPane.refreshClass.isEnabled())
workPane.refreshClass.setEnabled(true);
}
@ -913,9 +898,7 @@ public class MainViewerGUI extends JFrame
public void reloadResources()
{
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.RELOAD_RESOURCES_TITLE.toString(),
TranslatedStrings.RELOAD_RESOURCES_CONFIRM.toString(),
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.RELOAD_RESOURCES_TITLE.toString(), TranslatedStrings.RELOAD_RESOURCES_CONFIRM.toString(), new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
if (dialog.promptChoice() == 0)
{
@ -925,8 +908,7 @@ public class MainViewerGUI extends JFrame
for (ResourceContainer container : BytecodeViewer.resourceContainers.values())
{
File newFile = new File(container.file.getParent() + fs + container.name);
if (!container.file.getAbsolutePath().equals(newFile.getAbsolutePath()) &&
(container.file.getAbsolutePath().endsWith(".apk") || container.file.getAbsolutePath().endsWith(".dex"))) //APKs & dex get renamed
if (!container.file.getAbsolutePath().equals(newFile.getAbsolutePath()) && (container.file.getAbsolutePath().endsWith(".apk") || container.file.getAbsolutePath().endsWith(".dex"))) //APKs & dex get renamed
{
container.file.renameTo(newFile);
container.file = newFile;
@ -948,11 +930,9 @@ public class MainViewerGUI extends JFrame
public void selectFile()
{
final File file = DialogUtils.fileChooser(TranslatedStrings.SELECT_FILE_TITLE.toString(),
TranslatedStrings.SELECT_FILE_DESCRIPTION.toString(),
Constants.SUPPORTED_FILE_EXTENSIONS);
final File file = DialogUtils.fileChooser(TranslatedStrings.SELECT_FILE_TITLE.toString(), TranslatedStrings.SELECT_FILE_DESCRIPTION.toString(), Constants.SUPPORTED_FILE_EXTENSIONS);
if(file == null)
if (file == null)
return;
BytecodeViewer.updateBusyStatus(true);
@ -962,14 +942,9 @@ public class MainViewerGUI extends JFrame
public void openExternalPlugin()
{
final File file = DialogUtils.fileChooser(TranslatedStrings.SELECT_EXTERNAL_PLUGIN_TITLE.toString(),
TranslatedStrings.SELECT_EXTERNAL_PLUGIN_DESCRIPTION.toString(),
Configuration.getLastPluginDirectory(),
PluginManager.fileFilter(),
Configuration::setLastPluginDirectory,
FileChooser.EVERYTHING);
final File file = DialogUtils.fileChooser(TranslatedStrings.SELECT_EXTERNAL_PLUGIN_TITLE.toString(), TranslatedStrings.SELECT_EXTERNAL_PLUGIN_DESCRIPTION.toString(), Configuration.getLastPluginDirectory(), PluginManager.fileFilter(), Configuration::setLastPluginDirectory, FileChooser.EVERYTHING);
if(file == null)
if (file == null)
return;
BytecodeViewer.updateBusyStatus(true);
@ -980,9 +955,7 @@ public class MainViewerGUI extends JFrame
public void askBeforeExiting()
{
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.EXIT_TITLE.toString(),
TranslatedStrings.EXIT_CONFIRM.toString(),
new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
MultipleChoiceDialog dialog = new MultipleChoiceDialog(TranslatedStrings.EXIT_TITLE.toString(), TranslatedStrings.EXIT_CONFIRM.toString(), new String[]{TranslatedStrings.YES.toString(), TranslatedStrings.NO.toString()});
if (dialog.promptChoice() == 0)
{
@ -1003,13 +976,13 @@ public class MainViewerGUI extends JFrame
{
try
{
for(Component viewerComponent : BytecodeViewer.viewer.workPane.tabs.getComponents())
for (Component viewerComponent : BytecodeViewer.viewer.workPane.tabs.getComponents())
{
if(!(viewerComponent instanceof ResourceViewer))
if (!(viewerComponent instanceof ResourceViewer))
continue;
ResourceViewer viewerResource = (ResourceViewer) viewerComponent;
if(!(viewerResource instanceof ClassViewer))
if (!(viewerResource instanceof ClassViewer))
continue;
ClassViewer viewerClass = (ClassViewer) viewerResource;

View File

@ -18,14 +18,14 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.CardLayout;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import the.bytecode.club.bytecodeviewer.bootloader.InitialBootScreen;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import static the.bytecode.club.bytecodeviewer.Configuration.language;
/**

View File

@ -18,17 +18,14 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JSeparator;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.WorkspaceRefreshEvent;
import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBoxMenuItem;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJRadioButtonMenuItem;
import javax.swing.*;
import static the.bytecode.club.bytecodeviewer.gui.components.DecompilerViewComponent.DecompilerComponentType.*;
/**
@ -53,19 +50,19 @@ public class DecompilerViewComponent
this.decompilers = decompilers;
this.java = new TranslatedJRadioButtonMenuItem("Java", TranslatedComponents.JAVA);
this.bytecode = new TranslatedJRadioButtonMenuItem("Bytecode", TranslatedComponents.BYTECODE);
this.editable = new TranslatedJCheckBoxMenuItem( "Editable", TranslatedComponents.EDITABLE);
this.editable = new TranslatedJCheckBoxMenuItem("Editable", TranslatedComponents.EDITABLE);
createMenu();
}
private void createMenu()
{
if(type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
menu.add(java);
if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
menu.add(bytecode);
if(type != JAVA_NON_EDITABLE && type != BYTECODE_NON_EDITABLE)
if (type != JAVA_NON_EDITABLE && type != BYTECODE_NON_EDITABLE)
{
menu.add(new JSeparator());
menu.add(editable);
@ -76,9 +73,9 @@ public class DecompilerViewComponent
public void addToGroup(ButtonGroup group)
{
if(type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE)
group.add(java);
if(type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE)
group.add(bytecode);
}
@ -114,10 +111,6 @@ public class DecompilerViewComponent
public enum DecompilerComponentType
{
JAVA,
JAVA_NON_EDITABLE,
BYTECODE,
BYTECODE_NON_EDITABLE,
JAVA_AND_BYTECODE
JAVA, JAVA_NON_EDITABLE, BYTECODE, BYTECODE_NON_EDITABLE, JAVA_AND_BYTECODE
}
}

View File

@ -18,16 +18,12 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.util.JarUtils;
import javax.swing.*;
import java.awt.*;
/**
* The export as Jar UI.
*

View File

@ -18,27 +18,12 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.HeadlessException;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import static javax.swing.JOptionPane.CLOSED_OPTION;
import static javax.swing.JOptionPane.DEFAULT_OPTION;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
import static javax.swing.JOptionPane.OK_CANCEL_OPTION;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import static javax.swing.JOptionPane.UNINITIALIZED_VALUE;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.getRootFrame;
import javax.swing.*;
import java.awt.*;
import static javax.swing.JOptionPane.*;
/**
* Extends the JOptionPane
@ -51,117 +36,90 @@ import static javax.swing.JOptionPane.getRootFrame;
public class ExtendedJOptionPane
{
public static void showMessageDialog(Component parentComponent,
Object message) throws HeadlessException
public static void showMessageDialog(Component parentComponent, Object message) throws HeadlessException
{
showMessageDialog(parentComponent, message, UIManager.getString(
"OptionPane.messageDialogTitle", parentComponent.getLocale()),
INFORMATION_MESSAGE);
showMessageDialog(parentComponent, message, UIManager.getString("OptionPane.messageDialogTitle", parentComponent.getLocale()), INFORMATION_MESSAGE);
}
public static void showMessageDialog(Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException
public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType) throws HeadlessException
{
showMessageDialog(parentComponent, message, title, messageType, null);
}
public static void showMessageDialog(Component parentComponent,
Object message, String title, int messageType, Icon icon)
throws HeadlessException
public static void showMessageDialog(Component parentComponent, Object message, String title, int messageType, Icon icon) throws HeadlessException
{
showOptionDialog(parentComponent, message, title, DEFAULT_OPTION,
messageType, icon, null, null);
showOptionDialog(parentComponent, message, title, DEFAULT_OPTION, messageType, icon, null, null);
}
public static String showInputDialog(Object message)
throws HeadlessException {
public static String showInputDialog(Object message) throws HeadlessException
{
return showInputDialog(null, message);
}
public static String showInputDialog(Object message, Object initialSelectionValue) {
public static String showInputDialog(Object message, Object initialSelectionValue)
{
return showInputDialog(null, message, initialSelectionValue);
}
public static String showInputDialog(Component parentComponent,
Object message) throws HeadlessException {
return showInputDialog(parentComponent, message, UIManager.getString(
"OptionPane.inputDialogTitle", parentComponent.getLocale()), QUESTION_MESSAGE);
}
public static String showInputDialog(Component parentComponent, Object message,
Object initialSelectionValue) {
return (String)showInputDialog(parentComponent, message,
UIManager.getString("OptionPane.inputDialogTitle",
parentComponent.getLocale()), QUESTION_MESSAGE, null, null,
initialSelectionValue);
}
public static String showInputDialog(Component parentComponent,
Object message, String title, int messageType)
throws HeadlessException {
return (String)showInputDialog(parentComponent, message, title,
messageType, null, null, null);
}
public static int showOptionDialog(Component parentComponent,
Object message, String title, int optionType, int messageType,
Icon icon, Object[] options, Object initialValue)
throws HeadlessException
public static String showInputDialog(Component parentComponent, Object message) throws HeadlessException
{
JOptionPane pane = new JOptionPane(message, messageType,
optionType, icon,
options, initialValue);
return showInputDialog(parentComponent, message, UIManager.getString("OptionPane.inputDialogTitle", parentComponent.getLocale()), QUESTION_MESSAGE);
}
public static String showInputDialog(Component parentComponent, Object message, Object initialSelectionValue)
{
return (String) showInputDialog(parentComponent, message, UIManager.getString("OptionPane.inputDialogTitle", parentComponent.getLocale()), QUESTION_MESSAGE, null, null, initialSelectionValue);
}
public static String showInputDialog(Component parentComponent, Object message, String title, int messageType) throws HeadlessException
{
return (String) showInputDialog(parentComponent, message, title, messageType, null, null, null);
}
public static int showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue) throws HeadlessException
{
JOptionPane pane = new JOptionPane(message, messageType, optionType, icon, options, initialValue);
pane.setInitialValue(initialValue);
pane.setComponentOrientation(((parentComponent == null) ?
getRootFrame() : parentComponent).getComponentOrientation());
pane.setComponentOrientation(((parentComponent == null) ? getRootFrame() : parentComponent).getComponentOrientation());
int style = styleFromMessageType(messageType);
JDialog dialog = createNewJDialog(parentComponent, pane, title, style, (d)->
pane.selectInitialValue());
JDialog dialog = createNewJDialog(parentComponent, pane, title, style, (d) -> pane.selectInitialValue());
pane.selectInitialValue();
Object selectedValue = pane.getValue();
if(selectedValue == null)
if (selectedValue == null)
return CLOSED_OPTION;
if(options == null)
if (options == null)
{
if(selectedValue instanceof Integer)
if (selectedValue instanceof Integer)
return (Integer) selectedValue;
return CLOSED_OPTION;
}
for(int counter = 0, maxCounter = options.length;
counter < maxCounter; counter++)
for (int counter = 0, maxCounter = options.length; counter < maxCounter; counter++)
{
if(options[counter].equals(selectedValue))
if (options[counter].equals(selectedValue))
return counter;
}
return CLOSED_OPTION;
}
public static Object showInputDialog(Component parentComponent,
Object message, String title, int messageType, Icon icon,
Object[] selectionValues, Object initialSelectionValue)
throws HeadlessException {
JOptionPane pane = new JOptionPane(message, messageType,
OK_CANCEL_OPTION, icon,
null, null);
public static Object showInputDialog(Component parentComponent, Object message, String title, int messageType, Icon icon, Object[] selectionValues, Object initialSelectionValue) throws HeadlessException
{
JOptionPane pane = new JOptionPane(message, messageType, OK_CANCEL_OPTION, icon, null, null);
pane.setWantsInput(true);
pane.setSelectionValues(selectionValues);
pane.setInitialSelectionValue(initialSelectionValue);
pane.setComponentOrientation(((parentComponent == null) ?
getRootFrame() : parentComponent).getComponentOrientation());
pane.setComponentOrientation(((parentComponent == null) ? getRootFrame() : parentComponent).getComponentOrientation());
int style = styleFromMessageType(messageType);
JDialog dialog = createNewJDialog(parentComponent, pane, title, style, (d)->
pane.selectInitialValue());
JDialog dialog = createNewJDialog(parentComponent, pane, title, style, (d) -> pane.selectInitialValue());
pane.selectInitialValue();
@ -173,20 +131,19 @@ public class ExtendedJOptionPane
return value;
}
public static void showJPanelDialog(Component parentComponent, JScrollPane panel, int minimumHeight, OnCreate onCreate)
throws HeadlessException
public static void showJPanelDialog(Component parentComponent, JScrollPane panel, int minimumHeight, OnCreate onCreate) throws HeadlessException
{
//create a new option pane with a empty text and just 'ok'
JOptionPane pane = new JOptionPane("");
pane.add(panel, 0);
JDialog dialog = createNewJDialog(parentComponent, pane, panel.getName(), ERROR_MESSAGE, (d)->
JDialog dialog = createNewJDialog(parentComponent, pane, panel.getName(), ERROR_MESSAGE, (d) ->
{
int newHeight = Math.min(minimumHeight, d.getHeight());
d.setMinimumSize(new Dimension(d.getWidth(), newHeight));
d.setSize(new Dimension(d.getWidth(), newHeight));
if(onCreate != null)
if (onCreate != null)
onCreate.onCreate(d);
});
}
@ -194,10 +151,11 @@ public class ExtendedJOptionPane
private static JDialog createNewJDialog(Component parentComponent, JOptionPane pane, String title, int style, OnCreate onCreate)
{
JDialog dialog = pane.createDialog(parentComponent, title);
if (JDialog.isDefaultLookAndFeelDecorated()) {
boolean supportsWindowDecorations =
UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations) {
if (JDialog.isDefaultLookAndFeelDecorated())
{
boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations)
{
dialog.setUndecorated(true);
pane.getRootPane().setWindowDecorationStyle(style);
}

View File

@ -18,13 +18,14 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
/**
* @author Konloch
@ -44,14 +45,18 @@ public class FileChooser extends JFileChooser
Set<String> extensionSet = new HashSet<>(Arrays.asList(extensions));
setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
try {
try
{
setSelectedFile(file);
} catch (Exception ignored) { }
}
catch (Exception ignored)
{
}
setDialogTitle(title);
setFileHidingEnabled(false);
setAcceptAllFileFilterUsed(false);
if(!skipFileFilter)
if (!skipFileFilter)
{
addChoosableFileFilter(new FileFilter()
{
@ -61,14 +66,15 @@ public class FileChooser extends JFileChooser
if (f.isDirectory())
return true;
if(extensions[0].equals(EVERYTHING))
if (extensions[0].equals(EVERYTHING))
return true;
return extensionSet.contains(MiscUtils.extension(f.getAbsolutePath()));
}
@Override
public String getDescription() {
public String getDescription()
{
return description;
}
});

View File

@ -18,20 +18,16 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import javax.swing.JEditorPane;
import javax.swing.text.html.HTMLEditorKit;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.bootloader.InitialBootScreen;
import static the.bytecode.club.bytecodeviewer.Constants.BCVDir;
import static the.bytecode.club.bytecodeviewer.Constants.FAT_JAR;
import static the.bytecode.club.bytecodeviewer.Constants.enjarifyVersion;
import static the.bytecode.club.bytecodeviewer.Constants.enjarifyWorkingDirectory;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauVersion;
import static the.bytecode.club.bytecodeviewer.Constants.krakatauWorkingDirectory;
import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import static the.bytecode.club.bytecodeviewer.Constants.*;
/**
* @author Konloch
@ -47,7 +43,8 @@ public class HTMLPane extends JEditorPane
public static HTMLPane fromResource(String resourcePath) throws IOException
{
try (InputStream is = InitialBootScreen.class.getClassLoader().getResourceAsStream(resourcePath)) {
try (InputStream is = InitialBootScreen.class.getClassLoader().getResourceAsStream(resourcePath))
{
return fromString(convertStreamToString(is));
}
}
@ -63,7 +60,7 @@ public class HTMLPane extends JEditorPane
text = text.replace("{java}", Configuration.java);
text = text.replace("{javac}", Configuration.javac);
text = text.replace("{bcvDir}", BCVDir.getAbsolutePath());
text = text.replace("{python}", Configuration.python2+" " + (Configuration.python2Extra ? "-2" : ""));
text = text.replace("{python}", Configuration.python2 + " " + (Configuration.python2Extra ? "-2" : ""));
text = text.replace("{python3}", Configuration.python3 + " " + (Configuration.python3Extra ? "-3" : ""));
text = text.replace("{rt}", Configuration.rt);
text = text.replace("{lib}", Configuration.library);
@ -82,8 +79,8 @@ public class HTMLPane extends JEditorPane
{
if (is == null)
return null;
try (InputStream stream = is;
Scanner s = new Scanner(stream, "UTF-8").useDelimiter("\\A")) {
try (InputStream stream = is; Scanner s = new Scanner(stream, "UTF-8").useDelimiter("\\A"))
{
return s.hasNext() ? s.next() : "";
}
}

View File

@ -18,9 +18,8 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
/**
* Display an image on a JLabel element

View File

@ -18,13 +18,13 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import javax.swing.JFrame;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory;
/**
@ -63,10 +63,7 @@ public class JFrameConsole extends JFrame
*/
public void appendText(String t)
{
setText((textArea.getText().isEmpty()
? ""
: textArea.getText() + "\r\n"
) + t);
setText((textArea.getText().isEmpty() ? "" : textArea.getText() + "\r\n") + t);
}
/**
@ -129,14 +126,14 @@ public class JFrameConsole extends JFrame
//TODO this should also be a setting eventually
int max = 500_000;
if(len >= max)
if (len >= max)
{
//TODO if two consoles are ran at the same time and exceed the maximum this file will be overwritten
final File tempFile = new File(tempDirectory, "console_" + consoleID + ".log");
//TODO this needs to be rewritten, it doesn't work for a plugin that causes multiple exception UIs
new Thread(()->
new Thread(() ->
{
//save to disk
DiskWriter.replaceFile(tempFile.getAbsolutePath(), s, false);
@ -146,10 +143,8 @@ public class JFrameConsole extends JFrame
int skipped = len - max;
String trimmed = s.substring(0, max);
if(!trimmed.startsWith("WARNING: Skipping"))
trimmed = ("WARNING: Skipping " + skipped + " chars, allowing " + max + "\n\r")
+ "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r\n\r"
+ trimmed;
if (!trimmed.startsWith("WARNING: Skipping"))
trimmed = ("WARNING: Skipping " + skipped + " chars, allowing " + max + "\n\r") + "Full log saved to: " + tempFile.getAbsolutePath() + "\n\r\n\r" + trimmed;
return trimmed;
}

View File

@ -18,10 +18,11 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.io.PrintStream;
import javax.swing.SwingUtilities;
import the.bytecode.club.bytecodeviewer.Constants;
import javax.swing.*;
import java.io.PrintStream;
import static the.bytecode.club.bytecodeviewer.Constants.nl;
/**
@ -59,7 +60,7 @@ public class JFrameConsolePrintStream extends JFrameConsole
{
super.setVisible(b);
if(b && updateThread == null)
if (b && updateThread == null)
{
updateThread = new Thread(() ->
{
@ -67,9 +68,13 @@ public class JFrameConsolePrintStream extends JFrameConsole
{
update();
try {
try
{
Thread.sleep(10);
} catch (InterruptedException ignored) { }
}
catch (InterruptedException ignored)
{
}
}
lastUpdate = 0;
@ -99,16 +104,16 @@ public class JFrameConsolePrintStream extends JFrameConsole
private void update()
{
if(System.currentTimeMillis()-lastUpdate <= 50)
if (System.currentTimeMillis() - lastUpdate <= 50)
return;
lastUpdate = System.currentTimeMillis();
//update only if required
if(textAreaOutputStreamErr.noUpdateRequired() && textAreaOutputStreamOut.noUpdateRequired())
if (textAreaOutputStreamErr.noUpdateRequired() && textAreaOutputStreamOut.noUpdateRequired())
return;
SwingUtilities.invokeLater(()->
SwingUtilities.invokeLater(() ->
{
//print output to the pane
textAreaOutputStreamOut.update();
@ -118,7 +123,7 @@ public class JFrameConsolePrintStream extends JFrameConsole
//reformat the pane
String content = getTextArea().getText();
if(content.contains("File `"))
if (content.contains("File `"))
{
String[] test = content.split("\r?\n");

View File

@ -18,13 +18,11 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JTabbedPane;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import javax.swing.*;
import java.awt.*;
/**
* @author Konloch
* @since 7/14/2021

View File

@ -18,11 +18,8 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.Icon;
import javax.swing.JMenuItem;
import javax.swing.UIManager;
import javax.swing.*;
import java.awt.*;
/**
* @author Konloch
@ -36,7 +33,7 @@ public class JMenuItemIcon extends JMenuItem
setIcon(icon);
setAlignmentY(0.65f);
Dimension size = new Dimension((int) (icon.getIconWidth()*1.4), icon.getIconHeight());
Dimension size = new Dimension((int) (icon.getIconWidth() * 1.4), icon.getIconHeight());
setSize(size);
setPreferredSize(size);
setMinimumSize(size);

View File

@ -18,10 +18,10 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import javax.swing.*;
import java.io.Closeable;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JTextArea;
/**
* @author Konloch
@ -54,7 +54,7 @@ public class JTextAreaOutputStream extends OutputStream implements Closeable
public void write(int b)
{
sb.append((char) b);
if(og != null)
if (og != null)
og.write(b);
}
@ -64,7 +64,8 @@ public class JTextAreaOutputStream extends OutputStream implements Closeable
}
@Override
public void close() {
public void close()
{
if (og != null)
og.close();
}

View File

@ -18,8 +18,8 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.*;
import java.awt.*;
/**
* @author Konloch

View File

@ -18,16 +18,14 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Component;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.BytecodeViewPanel;
import the.bytecode.club.bytecodeviewer.gui.util.BytecodeViewPanelUpdater;
import the.bytecode.club.bytecodeviewer.util.MethodParser;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* @author Konloch
* @author Waterwolf
@ -44,16 +42,18 @@ public class MethodsRenderer extends JLabel implements ListCellRenderer<Object>
}
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
boolean cellHasFocus)
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)
{
int methodIndex = (Integer) value;
MethodParser methods;
List<MethodParser> methodParsers = bytecodeViewPanelUpdater.viewer.methods;
BytecodeViewPanel bytecodeViewPanel = bytecodeViewPanelUpdater.bytecodeViewPanel;
try {
try
{
methods = methodParsers.get(bytecodeViewPanel.decompiler.ordinal());
} catch (ArrayIndexOutOfBoundsException e) {
}
catch (ArrayIndexOutOfBoundsException e)
{
methods = methodParsers.get(bytecodeViewPanel.panelIndex);
}
MethodParser.Method method = methods.getMethod(methodIndex);

View File

@ -18,10 +18,10 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import javax.swing.*;
/**
* @author Konloch
* @since 6/26/2021

View File

@ -122,7 +122,8 @@ public class MyErrorStripe extends JPanel
try
{
line = textArea.getLineOfOffset(range.getStartOffset());
} catch (BadLocationException e)
}
catch (BadLocationException e)
{
continue;
}
@ -136,7 +137,8 @@ public class MyErrorStripe extends JPanel
m.addMouseListener(listener);
markerMap.put(key, m);
add(m);
} else
}
else
{
if (!m.containsMarkedOccurrence())
m.addNotice(notice);
@ -214,7 +216,8 @@ public class MyErrorStripe extends JPanel
int offset = textArea.getLineOfOffset(line);
textArea.setCaretPosition(offset);
RSyntaxUtilities.selectAndPossiblyCenter(textArea, new DocumentRange(offset, offset), false);
} catch (BadLocationException exception)
}
catch (BadLocationException exception)
{
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}
@ -263,7 +266,8 @@ public class MyErrorStripe extends JPanel
try
{
return textArea.getLineOfOffset(range.getStartOffset()) + 1;
} catch (BadLocationException e)
}
catch (BadLocationException e)
{
return 0;
}
@ -362,7 +366,8 @@ public class MyErrorStripe extends JPanel
{
DocumentRange range = new DocumentRange(offs, offs + len);
RSyntaxUtilities.selectAndPossiblyCenter(textArea, range, true);
} else
}
else
{
int line = pn.getLine();
try
@ -370,7 +375,8 @@ public class MyErrorStripe extends JPanel
offs = textArea.getLineStartOffset(line);
textArea.getFoldManager().ensureOffsetNotInClosedFold(offs);
textArea.setCaretPosition(offs);
} catch (BadLocationException ble) // Never happens
}
catch (BadLocationException ble) // Never happens
{
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
}

View File

@ -18,17 +18,14 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import the.bytecode.club.bytecodeviewer.api.ASMResourceUtil;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import javax.swing.*;
import java.awt.*;
/**
* The UI for File>Run aka EZ-Injection plugin.
*
@ -114,16 +111,9 @@ public class RunOptions extends JFrame
printToCommandLine.setBounds(6, 315, 232, 23);
getContentPane().add(printToCommandLine);
this.setLocationRelativeTo(null);
btnNewButton.addActionListener(arg0 -> {
PluginManager.runPlugin(new EZInjection(accessModifiers
.isSelected(), injectHooks.isSelected(),
debugMethodCalls.isSelected(), invokeMethod
.isSelected(),
mainMethodFQN.getText(), false, false, debugClasses
.getText(), this.socksProxy.getText(), forceProxy
.isSelected(),
launchReflectionKit.isSelected(), console.isSelected(),
printToCommandLine.isSelected()));
btnNewButton.addActionListener(arg0 ->
{
PluginManager.runPlugin(new EZInjection(accessModifiers.isSelected(), injectHooks.isSelected(), debugMethodCalls.isSelected(), invokeMethod.isSelected(), mainMethodFQN.getText(), false, false, debugClasses.getText(), this.socksProxy.getText(), forceProxy.isSelected(), launchReflectionKit.isSelected(), console.isSelected(), printToCommandLine.isSelected()));
dispose();
});
}

View File

@ -18,18 +18,6 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.GlobalHotKeys;
import the.bytecode.club.bytecodeviewer.gui.components.listeners.PressKeyListener;
@ -39,6 +27,12 @@ import the.bytecode.club.bytecodeviewer.translation.TranslatedComponents;
import the.bytecode.club.bytecodeviewer.translation.components.TranslatedJCheckBox;
import the.bytecode.club.bytecodeviewer.util.JTextAreaUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseWheelListener;
/**
* Searching on a JTextArea using swing highlighting
*
@ -93,7 +87,8 @@ public class SearchableJTextArea extends JTextArea
//set number-bar font
setFont(newFont);
SwingUtilities.invokeLater(()-> {
SwingUtilities.invokeLater(() ->
{
//attach CTRL + Mouse Wheel Zoom
attachCtrlMouseWheelZoom();
@ -115,11 +110,10 @@ public class SearchableJTextArea extends JTextArea
public void attachCtrlMouseWheelZoom()
{
//get the existing scroll event
MouseWheelListener ogListener = scrollPane.getMouseWheelListeners().length > 0 ?
scrollPane.getMouseWheelListeners()[0] : null;
MouseWheelListener ogListener = scrollPane.getMouseWheelListeners().length > 0 ? scrollPane.getMouseWheelListeners()[0] : null;
//remove the existing event
if(ogListener != null)
if (ogListener != null)
scrollPane.removeMouseWheelListener(ogListener);
//add a new event
@ -140,7 +134,7 @@ public class SearchableJTextArea extends JTextArea
e.consume();
}
else if(ogListener != null)
else if (ogListener != null)
{
ogListener.mouseWheelMoved(e);
}

View File

@ -58,7 +58,8 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
scrollPane.getHorizontalScrollBar().setForeground(blackScrollForeground);
scrollPane.getVerticalScrollBar().setBackground(blackScrollBackground);
scrollPane.getVerticalScrollBar().setForeground(blackScrollForeground);
} else if (Configuration.lafTheme.isDark())
}
else if (Configuration.lafTheme.isDark())
{
//this fixes the white border on the jScrollBar panes
scrollPane.getHorizontalScrollBar().setBackground(darkScrollBackground);
@ -108,7 +109,8 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
//set number-bar font
setFont(newFont);
SwingUtilities.invokeLater(() -> {
SwingUtilities.invokeLater(() ->
{
//attach CTRL + Mouse Wheel Zoom
attachCtrlMouseWheelZoom();
@ -130,8 +132,10 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
public void attachCtrlMouseWheelZoom()
{
scrollPane.addMouseWheelListener(e -> {
if (getText().isEmpty()) return;
scrollPane.addMouseWheelListener(e ->
{
if (getText().isEmpty())
return;
if ((e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0)
{
Font font = getFont();
@ -176,7 +180,8 @@ public class SearchableRSyntaxTextArea extends RSyntaxTextArea
int end = getLineEndOffset(line);
return getText(start, end - start).trim();
}
} catch (BadLocationException ignored)
}
catch (BadLocationException ignored)
{
}
return "";

View File

@ -18,16 +18,10 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import java.awt.Component;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import static the.bytecode.club.bytecodeviewer.Configuration.useNewSettingsDialog;
@ -51,13 +45,13 @@ public class SettingsDialog extends JScrollPane
this.menu = menu;
this.display = display;
if(!useNewSettingsDialog)
if (!useNewSettingsDialog)
return;
List<JMenuItem> options = new ArrayList<>();
for(Component child : menu.getMenuComponents())
for (Component child : menu.getMenuComponents())
{
if(!(child instanceof JMenuItem))
if (!(child instanceof JMenuItem))
continue;
JMenuItem menuItem = (JMenuItem) child;
@ -89,14 +83,14 @@ public class SettingsDialog extends JScrollPane
private void buildPanel()
{
display.setLayout(new BoxLayout(display, BoxLayout.Y_AXIS));
for(JMenuItem menuItem : options)
for (JMenuItem menuItem : options)
display.add(menuItem);
}
@Override
public String getName()
{
if(menu == null)
if (menu == null)
return "ERROR: Dialog missing menu";
return menu.getText();

View File

@ -19,12 +19,12 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import com.github.weisj.darklaf.iconset.AllIcons;
import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.theme.LAFTheme;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import javax.swing.*;
/**
* Used to represent all the panes inside of Bytecode Viewer.
*
@ -42,7 +42,8 @@ public abstract class VisibleComponent extends JInternalFrame
}
@Override
public void updateUI() {
public void updateUI()
{
if (Configuration.lafTheme != LAFTheme.SYSTEM)
setBorder(BorderFactory.createEmptyBorder());
else
@ -52,12 +53,15 @@ public abstract class VisibleComponent extends JInternalFrame
public void setDefaultIcon()
{
try {
if(Configuration.showDarkLAFComponentIcons)
try
{
if (Configuration.showDarkLAFComponentIcons)
setFrameIcon(AllIcons.Window.Frame.get(16, 16));
else
setFrameIcon(IconResources.jarIcon);
} catch (Exception e) {
}
catch (Exception e)
{
e.printStackTrace();
}
}

View File

@ -18,15 +18,11 @@
package the.bytecode.club.bytecodeviewer.gui.components;
import javax.swing.Icon;
import com.github.weisj.darklaf.components.RotatableIconAnimator;
import com.github.weisj.darklaf.components.loading.LoadingIndicator;
import com.github.weisj.darklaf.iconset.AllIcons;
import com.github.weisj.darklaf.properties.icons.RotatableIcon;
import the.bytecode.club.bytecodeviewer.resources.IconResources;
import java.awt.event.*;
import java.awt.event.HierarchyEvent;
/**
* @author Konloch
@ -40,7 +36,8 @@ public class WaitBusyIcon extends JMenuItemIcon
{
super(new RotatableIcon(IconResources.busyIcon));
animator = new RotatableIconAnimator(8, (RotatableIcon) getIcon(), this);
addHierarchyListener(e -> {
addHierarchyListener(e ->
{
if ((e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) != 0)
{
if (getParent() == null)

View File

@ -42,7 +42,8 @@ public class GoToAction extends AbstractAction
int line = textArea.getCaretLineNumber() + 1;
int column = textArea.getCaretOffsetFromLineStart();
container.fieldMembers.values().forEach(fields -> fields.forEach(field -> {
container.fieldMembers.values().forEach(fields -> fields.forEach(field ->
{
if (field.line == line && field.columnStart - 1 <= column && field.columnEnd >= column)
{
Element root = textArea.getDocument().getDefaultRootElement();
@ -59,7 +60,8 @@ public class GoToAction extends AbstractAction
}
}));
container.methodParameterMembers.values().forEach(parameters -> parameters.forEach(parameter -> {
container.methodParameterMembers.values().forEach(parameters -> parameters.forEach(parameter ->
{
if (parameter.line == line && parameter.columnStart - 1 <= column && parameter.columnEnd >= column)
{
Element root = textArea.getDocument().getDefaultRootElement();
@ -67,10 +69,12 @@ public class GoToAction extends AbstractAction
{
int startOffset = root.getElement(parameter.line - 1).getStartOffset() + (parameter.columnStart - 1);
textArea.setCaretPosition(startOffset);
} else
}
else
{
String method = parameter.method;
parameters.stream().filter(classParameterLocation -> classParameterLocation.method.equals(method)).forEach(classParameterLocation -> {
parameters.stream().filter(classParameterLocation -> classParameterLocation.method.equals(method)).forEach(classParameterLocation ->
{
if (classParameterLocation.decRef.equalsIgnoreCase("declaration"))
{
int startOffset = root.getElement(classParameterLocation.line - 1).getStartOffset() + (classParameterLocation.columnStart - 1);
@ -81,7 +85,8 @@ public class GoToAction extends AbstractAction
}
}));
container.methodLocalMembers.values().forEach(localMembers -> localMembers.forEach(localMember -> {
container.methodLocalMembers.values().forEach(localMembers -> localMembers.forEach(localMember ->
{
if (localMember.line == line && localMember.columnStart - 1 <= column && localMember.columnEnd >= column)
{
Element root = textArea.getDocument().getDefaultRootElement();
@ -89,10 +94,12 @@ public class GoToAction extends AbstractAction
{
int startOffset = root.getElement(localMember.line - 1).getStartOffset() + (localMember.columnStart - 1);
textArea.setCaretPosition(startOffset);
} else
}
else
{
String method = localMember.method;
localMembers.stream().filter(classLocalVariableLocation -> classLocalVariableLocation.method.equals(method)).forEach(classLocalVariableLocation -> {
localMembers.stream().filter(classLocalVariableLocation -> classLocalVariableLocation.method.equals(method)).forEach(classLocalVariableLocation ->
{
if (classLocalVariableLocation.decRef.equalsIgnoreCase("declaration"))
{
int startOffset = root.getElement(classLocalVariableLocation.line - 1).getStartOffset() + (classLocalVariableLocation.columnStart - 1);
@ -103,7 +110,8 @@ public class GoToAction extends AbstractAction
}
}));
container.methodMembers.values().forEach(methods -> methods.forEach(method -> {
container.methodMembers.values().forEach(methods -> methods.forEach(method ->
{
if (method.line == line && method.columnStart - 1 <= column && method.columnEnd >= column)
{
Element root = textArea.getDocument().getDefaultRootElement();
@ -111,9 +119,11 @@ public class GoToAction extends AbstractAction
{
int startOffset = root.getElement(method.line - 1).getStartOffset() + (method.columnStart - 1);
textArea.setCaretPosition(startOffset);
} else
}
else
{
methods.stream().filter(classMethodLocation -> classMethodLocation.owner.equals(method.owner)).forEach(classMethodLocation ->
{
methods.stream().filter(classMethodLocation -> classMethodLocation.owner.equals(method.owner)).forEach(classMethodLocation -> {
if (classMethodLocation.decRef.equalsIgnoreCase("declaration"))
{
int startOffset = root.getElement(classMethodLocation.line - 1).getStartOffset() + (classMethodLocation.columnStart - 1);
@ -127,7 +137,8 @@ public class GoToAction extends AbstractAction
}
}));
container.classReferences.values().forEach(classes -> classes.forEach(clazz -> {
container.classReferences.values().forEach(classes -> classes.forEach(clazz ->
{
String name;
if (clazz.line == line && clazz.columnStart - 1 <= column && clazz.columnEnd - 1 >= column)
{
@ -137,9 +148,11 @@ public class GoToAction extends AbstractAction
{
int startOffset = root.getElement(clazz.line - 1).getStartOffset() + (clazz.columnStart - 1);
textArea.setCaretPosition(startOffset);
} else
}
else
{
classes.stream().filter(classReferenceLocation -> classReferenceLocation.owner.equals(name)).forEach(classReferenceLocation ->
{
classes.stream().filter(classReferenceLocation -> classReferenceLocation.owner.equals(name)).forEach(classReferenceLocation -> {
if (classReferenceLocation.type.equals("declaration"))
{
int startOffset = root.getElement(classReferenceLocation.line - 1).getStartOffset() + (classReferenceLocation.columnStart - 1);
@ -170,14 +183,16 @@ public class GoToAction extends AbstractAction
ClassViewer activeResource = (ClassViewer) BytecodeViewer.viewer.workPane.getActiveResource();
HashMap<String, ClassFileContainer> classFiles = BytecodeViewer.viewer.workPane.classFiles;
return wait(classFiles, activeResource);
} else if (method)
}
else if (method)
{
ClassMethodLocation classMethodLocation = container.getMethodLocationsFor(lexeme).get(0);
ClassReferenceLocation classReferenceLocation = null;
try
{
classReferenceLocation = container.getClassReferenceLocationsFor(classMethodLocation.owner).get(0);
} catch (Exception ignored)
}
catch (Exception ignored)
{
}
@ -196,7 +211,8 @@ public class GoToAction extends AbstractAction
HashMap<String, ClassFileContainer> classFiles = BytecodeViewer.viewer.workPane.classFiles;
return wait(classFiles, activeResource);
}
} else
}
else
{
ClassReferenceLocation classReferenceLocation = container.getClassReferenceLocationsFor(lexeme).get(0);
String packagePath = classReferenceLocation.packagePath;
@ -218,7 +234,8 @@ public class GoToAction extends AbstractAction
private void open(RSyntaxTextArea textArea, boolean isClass, boolean isField, boolean isMethod)
{
Thread thread = new Thread(() -> {
Thread thread = new Thread(() ->
{
Token token = textArea.modelToToken(textArea.getCaretPosition());
token = TokenUtil.getToken(textArea, token);
String lexeme = token.getLexeme();
@ -229,10 +246,12 @@ public class GoToAction extends AbstractAction
if (classFileContainer == null)
return;
classFileContainer.classReferences.forEach((className, classReference) -> {
classFileContainer.classReferences.forEach((className, classReference) ->
{
if (className.equals(lexeme))
{
classReference.forEach(classReferenceLocation -> {
classReference.forEach(classReferenceLocation ->
{
if (classReferenceLocation.type.equals("declaration"))
{
moveCursor(classReferenceLocation.line, classReferenceLocation.columnStart);
@ -240,16 +259,19 @@ public class GoToAction extends AbstractAction
});
}
});
} else if (isField)
}
else if (isField)
{
classFileContainer = openClass(lexeme, true, false);
if (classFileContainer == null)
return;
classFileContainer.fieldMembers.forEach((fieldName, fields) -> {
classFileContainer.fieldMembers.forEach((fieldName, fields) ->
{
if (fieldName.equals(lexeme))
{
fields.forEach(classFieldLocation -> {
fields.forEach(classFieldLocation ->
{
if (classFieldLocation.type.equals("declaration"))
{
moveCursor(classFieldLocation.line, classFieldLocation.columnStart);
@ -257,16 +279,19 @@ public class GoToAction extends AbstractAction
});
}
});
} else if (isMethod)
}
else if (isMethod)
{
classFileContainer = openClass(lexeme, false, true);
if (classFileContainer == null)
return;
classFileContainer.methodMembers.forEach((methodName, methods) -> {
classFileContainer.methodMembers.forEach((methodName, methods) ->
{
if (methodName.equals(lexeme))
{
methods.forEach(method -> {
methods.forEach(method ->
{
if (method.decRef.equalsIgnoreCase("declaration"))
{
moveCursor(method.line, method.columnStart);
@ -285,22 +310,26 @@ public class GoToAction extends AbstractAction
try
{
BytecodeViewer.updateBusyStatus(true);
Thread.getAllStackTraces().forEach((name, stackTrace) -> {
Thread.getAllStackTraces().forEach((name, stackTrace) ->
{
if (name.getName().equals("Pane Update"))
{
try
{
name.join();
} catch (InterruptedException e)
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
});
} catch (Exception e)
}
catch (Exception e)
{
throw new RuntimeException(e);
} finally
}
finally
{
BytecodeViewer.updateBusyStatus(false);
}

View File

@ -20,7 +20,6 @@ package the.bytecode.club.bytecodeviewer.gui.components.listeners;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* @author Konloch
@ -36,7 +35,8 @@ public class MouseClickedListener extends MouseAdapter
}
@Override
public void mouseClicked(MouseEvent e) {
public void mouseClicked(MouseEvent e)
{
mouseClickedEvent.mouseClicked(e);
super.mouseClicked(e);
}

View File

@ -29,10 +29,15 @@ public class PressKeyListener implements KeyListener
{
private final KeyPressedEvent keyPressedEvent;
public PressKeyListener(KeyPressedEvent keyPressedEvent) {this.keyPressedEvent = keyPressedEvent;}
public PressKeyListener(KeyPressedEvent keyPressedEvent)
{
this.keyPressedEvent = keyPressedEvent;
}
@Override
public void keyTyped(KeyEvent e) { }
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
@ -41,7 +46,9 @@ public class PressKeyListener implements KeyListener
}
@Override
public void keyReleased(KeyEvent e) {}
public void keyReleased(KeyEvent e)
{
}
public interface KeyPressedEvent
{

View File

@ -29,13 +29,20 @@ public class ReleaseKeyListener implements KeyListener
{
private final KeyReleasedEvent keyReleasedEvent;
public ReleaseKeyListener(KeyReleasedEvent keyReleasedEvent) {this.keyReleasedEvent = keyReleasedEvent;}
public ReleaseKeyListener(KeyReleasedEvent keyReleasedEvent)
{
this.keyReleasedEvent = keyReleasedEvent;
}
@Override
public void keyTyped(KeyEvent e) { }
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e) { }
public void keyPressed(KeyEvent e)
{
}
@Override
public void keyReleased(KeyEvent e)

View File

@ -18,11 +18,12 @@
package the.bytecode.club.bytecodeviewer.gui.contextmenu;
import javax.swing.JPopupMenu;
import javax.swing.tree.TreePath;
import the.bytecode.club.bytecodeviewer.gui.resourcelist.ResourceTree;
import the.bytecode.club.bytecodeviewer.searching.LDCSearchTreeNodeResult;
import javax.swing.*;
import javax.swing.tree.TreePath;
/**
* @author Konloch
* @since 7/26/2021

View File

@ -18,21 +18,16 @@
package the.bytecode.club.bytecodeviewer.gui.contextmenu;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPopupMenu;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.Collapse;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.Expand;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.New;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.Open;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.QuickEdit;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.QuickOpen;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.Delete;
import the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist.*;
import the.bytecode.club.bytecodeviewer.gui.resourcelist.ResourceTree;
import the.bytecode.club.bytecodeviewer.searching.LDCSearchTreeNodeResult;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.List;
/**
* @author Konloch
* @since 7/26/2021
@ -73,35 +68,35 @@ public class ContextMenu
boolean isResourceSelected = false;
//TODO this is hacky - there is probably a better way to do this
if(!searchBoxPane)
if (!searchBoxPane)
{
tree.setSelectionPath(selPath);
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
isResourceSelected = !node.children().hasMoreElements();
}
for(ContextMenuItem item : SINGLETON.contextMenuItems)
for (ContextMenuItem item : SINGLETON.contextMenuItems)
{
switch(item.getMenuType())
switch (item.getMenuType())
{
case CONTAINER:
if(!isContainerSelected)
if (!isContainerSelected)
continue;
break;
case RESOURCE:
if(!isResourceSelected || isContainerSelected)
if (!isResourceSelected || isContainerSelected)
continue;
break;
case DIRECTORY:
if(isResourceSelected || searchBoxPane)
if (isResourceSelected || searchBoxPane)
continue;
break;
case RESOURCE_LIST:
if(searchBoxPane)
if (searchBoxPane)
continue;
break;
case SEARCH_BOX_RESULT:
if(!searchBoxPane)
if (!searchBoxPane)
continue;
break;
}

Some files were not shown because too many files have changed in this diff Show More