diff --git a/README.txt b/README.txt index f9a3de36..1a26d884 100644 --- a/README.txt +++ b/README.txt @@ -30,6 +30,7 @@ Contributors: Afffsdd Szperak Zooty + samczsun If I missed you, please feel free to contact me @Konloch or konloch@gmail.com Contribution Guide Lines/Coding Conventions: diff --git a/src/main/java/com/jhe/hexed/JHexEditorASCII.java b/src/main/java/com/jhe/hexed/JHexEditorASCII.java index 9ac9747f..0631f84d 100644 --- a/src/main/java/com/jhe/hexed/JHexEditorASCII.java +++ b/src/main/java/com/jhe/hexed/JHexEditorASCII.java @@ -69,7 +69,7 @@ public class JHexEditorASCII extends JComponent implements MouseListener, g.setColor(Color.black); } - String s = "" + new Character((char) he.buff[n]); + String s = String.valueOf(he.buff[n]); if ((he.buff[n] < 20) || (he.buff[n] > 126)) s = "" + (char) 16; he.printString(g, s, (x++), y); diff --git a/src/main/java/me/konloch/kontainer/io/DiskReader.java b/src/main/java/me/konloch/kontainer/io/DiskReader.java deleted file mode 100644 index c4465fbf..00000000 --- a/src/main/java/me/konloch/kontainer/io/DiskReader.java +++ /dev/null @@ -1,94 +0,0 @@ -package me.konloch.kontainer.io; - -import java.io.*; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Random; - -/** - * Used to load from the disk, optional caching - * - * @author Konloch - */ - -public class DiskReader { - - public static Random random = new Random(); - public static HashMap> map = new HashMap>(); - - /** - * Used to load from file, allows caching - */ - public synchronized static ArrayList loadArrayList(String fileName, - boolean cache) { - ArrayList array = new ArrayList(); - if (!map.containsKey(fileName)) { - try { - File file = new File(fileName); - if (!file.exists()) // doesnt exist, return empty - return array; - - BufferedReader reader = new BufferedReader(new FileReader(file)); - String add; - - while ((add = reader.readLine()) != null) - array.add(add); - - reader.close(); - - if (cache) - map.put(fileName, array); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - array = map.get(fileName); - } - - return array; - - } - - /** - * Used to load from file - */ - public static String loadAsString(String fileName) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - Files.copy(new File(fileName).toPath(), outputStream); - return outputStream.toString("UTF-8"); - } - - /** - * Used to load a string via line number lineNumber = -1 means random. - */ - public static String loadString(String fileName, int lineNumber, - boolean cache) throws Exception { - - ArrayList array; - if (!map.containsKey(fileName)) { - array = new ArrayList(); - File file = new File(fileName); - - BufferedReader reader = new BufferedReader(new FileReader(file)); - String add; - - while ((add = reader.readLine()) != null) - array.add(add); - - reader.close(); - - if (cache) - map.put(fileName, array); - } else { - array = map.get(fileName); - } - - if (lineNumber == -1) { - int size = array.size(); - return array.get(random.nextInt(size)); - } else - return array.get(lineNumber); - } - -} \ No newline at end of file diff --git a/src/main/java/me/konloch/kontainer/io/DiskWriter.java b/src/main/java/me/konloch/kontainer/io/DiskWriter.java deleted file mode 100644 index 2db4f601..00000000 --- a/src/main/java/me/konloch/kontainer/io/DiskWriter.java +++ /dev/null @@ -1,200 +0,0 @@ -package me.konloch.kontainer.io; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.PrintWriter; - -/** - * This method will save to disk - * - * @author Konloch - * - */ - -public class DiskWriter { - - /** - * Used to insert a difference string with preserving the file extension - * - * @param fileName - * The file name - * @param difference - * Normally an integer - * @return The filename with the difference inserted and the file extension - * preserved - */ - public static String insertFileName(String fileName, String difference) { - String[] babe = fileName.split("\\."); - int count = 0; - int math = babe.length; - String m = ""; - - for (String s2 : babe) { - m += s2; - if (math - 2 == count) - m += difference + "."; - else if (math - 1 != count) - m += "."; - count++; - } - - return m; - } - - /** - * Writes a new line to the file, if it doesn't exist it will automatically - * create it. - * - * @param filename - * @param fileContents - * @param debug - */ - public static synchronized void writeNewLine(String filename, - byte[] fileContents, boolean debug) { - PrintWriter writer = null; - String original = filename; - int counter = 0; - - boolean saved = false; - while (!saved) { - try { - writer = new PrintWriter(new BufferedWriter(new FileWriter( - filename, true))); - writer.println(fileContents); - if (debug) - System.out.println("Saved " + filename + " to disk"); - saved = true; - } catch (Exception e) { - if (debug) - System.out.println("Failed saving, trying to save as " - + filename); - if (original.contains(".")) { - filename = insertFileName(original, "" + counter); - } else - filename = original + counter; - counter++; - } - } - writer.close(); - } - - /** - * Writes a string to the file - * - * @param filename - * @param lineToWrite - * @param debug - */ - public static synchronized void writeNewLine(String filename, - String lineToWrite, boolean debug) { - PrintWriter writer = null; - String original = filename; - int counter = 0; - - boolean saved = false; - while (!saved) { - try { - writer = new PrintWriter(new BufferedWriter(new FileWriter( - filename, true))); - writer.println(lineToWrite); - if (debug) - System.out.println("Saved " + filename + ">" + lineToWrite - + " to disk"); - saved = true; - } catch (Exception e) { - if (debug) - System.out.println("Failed saving, trying to save as " - + filename); - if (original.contains(".")) { - filename = insertFileName(original, "" + counter); - } else - filename = original + counter; - counter++; - } - } - writer.close(); - } - - /** - * Deletes the original file if it exists, then writes the fileContents[] to - * the file. - * - * @param filename - * @param fileContents - * @param debug - */ - public static synchronized void replaceFile(String filename, - byte[] fileContents, boolean debug) { - File f = new File(filename); - if (f.exists()) - f.delete(); - PrintWriter writer = null; - String original = filename; - int counter = 0; - - boolean saved = false; - while (!saved) { - try { - writer = new PrintWriter(new BufferedWriter(new FileWriter( - filename, true))); - writer.println(fileContents); - if (debug) - System.out.println("Saved " + filename + " to disk"); - saved = true; - } catch (Exception e) { - if (debug) - System.out.println("Failed saving, trying to save as " - + filename); - if (original.contains(".")) { - filename = insertFileName(original, "" + counter); - } else - filename = original + counter; - counter++; - } - } - writer.close(); - } - - /** - * Deletes the original file if it exists, then writes the lineToWrite to - * the file. - * - * @param filename - * @param lineToWrite - * @param debug - */ - public static synchronized void replaceFile(String filename, - String lineToWrite, boolean debug) { - File f = new File(filename); - if (f.exists()) - f.delete(); - PrintWriter writer = null; - String original = filename; - int counter = 0; - - boolean saved = false; - while (!saved) { - try { - writer = new PrintWriter(new BufferedWriter(new FileWriter( - filename, true))); - writer.println(lineToWrite); - if (debug) - System.out.println("Saved " + filename + ">" + lineToWrite - + " to disk"); - saved = true; - } catch (Exception e) { - if (debug) - System.out.println("Failed saving, trying to save as " - + filename + "_"); - if (original.contains(".")) { - filename = insertFileName(original, "" + counter); - } else - filename = original + counter; - counter++; - } - } - writer.close(); - } - -} \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/APKTool.java b/src/main/java/the/bytecode/club/bytecodeviewer/APKTool.java index 111a4a9c..3b8490cf 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/APKTool.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/APKTool.java @@ -1,47 +1,47 @@ package the.bytecode.club.bytecodeviewer; -import java.io.File; - import org.apache.commons.io.FileUtils; +import org.zeroturnaround.zip.ZipUtil; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ public class APKTool { - - public static synchronized void decodeResources(File input, File output) { - try { - File dir = new File(BytecodeViewer.tempDirectory+BytecodeViewer.fs+"Decoded Resources"); - FileUtils.deleteDirectory(dir); - brut.apktool.Main.main(new String[]{"-s", "-f", "-o", dir.getAbsolutePath(), "decode", input.getAbsolutePath()}); - File original = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "original"); - FileUtils.deleteDirectory(original); - File classes = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "classes.dex"); - classes.delete(); - File apktool = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "apktool.yml"); - apktool.delete(); - File zip = new File(BytecodeViewer.tempDirectory+BytecodeViewer.fs+MiscUtils.randomString(12)+".zip"); - ZipUtils.zipFolder(dir.getAbsolutePath(), zip.getAbsolutePath(), null); - if(zip.exists()) - zip.renameTo(output); - FileUtils.deleteDirectory(dir); - } catch(Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } + public static synchronized void decodeResources(File input, File output) { + try { + Path temporaryDirectory = Files.createTempDirectory("apkresources"); + Files.delete(temporaryDirectory); + brut.apktool.Main.main(new String[]{"-s", "-f", "-o", temporaryDirectory.toAbsolutePath().toString(), "decode", input.getAbsolutePath()}); + File directory = temporaryDirectory.toFile(); + File original = new File(directory, "original"); + FileUtils.deleteDirectory(original); + File classes = new File(directory, "classes.dex"); + classes.delete(); + File apktool = new File(directory, "apktool.yml"); + apktool.delete(); + ZipUtil.pack(directory, output); + FileUtils.deleteDirectory(directory); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Boot.java b/src/main/java/the/bytecode/club/bytecodeviewer/Boot.java index 07a4196e..826adea1 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Boot.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Boot.java @@ -1,9 +1,10 @@ package the.bytecode.club.bytecodeviewer; import org.apache.commons.io.FileUtils; +import org.zeroturnaround.zip.ZipUtil; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; -import javax.swing.*; +import javax.swing.SwingUtilities; import java.io.File; import java.io.InputStream; import java.nio.file.Files; @@ -44,8 +45,6 @@ public class Boot { } public static void boot() throws Exception { - BytecodeViewer.enjarifyWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion + BytecodeViewer.fs + "enjarify-master"; - BytecodeViewer.krakatauWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion + BytecodeViewer.fs + "Krakatau-master"; File enjarifyDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion); File krakatauDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion); if (!enjarifyDirectory.exists() || !krakatauDirectory.exists()) { @@ -99,7 +98,7 @@ public class Boot { Files.delete(temporaryEnjarifyZip); InputStream inputStream = Boot.class.getResourceAsStream("/enjarify-2.zip"); Files.copy(inputStream, temporaryEnjarifyZip); - ZipUtils.unzipFilesToPath(temporaryEnjarifyZip.normalize().toString(), enjarifyDirectory.getAbsolutePath()); + ZipUtil.unpack(temporaryEnjarifyZip.toFile(), enjarifyDirectory); Files.delete(temporaryEnjarifyZip); } catch (Exception e) { BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart BCV." + BytecodeViewer.nl + @@ -131,7 +130,7 @@ public class Boot { Files.delete(temporaryKrakatauZip); InputStream inputStream = Boot.class.getResourceAsStream("/Krakatau-8.zip"); Files.copy(inputStream, temporaryKrakatauZip); - ZipUtils.unzipFilesToPath(temporaryKrakatauZip.normalize().toString(), krakatauDirectory.getAbsolutePath()); + ZipUtil.unpack(temporaryKrakatauZip.toFile(), krakatauDirectory); Files.delete(temporaryKrakatauZip); } catch (Exception e) { BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly corrupt). Restart BCV." + BytecodeViewer.nl + @@ -160,5 +159,5 @@ public class Boot { public String getMessage() { return this.message; } - } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index 07d8aabf..34633c52 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -1,28 +1,43 @@ package the.bytecode.club.bytecodeviewer; -import me.konloch.kontainer.io.DiskReader; -import me.konloch.kontainer.io.DiskWriter; import me.konloch.kontainer.io.HTTPRequest; import org.apache.commons.io.FileUtils; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader; -import the.bytecode.club.bytecodeviewer.gui.*; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; +import the.bytecode.club.bytecodeviewer.gui.ClassViewer; +import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane; +import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI; +import the.bytecode.club.bytecodeviewer.gui.RunOptions; +import the.bytecode.club.bytecodeviewer.gui.SearchingPane; +import the.bytecode.club.bytecodeviewer.gui.SystemErrConsole; +import the.bytecode.club.bytecodeviewer.gui.WorkPane; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.Refactorer; import the.bytecode.club.bytecodeviewer.plugin.PluginManager; -import javax.swing.*; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.UIManager; import javax.swing.filechooser.FileFilter; -import java.awt.*; +import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +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 java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /*************************************************************************** @@ -107,37 +122,31 @@ import java.util.Map; public class BytecodeViewer { /*per version*/ - public static String version = "3.0.0"; - public static boolean previewCopy = false; + public static final String version = "3.0.0"; + public static final String krakatauVersion = "8"; + public static final String enjarifyVersion = "2"; + public static final boolean previewCopy = false; + /* Constants */ + public static final String fs = System.getProperty("file.separator"); + public static final String nl = System.getProperty("line.separator"); + public static final File dataDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer"); + public static final File filesFile = new File(dataDir, "recentfiles.bcv"); + public static final File pluginsFile = new File(dataDir, "recentplugins.bcv"); + public static final File settingsFile = new File(dataDir, "settings.bcv"); + public static final File krakatauDirectory = new File(dataDir + fs + "krakatau_" + krakatauVersion + fs + "Krakatau-master"); + public static final File enjarifyDirectory = new File(dataDir + fs + "enjarify_" + enjarifyVersion + fs + "enjarify-master"); + @Deprecated + public static final File tempDir = new File(dataDir, "bcv_temp"); + private static final long start = System.currentTimeMillis(); /*the rest*/ - public static String[] args; public static MainViewerGUI viewer = null; - public static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV, however that's highly unlikely. - public static SecurityMan sm = new SecurityMan(); //might be insecure due to assholes targeting BCV, however that's highly unlikely. - public static String python = ""; - public static String python3 = ""; - public static String rt = ""; - public static String library = ""; - public static String javac = ""; - public static String java = ""; + public static ClassNodeLoader loader = new ClassNodeLoader(); // TODO MAKE SECURE BECAUSE THIS IS INSECURE + public static SecurityMan sm = new SecurityMan(); // TODO MAKE SECURE BECAUSE THIS IS INSECURE public static ArrayList files = new ArrayList(); //all of BCV's loaded files/classes/etc private static int maxRecentFiles = 25; - public static String fs = System.getProperty("file.separator"); - public static String nl = System.getProperty("line.separator"); - private static File BCVDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer"); - private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv"; - private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv"; - public static String settingsName = getBCVDirectory() + fs + "settings.bcv"; - public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs; - public static String libsDirectory = getBCVDirectory() + fs + "libs" + fs; - public static String krakatauWorkingDirectory = ""; - public static String krakatauVersion = "8"; - public static String enjarifyWorkingDirectory = ""; - public static String enjarifyVersion = "2"; - private static ArrayList recentFiles = DiskReader.loadArrayList(filesName, false); - private static ArrayList recentPlugins = DiskReader.loadArrayList(pluginsName, false); + private static List recentFiles = new ArrayList<>(); + private static List recentPlugins = new ArrayList<>(); public static boolean runningObfuscation = false; - private static long start = System.currentTimeMillis(); public static String lastDirectory = ""; public static ArrayList createdProcesses = new ArrayList(); public static Refactorer refactorer = new Refactorer(); @@ -150,30 +159,36 @@ public class BytecodeViewer { * @param args files you want to open or CLI */ public static void main(String[] args) { - System.setSecurityManager(sm); - BytecodeViewer.args = args; - System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - if (previewCopy && !CommandLineInput.containsCommand(args)) + } catch (Exception e) { + new ExceptionUI(e); + } + try { + System.setSecurityManager(sm); + System.out.println("https://the.bytecode.club - Created by @Konloch and @samczsun - Bytecode Viewer " + version); + CommandLineInput input = new CommandLineInput(args); + if (previewCopy && !input.containsCommand()) showMessage("WARNING: This is a preview/dev copy, you WON'T be alerted when " + version + " is actually out if you use this." + nl + "Make sure to watch the repo: https://github.com/Konloch/bytecode-viewer for " + version + "'s release"); - - viewer = new MainViewerGUI(); - Settings.loadGUI(); - - int CLI = CommandLineInput.parseCommandLine(args); - - if (CLI == CommandLineInput.STOP) - return; - - Boot.boot(); - - if (CLI == CommandLineInput.OPEN_FILE) - BytecodeViewer.BOOT(false); - else { - BytecodeViewer.BOOT(true); - CommandLineInput.executeCommandLine(args); + if (!filesFile.exists() && !filesFile.createNewFile()) { + throw new RuntimeException("Could not create recent files file"); + } + if (!pluginsFile.exists() && !pluginsFile.createNewFile()) { + throw new RuntimeException("Could not create recent plugins file"); + } + recentFiles.addAll(FileUtils.readLines(filesFile, "UTF-8")); + recentPlugins.addAll(FileUtils.readLines(pluginsFile, "UTF-8")); + int CLI = input.parseCommandLine(); + if (CLI == CommandLineInput.STOP) return; + if (CLI == CommandLineInput.OPEN_FILE) { + viewer = new MainViewerGUI(); + Settings.loadGUI(); + Boot.boot(); + BytecodeViewer.BOOT(args, false); + } else { + BytecodeViewer.BOOT(args, true); + input.executeCommandLine(); } } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); @@ -183,7 +198,7 @@ public class BytecodeViewer { /** * The version checker thread */ - private static Thread versionChecker = new Thread() { + private static final Thread versionChecker = new Thread() { @Override public void run() { try { @@ -192,8 +207,7 @@ public class BytecodeViewer { try { int simplemaths = Integer.parseInt(version.replace(".", "")); int simplemaths2 = Integer.parseInt(BytecodeViewer.version.replace(".", "")); - if (simplemaths2 > simplemaths) - return; //developer version + if (simplemaths2 > simplemaths) return; //developer version } catch (Exception e) { } @@ -210,35 +224,21 @@ public class BytecodeViewer { changelog = ""; trigger = true; } else if (trigger) { - if (st.startsWith("--- ")) - finalTrigger = true; + if (st.startsWith("--- ")) finalTrigger = true; - if (finalTrigger) - changelog += st + nl; + if (finalTrigger) changelog += st + nl; } } - JOptionPane pane = new JOptionPane("Your version: " - + BytecodeViewer.version - + ", latest version: " - + version - + nl - + nl - + "Changes since your version:" - + nl - + changelog - + nl - + "What would you like to do?"); + JOptionPane pane = new JOptionPane("Your version: " + BytecodeViewer.version + ", latest version: " + version + nl + nl + "Changes since your version:" + nl + changelog + nl + "What would you like to do?"); Object[] options = new String[]{"Open The Download Page", "Download The Updated Jar", "Do Nothing"}; pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Outdated Version"); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Outdated Version"); dialog.setVisible(true); Object obj = pane.getValue(); int result = -1; for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; + if (options[k].equals(obj)) result = k; if (result == 0) { if (Desktop.isDesktopSupported()) { @@ -277,17 +277,14 @@ public class BytecodeViewer { pane = new JOptionPane("The file " + file + " exists, would you like to overwrite it?"); options = new String[]{"Yes", "No"}; pane.setOptions(options); - dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); + dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); dialog.setVisible(true); obj = pane.getValue(); result = -1; for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; + if (options[k].equals(obj)) result = k; - if (result != 0) - return; + if (result != 0) return; file.delete(); } @@ -312,11 +309,9 @@ public class BytecodeViewer { downloaded += 8192; int mbs = downloaded / 1048576; if (mbs % 5 == 0 && mbs != 0) { - if (!flag) - System.out.println("Downloaded " + mbs + "MBs so far"); + if (!flag) System.out.println("Downloaded " + mbs + "MBs so far"); flag = true; - } else - flag = false; + } else flag = false; } } finally { try { @@ -353,7 +348,7 @@ public class BytecodeViewer { /** * Pings back to bytecodeviewer.com to be added into the total running statistics */ - private static Thread PingBack = new Thread() { + private static final Thread PingBack = new Thread() { @Override public void run() { try { @@ -365,59 +360,43 @@ public class BytecodeViewer { }; public static void pingback() { - JOptionPane pane = new JOptionPane( - "Would you like to 'pingback' to https://bytecodeviewer.com to be counted in the global users for BCV?"); + JOptionPane pane = new JOptionPane("Would you like to 'pingback' to https://bytecodeviewer.com to be counted in the global users for BCV?"); Object[] options = new String[]{"Yes", "No"}; pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Optional Pingback"); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Optional Pingback"); dialog.setVisible(true); Object obj = pane.getValue(); int result = -1; for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; + if (options[k].equals(obj)) result = k; if (result == 0) { try { - if (!PingBack.isAlive()) - PingBack.start(); + if (!PingBack.isAlive()) PingBack.start(); } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } } } - /** - * Grab the byte array from the loaded Class object - * - * @param clazz - * @return - * @throws IOException - */ - public static byte[] getClassFile(Class clazz) throws IOException { - InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class"); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int r = 0; - byte[] buffer = new byte[8192]; - while ((r = is.read(buffer)) >= 0) { - baos.write(buffer, 0, r); - } - return baos.toByteArray(); - } - /** * Boot after all of the libraries have been loaded * * @param cli is it running CLI mode or not */ - public static void BOOT(boolean cli) { + public static void BOOT(String[] args, boolean cli) { cleanup(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { for (Process proc : createdProcesses) proc.destroy(); + try { + FileUtils.writeLines(filesFile, recentFiles); + FileUtils.writeLines(pluginsFile, recentPlugins); + } catch (IOException e) { + new ExceptionUI(e); + } Settings.saveGUI(); cleanup(); } @@ -431,19 +410,15 @@ public class BytecodeViewer { pingback = true; } - if (viewer.chckbxmntmNewCheckItem_12.isSelected()) - versionChecker.start(); + if (viewer.chckbxmntmNewCheckItem_12.isSelected()) versionChecker.start(); - if (!cli) - viewer.setVisible(true); + if (!cli) viewer.setVisible(true); System.out.println("Start up took " + ((System.currentTimeMillis() - start) / 1000) + " seconds"); - if (!cli) - if (args.length >= 1) - for (String s : args) { - openFiles(new File[]{new File(s)}, true); - } + if (!cli) if (args.length >= 1) for (String s : args) { + openFiles(new File[]{new File(s)}, true); + } } /** @@ -455,32 +430,6 @@ public class BytecodeViewer { } - /** - * Returns the java command it can use to launch the decompilers - * - * @return - */ - public static synchronized String getJavaCommand() { - try { - sm.stopBlocking(); - ProcessBuilder pb = new ProcessBuilder("java", "-version"); - Process p = pb.start(); - sm.setBlocking(); - if (p != null) - return "java"; //java is set - } catch (Exception e) { //ignore - sm.setBlocking(); - boolean empty = java.isEmpty(); - while (empty) { - showMessage("You need to set your Java path, this requires the JRE to be downloaded." + BytecodeViewer.nl + - "(C:/programfiles/Java/JRE_xx/bin/java.exe)"); - viewer.java(); - empty = java.isEmpty(); - } - } - return java; - } - /** * Returns the currently opened ClassNode * @@ -498,11 +447,19 @@ public class BytecodeViewer { */ public static ClassNode getClassNode(String name) { for (FileContainer container : files) { - if (container.getClassNode(name) != null) { + if (container.getData().containsKey(name + ".class")) { return container.getClassNode(name); } } + return null; + } + public static byte[] getClassBytes(String name) { + for (FileContainer container : files) { + if (container.getData().containsKey(name)) { + return container.getData().get(name); + } + } return null; } @@ -515,8 +472,7 @@ public class BytecodeViewer { public static byte[] getFileContents(String name) { for (FileContainer container : files) { HashMap files = container.files; - if (files.containsKey(name)) - return files.get(name); + if (files.containsKey(name)) return files.get(name); } return null; @@ -530,8 +486,7 @@ public class BytecodeViewer { */ public static void updateNode(ClassNode oldNode, ClassNode newNode) { for (FileContainer container : files) { - if (container.remove(oldNode)) - container.add(newNode); + if (container.remove(oldNode)) container.add(newNode); } } @@ -545,8 +500,21 @@ public class BytecodeViewer { for (FileContainer container : files) for (ClassNode c : container.values()) - if (!a.contains(c)) - a.add(c); + if (!a.contains(c)) a.add(c); + + return a; + } + + public static ArrayList loadAllClasses() { + ArrayList a = new ArrayList(); + for (FileContainer container : files) { + for (String s : container.files.keySet()) { + ClassNode loaded = container.getClassNode(s.substring(0, s.length() - 6)); + if (loaded != null) { + a.add(loaded); + } + } + } return a; } @@ -572,9 +540,13 @@ public class BytecodeViewer { for (java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers()) { if (c instanceof ClassViewer) { ClassViewer cv = (ClassViewer) c; - if (cv.smali1 != null && cv.smali1.isEditable() || - cv.smali2 != null && cv.smali2.isEditable() || - cv.smali3 != null && cv.smali3.isEditable()) { + boolean valid = false; + for (int i = 0; i < cv.panels.size(); i++) { + if (cv.smalis.get(i) != null && cv.smalis.get(i).isEditable()) { + valid = true; + } + } + if (valid) { actuallyTried = true; Object smali[] = cv.getSmali(); if (smali != null) { @@ -591,11 +563,13 @@ public class BytecodeViewer { } } } - - - if (cv.krakatau1 != null && cv.krakatau1.isEditable() || - cv.krakatau2 != null && cv.krakatau2.isEditable() || - cv.krakatau3 != null && cv.krakatau3.isEditable()) { + valid = false; + for (int i = 0; i < cv.panels.size(); i++) { + if (cv.krakataus.get(i) != null && cv.krakataus.get(i).isEditable()) { + valid = true; + } + } + if (valid) { actuallyTried = true; Object krakatau[] = cv.getKrakatau(); if (krakatau != null) { @@ -612,10 +586,13 @@ public class BytecodeViewer { } } } - - if (cv.java1 != null && cv.java1.isEditable() || - cv.java2 != null && cv.java2.isEditable() || - cv.java3 != null && cv.java3.isEditable()) { + valid = false; + for (int i = 0; i < cv.panels.size(); i++) { + if (cv.javas.get(i) != null && cv.javas.get(i).isEditable()) { + valid = true; + } + } + if (valid) { actuallyTried = true; Object java[] = cv.getJava(); if (java != null) { @@ -642,11 +619,8 @@ public class BytecodeViewer { } } - if (message) - if (actuallyTried) - BytecodeViewer.showMessage("Compiled Successfully."); - else - BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again."); + if (message) if (actuallyTried) BytecodeViewer.showMessage("Compiled Successfully."); + else BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again."); BytecodeViewer.viewer.setIcon(false); return true; @@ -661,10 +635,8 @@ public class BytecodeViewer { * @param recentFiles if it should append to the recent files menu */ public static void openFiles(final File[] files, boolean recentFiles) { - if (recentFiles) - for (File f : files) - if (f.exists()) - BytecodeViewer.addRecentFile(f); + if (recentFiles) for (File f : files) + if (f.exists()) BytecodeViewer.addRecentFile(f); BytecodeViewer.viewer.setIcon(true); update = true; @@ -691,12 +663,11 @@ public class BytecodeViewer { boolean added = false; for (int i = 0; i < totalFiles.size(); i++) { File child = totalFiles.get(i); - if (child.listFiles() != null) - for (File rocket : child.listFiles()) - if (!totalFiles.contains(rocket)) { - totalFiles.add(rocket); - added = true; - } + if (child.listFiles() != null) for (File rocket : child.listFiles()) + if (!totalFiles.contains(rocket)) { + totalFiles.add(rocket); + added = true; + } } if (!added) { @@ -746,7 +717,7 @@ public class BytecodeViewer { FileContainer container = new FileContainer(f); if (viewer.decodeAPKResources.isSelected()) { - File decodedResources = new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk"); + File decodedResources = new File(tempDir, MiscUtils.randomString(32) + ".apk"); APKTool.decodeResources(f, decodedResources); container.files = JarUtils.loadResources(decodedResources); } @@ -754,7 +725,7 @@ public class BytecodeViewer { container.files.putAll(JarUtils.loadResources(f)); String name = getRandomizedName() + ".jar"; - File output = new File(tempDirectory + fs + name); + File output = new File(tempDir, name); if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel())) Dex2Jar.dex2Jar(f, output); @@ -777,7 +748,7 @@ public class BytecodeViewer { FileContainer container = new FileContainer(f); String name = getRandomizedName() + ".jar"; - File output = new File(tempDirectory + fs + name); + File output = new File(tempDir, name); if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel())) Dex2Jar.dex2Jar(f, output); @@ -811,11 +782,10 @@ public class BytecodeViewer { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } finally { BytecodeViewer.viewer.setIcon(false); - if (update) - try { - MainViewerGUI.getComponent(FileNavigationPane.class).updateTree(); - } catch (java.lang.NullPointerException e) { - } + if (update) try { + MainViewerGUI.getComponent(FileNavigationPane.class).updateTree(); + } catch (java.lang.NullPointerException e) { + } } } }; @@ -828,8 +798,7 @@ public class BytecodeViewer { * @param file the file of the plugin */ public static void startPlugin(File file) { - if (!file.exists()) - return; + if (!file.exists()) return; try { PluginManager.runPlugin(file); @@ -861,18 +830,15 @@ public class BytecodeViewer { MainViewerGUI.getComponent(SearchingPane.class).resetWorkspace(); the.bytecode.club.bytecodeviewer.api.BytecodeViewer.getClassNodeLoader().clear(); } else { - JOptionPane pane = new JOptionPane( - "Are you sure you want to reset the workspace?\n\rIt will also reset your file navigator and search."); + JOptionPane pane = new JOptionPane("Are you sure you want to reset the workspace?\n\rIt will also reset your file navigator and search."); Object[] options = new String[]{"Yes", "No"}; pane.setOptions(options); - JDialog dialog = pane.createDialog(viewer, - "Bytecode Viewer - Reset Workspace"); + JDialog dialog = pane.createDialog(viewer, "Bytecode Viewer - Reset Workspace"); dialog.setVisible(true); Object obj = pane.getValue(); int result = -1; for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; + if (options[k].equals(obj)) result = k; if (result == 0) { files.clear(); @@ -894,8 +860,7 @@ public class BytecodeViewer { public static void addRecentFile(File f) { for (int i = 0; i < recentFiles.size(); i++) { // remove dead strings String s = recentFiles.get(i); - if (s.isEmpty() || i > maxRecentFiles) - killList.add(s); + if (s.isEmpty() || i > maxRecentFiles) killList.add(s); } if (!killList.isEmpty()) { for (String s : killList) @@ -905,11 +870,9 @@ public class BytecodeViewer { if (recentFiles.contains(f.getAbsolutePath())) // already added on the list recentFiles.remove(f.getAbsolutePath()); - if (recentFiles.size() >= maxRecentFiles) - recentFiles.remove(maxRecentFiles - 1); // zero indexing + if (recentFiles.size() >= maxRecentFiles) recentFiles.remove(maxRecentFiles - 1); // zero indexing recentFiles.add(0, f.getAbsolutePath()); - DiskWriter.replaceFile(filesName, quickConvert(recentFiles), false); resetRecentFilesMenu(); } @@ -923,8 +886,7 @@ public class BytecodeViewer { public static void addRecentPlugin(File f) { for (int i = 0; i < recentPlugins.size(); i++) { // remove dead strings String s = recentPlugins.get(i); - if (s.isEmpty() || i > maxRecentFiles) - killList2.add(s); + if (s.isEmpty() || i > maxRecentFiles) killList2.add(s); } if (!killList2.isEmpty()) { for (String s : killList2) @@ -934,11 +896,9 @@ public class BytecodeViewer { if (recentPlugins.contains(f.getAbsolutePath())) // already added on the list recentPlugins.remove(f.getAbsolutePath()); - if (recentPlugins.size() >= maxRecentFiles) - recentPlugins.remove(maxRecentFiles - 1); // zero indexing + if (recentPlugins.size() >= maxRecentFiles) recentPlugins.remove(maxRecentFiles - 1); // zero indexing recentPlugins.add(0, f.getAbsolutePath()); - DiskWriter.replaceFile(pluginsName, quickConvert(recentPlugins), false); resetRecentFilesMenu(); } @@ -974,21 +934,14 @@ public class BytecodeViewer { } } - private static File tempF = null; - /** * Clears the temp directory */ public static void cleanup() { - tempF = new File(tempDirectory); - try { - FileUtils.deleteDirectory(tempF); + FileUtils.cleanDirectory(tempDir); } catch (Exception e) { } - - while (!tempF.exists()) // keep making dirs - tempF.mkdir(); } public static ArrayList createdRandomizedNames = new ArrayList(); @@ -1018,13 +971,11 @@ public class BytecodeViewer { * @return the static BCV directory */ public static String getBCVDirectory() { - while (!BCVDir.exists()) - BCVDir.mkdirs(); + while (!dataDir.exists()) dataDir.mkdirs(); - if (!BCVDir.isHidden() && isWindows()) - hideFile(BCVDir); + if (!dataDir.isHidden() && isWindows()) hideFile(dataDir); - return BCVDir.getAbsolutePath(); + return dataDir.getAbsolutePath(); } /** @@ -1052,19 +1003,6 @@ public class BytecodeViewer { sm.setBlocking(); } - /** - * Converts an array list to a string - * - * @param a array - * @return string with newline per array object - */ - private static String quickConvert(ArrayList a) { - String s = ""; - for (String r : a) - s += r + nl; - return s; - } - private static long last = System.currentTimeMillis(); /** @@ -1073,8 +1011,7 @@ public class BytecodeViewer { * @param e */ public static void checkHotKey(KeyEvent e) { - if (System.currentTimeMillis() - last <= (4000)) - return; + if (System.currentTimeMillis() - last <= (4000)) return; if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { last = System.currentTimeMillis(); @@ -1087,14 +1024,11 @@ public class BytecodeViewer { fc.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { - if (f.isDirectory()) - return true; + if (f.isDirectory()) return true; String extension = MiscUtils.extension(f.getAbsolutePath()); if (extension != null) - if (extension.equals("jar") || extension.equals("zip") - || extension.equals("class") || extension.equals("apk") - || extension.equals("dex")) + if (extension.equals("jar") || extension.equals("zip") || extension.equals("class") || extension.equals("apk") || extension.equals("dex")) return true; return false; @@ -1147,8 +1081,7 @@ public class BytecodeViewer { Thread t = new Thread() { public void run() { - if (viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; + if (viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; JFileChooser fc = new JFileChooser(); fc.setFileFilter(new FileFilter() { @Override @@ -1166,22 +1099,18 @@ public class BytecodeViewer { int returnVal = fc.showSaveDialog(viewer); if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); - if (!file.getAbsolutePath().endsWith(".zip")) - file = new File(file.getAbsolutePath() + ".zip"); + if (!file.getAbsolutePath().endsWith(".zip")) file = new File(file.getAbsolutePath() + ".zip"); if (file.exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); Object[] options = new String[]{"Yes", "No"}; pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); dialog.setVisible(true); Object obj = pane.getValue(); int result = -1; for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; + if (options[k].equals(obj)) result = k; if (result == 0) { file.delete(); @@ -1196,8 +1125,7 @@ public class BytecodeViewer { Thread t = new Thread() { @Override public void run() { - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), - file2.getAbsolutePath()); + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), file2.getAbsolutePath()); BytecodeViewer.viewer.setIcon(false); } }; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/CommandLineInput.java b/src/main/java/the/bytecode/club/bytecodeviewer/CommandLineInput.java index 803436be..ddb7aba7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/CommandLineInput.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/CommandLineInput.java @@ -1,9 +1,14 @@ package the.bytecode.club.bytecodeviewer; -import me.konloch.kontainer.io.DiskWriter; -import org.apache.commons.cli.*; -import org.objectweb.asm.ClassWriter; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.io.FileUtils; import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; import java.io.File; @@ -27,16 +32,12 @@ import java.io.File; ***************************************************************************/ /** - * * Used to allow BCV to be integrated as CLI instead of GUI. * * @author Konloch - * */ public class CommandLineInput { - - private static final Options options = new Options(); private static final CommandLineParser parser = new DefaultParser(); @@ -45,6 +46,12 @@ public class CommandLineInput { public static int OPEN_FILE = 0; public static int CLI = 1; + private CommandLine parsed; + + public CommandLineInput(String[] args) throws ParseException { + parsed = parser.parse(options, args); + } + static { options.addOption(new Option("help", null, false, "prints the help menu.")); options.addOption(new Option("list", null, false, "lists all the available decompilers for BCV " + BytecodeViewer.version + ".")); @@ -55,36 +62,25 @@ public class CommandLineInput { options.addOption(new Option("nowait", null, true, "won't wait the 5 seconds to allow the user to read the CLI.")); } - public static boolean containsCommand(String[] args) { - if (args == null || args.length == 0) - return false; - - try { - CommandLine cmd = parser.parse(options, args); - if ( - cmd.hasOption("help") || - cmd.hasOption("list") || - cmd.hasOption("decompiler") || - cmd.hasOption("i") || - cmd.hasOption("o") || - cmd.hasOption("t") || - cmd.hasOption("nowait") - ) { - return true; - } - } catch (Exception e) { - e.printStackTrace(); + public boolean containsCommand() { + if (parsed.hasOption("help") || + parsed.hasOption("list") || + parsed.hasOption("decompiler") || + parsed.hasOption("i") || + parsed.hasOption("o") || + parsed.hasOption("t") || + parsed.hasOption("nowait")) { + return true; } - return false; } - public static int parseCommandLine(String[] args) { - if (!containsCommand(args)) + public int parseCommandLine() { + if (!containsCommand()) { return OPEN_FILE; + } try { - CommandLine cmd = parser.parse(options, args); - if (cmd.hasOption("list")) { + if (parsed.hasOption("list")) { System.out.println("Procyon"); System.out.println("CFR"); System.out.println("FernFlower"); @@ -93,35 +89,27 @@ public class CommandLineInput { System.out.println("JD-GUI"); System.out.println("Smali"); return STOP; - } else if (cmd.hasOption("help")) { - for (String s : new String[]{ - "-help Displays the help menu", - "-list Displays the available decompilers", - "-decompiler Selects the decompiler, procyon by default", - "-i Selects the input file", - "-o Selects the output file", - "-t 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 (parsed.hasOption("help")) { + for (String s : new String[]{"-help Displays the help menu", "-list Displays the available decompilers", "-decompiler Selects the decompiler, procyon by default", "-i Selects the input file", "-o Selects the output file", "-t 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) { + if (parsed.getOptionValue("i") == null) { System.err.println("Set the input with -i"); return STOP; } - if (cmd.getOptionValue("o") == null) { + if (parsed.getOptionValue("o") == null) { System.err.println("Set the output with -o"); return STOP; } - if (cmd.getOptionValue("t") == null) { + if (parsed.getOptionValue("t") == null) { System.err.println("Set the target with -t"); return STOP; } - File input = new File(cmd.getOptionValue("i")); - File output = new File(cmd.getOptionValue("o")); - String decompiler = cmd.getOptionValue("decompiler"); + File input = new File(parsed.getOptionValue("i")); + File output = new File(parsed.getOptionValue("o")); + String decompiler = parsed.getOptionValue("decompiler"); if (!input.exists()) { System.err.println(input.getAbsolutePath() + " does not exist."); @@ -137,201 +125,64 @@ 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") - ) { + 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")) { System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -decompiler-list for the list"); } - if (!cmd.hasOption("nowait")) - Thread.sleep(5 * 1000); + if (!parsed.hasOption("nowait")) Thread.sleep(5 * 1000); return CLI; } } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + new ExceptionUI(e); } return OPEN_FILE; } - public static void executeCommandLine(String[] args) { + public void executeCommandLine() { 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"); + File input = new File(parsed.getOptionValue("i")); + File output = new File(parsed.getOptionValue("o")); + String target = parsed.getOptionValue("t"); - if (cmd.getOptionValue("decompiler") == null) { + Decompiler use = null; + if (parsed.getOptionValue("decompiler") == null) { System.out.println("You can define another decompiler by appending -decompiler \"name\", by default procyon has been set."); - decompiler = "procyon"; + use = Decompiler.PROCYON; + } else if ((use = Decompiler.getByName(parsed.getOptionValue("decompiler"))) == null) { + System.out.println("Decompiler not found. By default Procyon has been set."); + use = Decompiler.PROCYON; } - //check if zip, jar, apk, dex, or class - //if its zip/jar/apk/dex attempt unzip as whole zip - //if its just class allow any - - 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")) { - Decompiler.procyon.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.procyon.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - Decompiler.cfr.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.cfr.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - Decompiler.fernflower.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.fernflower.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - Decompiler.krakatau.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.krakatau.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - System.out.println("Coming soon."); - //Decompiler.krakatauDA.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.krakatauDA.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - System.out.println("Coming soon."); - //Decompiler.jdgui.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.jdgui.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - } 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")) { - System.out.println("Coming soon."); - //Decompiler.smali.decompileToZip(output.getAbsolutePath()); - } else { - try { - ClassNode cn = BytecodeViewer.getClassNode(target); - final ClassWriter cw = accept(cn); - String contents = Decompiler.smali.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } + System.out.println("Decompiling " + input.getAbsolutePath() + " with " + use.getName()); + BytecodeViewer.openFiles(new File[]{input}, false); + Thread.sleep(5 * 1000); + if (target.equalsIgnoreCase("all")) { + use.decompileToZip(output.getAbsolutePath()); + } else { + try { + ClassNode cn = BytecodeViewer.getClassNode(target); + byte[] bytes = BytecodeViewer.getClassBytes(target); + String contents = use.decompileClassNode(cn, bytes); + FileUtils.write(output, contents, "UTF-8", false); + } catch (Exception e) { + new ExceptionUI(e); } } - System.out.println("Finished."); System.out.println("Bytecode Viewer CLI v" + BytecodeViewer.version + " by @Konloch - http://bytecodeviewer.com"); System.exit(0); } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + new ExceptionUI(e); } } - - public static ClassWriter accept(ClassNode cn) { - ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { - } - } - return cw; - } - } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/DecompilerSettings.java b/src/main/java/the/bytecode/club/bytecodeviewer/DecompilerSettings.java new file mode 100644 index 00000000..bc7404e9 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/DecompilerSettings.java @@ -0,0 +1,80 @@ +package the.bytecode.club.bytecodeviewer; + +import com.eclipsesource.json.JsonObject; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; + +import javax.swing.JCheckBoxMenuItem; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class DecompilerSettings { + private Decompiler decompiler; + + public DecompilerSettings(Decompiler decompiler) { + this.decompiler = decompiler; + } + + private Map menuItems = new HashMap<>(); + private List registrationOrder = new ArrayList<>(); + + public void registerSetting(Setting setting) { + if (!menuItems.containsKey(setting)) { + registrationOrder.add(setting); + JCheckBoxMenuItem item = new JCheckBoxMenuItem(setting.getText()); + if (setting.isDefaultOn()) { + item.setSelected(true); + } + menuItems.put(setting, item); + } + } + + public boolean isSelected(Setting setting) { + return menuItems.get(setting).isSelected(); + } + + public JCheckBoxMenuItem getMenuItem(Setting setting) { + return menuItems.get(setting); + } + + public int size() { + return registrationOrder.size(); + } + + public void loadFrom(JsonObject rootSettings) { + if (rootSettings.get("decompilers") != null) { + JsonObject decompilerSection = rootSettings.get("decompilers").asObject(); + if (decompilerSection.get(decompiler.getName()) != null) { + JsonObject thisDecompiler = decompilerSection.get(decompiler.getName()).asObject(); + for (Map.Entry entry : menuItems.entrySet()) { + if (thisDecompiler.get(entry.getKey().getParam()) != null) { + entry.getValue().setSelected(thisDecompiler.get(entry.getKey().getParam()).asBoolean()); + } + } + } + } + } + + public void saveTo(JsonObject rootSettings) { + if (rootSettings.get("decompilers") == null) { + rootSettings.add("decompilers", new JsonObject()); + } + JsonObject decompilerSection = rootSettings.get("decompilers").asObject(); + if (decompilerSection.get(decompiler.getName()) == null) { + decompilerSection.add(decompiler.getName(), new JsonObject()); + } + JsonObject thisDecompiler = decompilerSection.get(decompiler.getName()).asObject(); + for (Map.Entry entry : menuItems.entrySet()) { + thisDecompiler.add(entry.getKey().getParam(), entry.getValue().isSelected()); + } + } + + public interface Setting { + String getText(); + + String getParam(); + + boolean isDefaultOn(); + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Enjarify.java b/src/main/java/the/bytecode/club/bytecodeviewer/Enjarify.java index 348f5bec..62ece596 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Enjarify.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Enjarify.java @@ -35,12 +35,12 @@ public class Enjarify { * @param output the output .jar file */ public static synchronized void apk2Jar(File input, File output) { - if(BytecodeViewer.python3.equals("")) { + if(Settings.PYTHON3_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 3.x executable path."); BytecodeViewer.viewer.pythonC3(); } - if(BytecodeViewer.python3.equals("")) { + if(Settings.PYTHON3_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set Python!"); return; } @@ -48,7 +48,7 @@ public class Enjarify { BytecodeViewer.sm.stopBlocking(); try { ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python3, + Settings.PYTHON3_LOCATION.get(), "-O", "-m", "enjarify.main", @@ -58,7 +58,7 @@ public class Enjarify { "-f" ); - pb.directory(new File(BytecodeViewer.enjarifyWorkingDirectory)); + pb.directory(BytecodeViewer.enjarifyDirectory); Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); process.waitFor(); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/FileChangeNotifier.java b/src/main/java/the/bytecode/club/bytecodeviewer/FileChangeNotifier.java index b1dd34bd..03fc84af 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/FileChangeNotifier.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/FileChangeNotifier.java @@ -28,6 +28,6 @@ import org.objectweb.asm.tree.ClassNode; */ public interface FileChangeNotifier { - public void openClassFile(String name, ClassNode cn); - public void openFile(String name, byte[] contents); + void openClassFile(String name, ClassNode cn); + void openFile(String name, byte[] contents); } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/FileContainer.java b/src/main/java/the/bytecode/club/bytecodeviewer/FileContainer.java index 3627c562..6e61f468 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/FileContainer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/FileContainer.java @@ -1,14 +1,13 @@ package the.bytecode.club.bytecodeviewer; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.ClassNode; +import java.io.File; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/FileDrop.java b/src/main/java/the/bytecode/club/bytecodeviewer/FileDrop.java index 379648e7..40f18cdd 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/FileDrop.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/FileDrop.java @@ -335,8 +335,7 @@ public class FileDrop { // Get a useful list final java.util.List fileList = (java.util.List) tr .getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor); - final java.util.Iterator iterator = fileList - .iterator(); + final java.util.Iterator iterator = fileList.iterator(); // Convert list to array final java.io.File[] filesTemp = new java.io.File[fileList @@ -466,7 +465,7 @@ public class FileDrop { catch (final Exception e) { support = false; } // end catch - supportsDnD = new Boolean(support); + supportsDnD = support; } // end if: first time through return supportsDnD.booleanValue(); } // end supportsDnD diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/InitialBootScreen.java b/src/main/java/the/bytecode/club/bytecodeviewer/InitialBootScreen.java index 5f56349b..c3bd97c4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/InitialBootScreen.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/InitialBootScreen.java @@ -1,8 +1,15 @@ package the.bytecode.club.bytecodeviewer; -import javax.swing.*; +import javax.swing.JEditorPane; +import javax.swing.JFrame; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; import javax.swing.text.html.HTMLEditorKit; -import java.awt.*; +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.Toolkit; import java.io.IOException; /*************************************************************************** diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/JarUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/JarUtils.java index 2cfa9066..daf433de 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/JarUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/JarUtils.java @@ -1,5 +1,9 @@ package the.bytecode.club.bytecodeviewer; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; + import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -14,12 +18,6 @@ import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import me.konloch.kontainer.io.DiskWriter; - -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.tree.ClassNode; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -282,71 +280,6 @@ public class JarUtils { } } - /** - * Saves a jar without the manifest - * @param nodeList The loaded ClassNodes - * @param path the exact jar output path - */ - public static void saveAsJarClassesOnlyToDir(ArrayList nodeList, String dir) { - try { - for (ClassNode cn : nodeList) { - ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - - String name = dir + BytecodeViewer.fs + cn.name + ".class"; - File f = new File(name); - f.mkdirs(); - - DiskWriter.replaceFile(name, cw.toByteArray(), false); - } - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - - /** - * Saves a jar without the manifest - * @param nodeList The loaded ClassNodes - * @param path the exact jar output path - */ - public static void saveAsJar(ArrayList nodeList, String path) { - try { - JarOutputStream out = new JarOutputStream(new FileOutputStream(path)); - ArrayList noDupe = new ArrayList(); - for (ClassNode cn : nodeList) { - ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - - String name = cn.name + ".class"; - - if(!noDupe.contains(name)) { - noDupe.add(name); - out.putNextEntry(new ZipEntry(name)); - out.write(cw.toByteArray()); - out.closeEntry(); - } - } - - for(FileContainer container : BytecodeViewer.files) - for (Entry entry : container.files.entrySet()) { - String filename = entry.getKey(); - if (!filename.startsWith("META-INF")) { - if(!noDupe.contains(filename)) { - noDupe.add(filename); - out.putNextEntry(new ZipEntry(filename)); - out.write(entry.getValue()); - out.closeEntry(); - } - } - } - - noDupe.clear(); - out.close(); - } catch (IOException e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - public static void saveAsJar(Map nodeList, String path) { try { JarOutputStream out = new JarOutputStream(new FileOutputStream(path)); @@ -380,5 +313,4 @@ public class JarUtils { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } } - } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Resources.java b/src/main/java/the/bytecode/club/bytecodeviewer/Resources.java index 4a294a09..43fcd1eb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Resources.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Resources.java @@ -1,15 +1,13 @@ package the.bytecode.club.bytecodeviewer; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.util.ArrayList; +import org.imgscalr.Scalr; import javax.imageio.ImageIO; import javax.swing.ImageIcon; - -import org.apache.commons.codec.binary.Base64; -import org.imgscalr.Scalr; +import javax.xml.bind.DatatypeConverter; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -37,7 +35,6 @@ import org.imgscalr.Scalr; */ public class Resources { - public static ArrayList iconList; public static BufferedImage icon; public static ImageIcon nextIcon; @@ -86,7 +83,7 @@ public class Resources { decodedIcon = new ImageIcon(Resources.class.getClass().getResource("/decoded.png")); javaIcon = new ImageIcon(Resources.class.getClass().getResource("/java.png")); - iconList = new ArrayList(); + iconList = new ArrayList<>(); int size = 16; for (int i = 0; i < 24; i++) { iconList.add(resize(icon, size, size)); @@ -106,24 +103,13 @@ public class Resources { byte[] imageByte; try { - imageByte = Base64.decodeBase64(imageString); + imageByte = DatatypeConverter.parseBase64Binary(imageString); ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); image = ImageIO.read(bis); bis.close(); } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } - return image; } - - public static String findLibrary(String nameContains) { - for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) { - if(f.getName().contains(nameContains)) - return f.getAbsolutePath(); - } - - return null; - } - } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java index 2ac538f9..9fca8b68 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java @@ -1,420 +1,112 @@ package the.bytecode.club.bytecodeviewer; -import javax.swing.JFrame; +import com.eclipsesource.json.JsonObject; +import com.eclipsesource.json.ParseException; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; -import me.konloch.kontainer.io.DiskReader; -import me.konloch.kontainer.io.DiskWriter; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.util.HashMap; +import java.util.Map; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * Used to handle loading/saving the GUI (options). - * - * @author Konloch * + * @author Konloch */ +public class Settings { + private static final Map ALL_SETTINGS = new HashMap<>(); -public class Settings { + public static final Settings PYTHON2_LOCATION = new Settings<>("python2location"); + public static final Settings PYTHON3_LOCATION = new Settings<>("python3location"); + public static final Settings JAVAC_LOCATION = new Settings<>("javaclocation"); + public static final Settings JAVA_LOCATION = new Settings<>("javalocation"); + public static final Settings RT_LOCATION = new Settings<>("rtlocation"); + public static final Settings PATH = new Settings<>("path"); - public static void saveGUI() { - try { - DiskWriter.replaceFile(BytecodeViewer.settingsName, "", false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rbr.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rsy.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.din.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dc4.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.das.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hes.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hdc.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dgs.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.ner.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.den.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rgn.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.bto.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.nns.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.uto.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.udv.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rer.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.fdi.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.asc.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodeenumswitch.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodestringswitch.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.collectioniter.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removeboilerplate.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidebridgemethods.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.liftconstructorinit.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removedeadmethods.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removebadgenerics.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.showversion.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.lenient.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.comments.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcetopsortaggress.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.silent.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recover.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.override.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.showinferrable.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcecondpropagate.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidelongstrings.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.commentmonitor.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.allowcorrecting.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.labelledblocks.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidelangimports.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recoverytypeclash.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recoverytypehints.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forceturningifs.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forloopaggcapture.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forceexceptionprune.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmShowDebugLine.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.mnMergeVariables.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.debugHelpers.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "deprecated", false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.isSelected()), false); - if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false); - else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1JDGUI.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false); - - if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false); - else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2JDGUI.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false); - - if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3CFR.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Fern.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false); - else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3JDGUI.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false); - - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.isMaximized), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.lastDirectory, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.rt, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Proc_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1CFR_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Fern_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Krakatau_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Smali_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Proc_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2CFR_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Fern_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Krakatau_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Smali_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Proc_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3CFR_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Fern_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Krakatau_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Smali_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodeAPKResources.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.library, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.pingback), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1JDGUI_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2JDGUI_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3JDGUI_E.isSelected()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.fontSpinner.getValue()), false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.deleteForiegnLibraries), false); - if(BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); - else if(BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel())) - DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python3, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.javac, false); - DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.java, false); - } catch(Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - - public static void loadGUI() { //utilizes the Disk Reader's caching system. - try { - BytecodeViewer.viewer.rbr.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 1, true))); - BytecodeViewer.viewer.rsy.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 2, false))); - BytecodeViewer.viewer.din.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 3, false))); - BytecodeViewer.viewer.dc4.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 4, false))); - BytecodeViewer.viewer.das.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 5, false))); - BytecodeViewer.viewer.hes.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 6, false))); - BytecodeViewer.viewer.hdc.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 7, false))); - BytecodeViewer.viewer.dgs.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 8, false))); - BytecodeViewer.viewer.ner.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 9, false))); - BytecodeViewer.viewer.den.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 10, false))); - BytecodeViewer.viewer.rgn.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 11, false))); - BytecodeViewer.viewer.bto.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 12, false))); - BytecodeViewer.viewer.nns.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 13, false))); - BytecodeViewer.viewer.uto.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 14, false))); - BytecodeViewer.viewer.udv.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 15, false))); - BytecodeViewer.viewer.rer.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 16, false))); - BytecodeViewer.viewer.fdi.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 17, false))); - BytecodeViewer.viewer.asc.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 18, false))); - BytecodeViewer.viewer.decodeenumswitch.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 19, false))); - BytecodeViewer.viewer.sugarenums.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 20, false))); - BytecodeViewer.viewer.decodestringswitch.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 21, false))); - BytecodeViewer.viewer.arrayiter.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 22, false))); - BytecodeViewer.viewer.collectioniter.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 23, false))); - BytecodeViewer.viewer.innerclasses.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 24, false))); - BytecodeViewer.viewer.removeboilerplate.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 25, false))); - BytecodeViewer.viewer.removeinnerclasssynthetics.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 26, false))); - BytecodeViewer.viewer.decodelambdas.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 27, false))); - BytecodeViewer.viewer.hidebridgemethods.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 28, false))); - BytecodeViewer.viewer.liftconstructorinit.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 29, false))); - BytecodeViewer.viewer.removedeadmethods.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 30, false))); - BytecodeViewer.viewer.removebadgenerics.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 31, false))); - BytecodeViewer.viewer.sugarasserts.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 32, false))); - BytecodeViewer.viewer.sugarboxing.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 33, false))); - BytecodeViewer.viewer.showversion.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 34, false))); - BytecodeViewer.viewer.decodefinally.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 35, false))); - BytecodeViewer.viewer.tidymonitors.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 36, false))); - BytecodeViewer.viewer.lenient.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 37, false))); - BytecodeViewer.viewer.dumpclasspath.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 38, false))); - BytecodeViewer.viewer.comments.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 39, false))); - BytecodeViewer.viewer.forcetopsort.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 40, false))); - BytecodeViewer.viewer.forcetopsortaggress.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 41, false))); - BytecodeViewer.viewer.stringbuffer.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 42, false))); - BytecodeViewer.viewer.stringbuilder.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 43, false))); - BytecodeViewer.viewer.silent.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 44, false))); - BytecodeViewer.viewer.recover.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 45, false))); - BytecodeViewer.viewer.eclipse.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 46, false))); - BytecodeViewer.viewer.override.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 47, false))); - BytecodeViewer.viewer.showinferrable.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 48, false))); - BytecodeViewer.viewer.aexagg.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 49, false))); - BytecodeViewer.viewer.forcecondpropagate.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 50, false))); - BytecodeViewer.viewer.hideutf.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 51, false))); - BytecodeViewer.viewer.hidelongstrings.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 52, false))); - BytecodeViewer.viewer.commentmonitor.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 53, false))); - BytecodeViewer.viewer.allowcorrecting.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 54, false))); - BytecodeViewer.viewer.labelledblocks.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 55, false))); - BytecodeViewer.viewer.j14classobj.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 56, false))); - BytecodeViewer.viewer.hidelangimports.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 57, false))); - BytecodeViewer.viewer.recoverytypeclash.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 58, false))); - BytecodeViewer.viewer.recoverytypehints.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 59, false))); - BytecodeViewer.viewer.forceturningifs.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 60, false))); - BytecodeViewer.viewer.forloopaggcapture.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 61, false))); - BytecodeViewer.viewer.forceexceptionprune.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 62, false))); - BytecodeViewer.viewer.chckbxmntmShowDebugLine.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 63, false))); - BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 64, false))); - BytecodeViewer.viewer.mnMergeVariables.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 65, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 66, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 67, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 68, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 69, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 70, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 71, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 72, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 73, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 74, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 75, false))); - BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 76, false))); - BytecodeViewer.viewer.chckbxmntmAppendBrackets.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 77, false))); - BytecodeViewer.viewer.debugHelpers.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 78, false))); - //79 is deprecated - BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 80, false))); - int decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 81, false)); - if(decompiler == 0) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1None.getModel(), true); - else if(decompiler == 1) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true); - else if(decompiler == 2) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1CFR.getModel(), true); - else if(decompiler == 3) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true); - else if(decompiler == 4) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Bytecode.getModel(), true); - else if(decompiler == 5) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true); - else if(decompiler == 6) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Smali.getModel(), true); - else if(decompiler == 7) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Krakatau.getModel(), true); - else if(decompiler == 8) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel(), true); - else if(decompiler == 9) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1JDGUI.getModel(), true); + private String key; + private T value; - decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false)); - if(decompiler == 0) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2None.getModel(), true); - else if(decompiler == 1) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true); - else if(decompiler == 2) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2CFR.getModel(), true); - else if(decompiler == 3) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true); - else if(decompiler == 4) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Bytecode.getModel(), true); - else if(decompiler == 5) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true); - else if(decompiler == 6) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Smali.getModel(), true); - else if(decompiler == 7) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Krakatau.getModel(), true); - else if(decompiler == 8) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel(), true); - else if(decompiler == 9) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2JDGUI.getModel(), true); - - decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false)); - if(decompiler == 0) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3None.getModel(), true); - else if(decompiler == 1) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true); - else if(decompiler == 2) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3CFR.getModel(), true); - else if(decompiler == 3) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true); - else if(decompiler == 4) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Bytecode.getModel(), true); - else if(decompiler == 5) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true); - else if(decompiler == 6) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Smali.getModel(), true); - else if(decompiler == 7) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Krakatau.getModel(), true); - else if(decompiler == 8) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel(), true); - else if(decompiler == 9) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3JDGUI.getModel(), true); - - BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 84, false))); - - boolean bool = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 85, false)); - if(bool) { - BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH); - BytecodeViewer.viewer.isMaximized = true; - } - BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 86, false))); - BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 87, false))); - BytecodeViewer.lastDirectory = DiskReader.loadString(BytecodeViewer.settingsName, 88, false); - BytecodeViewer.python = DiskReader.loadString(BytecodeViewer.settingsName, 89, false); - BytecodeViewer.rt = DiskReader.loadString(BytecodeViewer.settingsName, 90, false); - BytecodeViewer.viewer.panel1Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 91, false))); - BytecodeViewer.viewer.panel1CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 92, false))); - BytecodeViewer.viewer.panel1Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 93, false))); - BytecodeViewer.viewer.panel1Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 94, false))); - BytecodeViewer.viewer.panel1Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 95, false))); - BytecodeViewer.viewer.panel2Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 96, false))); - BytecodeViewer.viewer.panel2CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 97, false))); - BytecodeViewer.viewer.panel2Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 98, false))); - BytecodeViewer.viewer.panel2Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 99, false))); - BytecodeViewer.viewer.panel2Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 100, false))); - BytecodeViewer.viewer.panel3Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 101, false))); - BytecodeViewer.viewer.panel3CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 101, false))); - BytecodeViewer.viewer.panel3Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 103, false))); - BytecodeViewer.viewer.panel3Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 104, false))); - BytecodeViewer.viewer.panel3Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 105, false))); - BytecodeViewer.viewer.decodeAPKResources.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 106, false))); - BytecodeViewer.library = DiskReader.loadString(BytecodeViewer.settingsName, 107, false); - BytecodeViewer.pingback = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 108, false)); - BytecodeViewer.viewer.panel1JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 109, false))); - BytecodeViewer.viewer.panel2JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 110, false))); - BytecodeViewer.viewer.panel3JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 111, false))); - BytecodeViewer.viewer.fontSpinner.setValue(Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 112, false))); - BytecodeViewer.deleteForiegnLibraries = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 113, false)); - decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 114, false)); - if(decompiler == 0) - BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionDex.getModel(), true); - else if(decompiler == 1) - BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel(), true); - BytecodeViewer.python3 = DiskReader.loadString(BytecodeViewer.settingsName, 115, false); - BytecodeViewer.javac = DiskReader.loadString(BytecodeViewer.settingsName, 116, false); - BytecodeViewer.java = DiskReader.loadString(BytecodeViewer.settingsName, 117, false); - } catch(Exception e) { - //ignore because errors are expected, first start up and outdated settings. - //e.printStackTrace(); - } - } + public Settings(String key) { + this.key = key; + ALL_SETTINGS.put(this.key, this); + } + public T get() { + return this.value; + } + + public void set(T value) { + this.value = value; + } + + public boolean isEmpty() { + return this.value == null || (this.value instanceof String && ((String) this.value).isEmpty()); + } + + public static void saveGUI() { + try { + JsonObject settings = new JsonObject(); + Decompiler.CFR.getSettings().saveTo(settings); + Decompiler.FERNFLOWER.getSettings().saveTo(settings); + Decompiler.PROCYON.getSettings().saveTo(settings); + Decompiler.BYTECODE.getSettings().saveTo(settings); + if (settings.get("settings") == null) { + settings.add("settings", new JsonObject()); + } + JsonObject rootSettings = settings.get("settings").asObject(); + for (Map.Entry setting : Settings.ALL_SETTINGS.entrySet()) { + if (setting.getValue().get() != null) { + rootSettings.add(setting.getKey(), setting.getValue().get().toString()); + } + } + FileOutputStream out = new FileOutputStream(BytecodeViewer.settingsFile); + out.write(settings.toString().getBytes("UTF-8")); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void loadGUI() { + try { + JsonObject settings = new JsonObject(); + try { + settings = JsonObject.readFrom(new FileReader(BytecodeViewer.settingsFile)); + } catch (ParseException | UnsupportedOperationException e) { + } + Decompiler.CFR.getSettings().loadFrom(settings); + Decompiler.FERNFLOWER.getSettings().loadFrom(settings); + Decompiler.PROCYON.getSettings().loadFrom(settings); + Decompiler.BYTECODE.getSettings().loadFrom(settings); + if (settings.get("settings") != null) { + JsonObject rootSettings = settings.get("settings").asObject(); + for (Map.Entry setting : Settings.ALL_SETTINGS.entrySet()) { + if (rootSettings.get(setting.getKey()) != null) { + setting.getValue().set(rootSettings.get(setting.getKey()).asString()); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/ZipUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/ZipUtils.java deleted file mode 100644 index dadedfc3..00000000 --- a/src/main/java/the/bytecode/club/bytecodeviewer/ZipUtils.java +++ /dev/null @@ -1,157 +0,0 @@ -package the.bytecode.club.bytecodeviewer; - -import java.io.*; -import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -/*************************************************************************** - * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * - * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -/** - * Rudimentary utility class for Zip archives. - */ -public final class ZipUtils { - - /** - * Unzip files to path. - * - * @param zipFileName the zip file name - * @param fileExtractPath the file extract path - * @throws IOException Signals that an I/O exception has occurred. - */ - public static void unzipFilesToPath(String jarPath, String destinationDir) throws IOException { - File file = new File(jarPath); - JarFile jar = new JarFile(file); - - // fist get all directories, - // then make those directory on the destination Path - for (Enumeration enums = jar.entries(); enums.hasMoreElements(); ) { - JarEntry entry = (JarEntry) enums.nextElement(); - - String fileName = destinationDir + File.separator + entry.getName(); - File f = new File(fileName); - - if (fileName.endsWith("/")) { - f.mkdirs(); - } - - } - - //now create all files - for (Enumeration enums = jar.entries(); enums.hasMoreElements(); ) { - JarEntry entry = (JarEntry) enums.nextElement(); - - String fileName = destinationDir + File.separator + entry.getName(); - File f = new File(fileName); - - if (!fileName.endsWith("/")) { - InputStream is = jar.getInputStream(entry); - FileOutputStream fos = new FileOutputStream(f); - - // write contents of 'is' to 'fos' - while (is.available() > 0) { - fos.write(is.read()); - } - - fos.close(); - is.close(); - } - } - - try { - jar.close(); - } catch (Exception e) { - - } - } - - public static void zipFile(File inputFile, File outputZip) { - byte[] buffer = new byte[1024]; - - try { - FileOutputStream fos = new FileOutputStream(outputZip); - ZipOutputStream zos = new ZipOutputStream(fos); - ZipEntry ze = new ZipEntry(inputFile.getName()); - zos.putNextEntry(ze); - FileInputStream in = new FileInputStream(inputFile); - - int len; - while ((len = in.read(buffer)) > 0) { - zos.write(buffer, 0, len); - } - - in.close(); - zos.closeEntry(); - - zos.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void zipFolder(String srcFolder, String destZipFile, String ignore) throws Exception { - ZipOutputStream zip = null; - FileOutputStream fileWriter = null; - - fileWriter = new FileOutputStream(destZipFile); - zip = new ZipOutputStream(fileWriter); - - addFolderToZip("", srcFolder, zip, ignore); - zip.flush(); - zip.close(); - } - - public static void addFileToZip(String path, String srcFile, ZipOutputStream zip, String ignore) - throws Exception { - - File folder = new File(srcFile); - if (folder.isDirectory()) { - addFolderToZip(path, srcFile, zip, ignore); - } else { - byte[] buf = new byte[1024]; - int len; - FileInputStream in = new FileInputStream(srcFile); - ZipEntry entry = null; - if (ignore == null) - entry = new ZipEntry(path + "/" + folder.getName()); - else - entry = new ZipEntry(path.replace(ignore, "BCV_Krakatau") + "/" + folder.getName()); - zip.putNextEntry(entry); - while ((len = in.read(buf)) > 0) { - zip.write(buf, 0, len); - } - in.close(); - } - } - - public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip, String ignore) - throws Exception { - File folder = new File(srcFolder); - - for (String fileName : folder.list()) { - if (path.equals("")) { - addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, ignore); - } else { - addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, ignore); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/ASMUtil_OLD.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/ASMUtil_OLD.java index 966d6d6e..b125b631 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/ASMUtil_OLD.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/ASMUtil_OLD.java @@ -1,7 +1,5 @@ package the.bytecode.club.bytecodeviewer.api; -import java.util.List; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldInsnNode; @@ -11,9 +9,10 @@ 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 the.bytecode.club.bytecodeviewer.BytecodeViewer; +import java.util.List; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java index dc5d8296..e54bc6ee 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java @@ -1,5 +1,10 @@ package the.bytecode.club.bytecodeviewer.api; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; + import java.io.File; import java.io.IOException; import java.net.URL; @@ -10,276 +15,260 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import org.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; -import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * The official API for BCV, this was designed for plugin authors and * people utilizing EZ-Injection. - * + * * @author Konloch - * + * */ public class BytecodeViewer { - private static URLClassLoader cl; - - /** - * Grab the loader instance - * - * @return - */ - public static ClassNodeLoader getClassNodeLoader() { - return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader; - } - - /** - * Returns the URLClassLoader instance - * @return the URLClassLoader instance - */ - public static URLClassLoader getClassLoaderInstance() { - return cl; - } + private static URLClassLoader cl; - - - /** - * Re-instances the URLClassLoader and loads a jar to it. - * - * @param nodeList - * The list of ClassNodes to be loaded - * @return The loaded classes into the new URLClassLoader instance - * @author Cafebabe - * @throws IOException - * @throws ClassNotFoundException - */ - @SuppressWarnings("deprecation") - public static List> loadClassesIntoClassLoader( - ArrayList nodeList) throws IOException, - ClassNotFoundException { + /** + * Grab the loader instance + * + * @return + */ + public static ClassNodeLoader getClassNodeLoader() { + return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader; + } - File f = new File( - the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDirectory - + the.bytecode.club.bytecodeviewer.BytecodeViewer.fs - + "loaded_temp.jar"); - JarUtils.saveAsJarClassesOnly(nodeList, f.getAbsolutePath()); - - JarFile jarFile = new JarFile("" + f.getAbsolutePath()); - Enumeration e = jarFile.entries(); - cl = URLClassLoader.newInstance(new URL[]{ f.toURL() }); - List> ret = new ArrayList>(); + /** + * Returns the URLClassLoader instance + * @return the URLClassLoader instance + */ + public static URLClassLoader getClassLoaderInstance() { + return cl; + } - while (e.hasMoreElements()) { - JarEntry je = (JarEntry) e.nextElement(); - if (je.isDirectory() || !je.getName().endsWith(".class")) - continue; - String className = je.getName().replace("/", ".").replace(".class", ""); - className = className.replace('/', '.'); - ret.add(cl.loadClass(className)); - } - jarFile.close(); + /** + * Re-instances the URLClassLoader and loads a jar to it. + * + * @param nodeList + * The list of ClassNodes to be loaded + * @return The loaded classes into the new URLClassLoader instance + * @author Cafebabe + * @throws IOException + * @throws ClassNotFoundException + */ + @SuppressWarnings("deprecation") + public static List> loadClassesIntoClassLoader(ArrayList nodeList) throws IOException, ClassNotFoundException { + File f = new File(the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDir, "loaded_temp.jar"); + JarUtils.saveAsJarClassesOnly(nodeList, f.getAbsolutePath()); - return ret; + JarFile jarFile = new JarFile("" + f.getAbsolutePath()); + Enumeration e = jarFile.entries(); + cl = URLClassLoader.newInstance(new URL[]{f.toURL()}); + List> ret = new ArrayList>(); - } - - - /** - * Re-instances the URLClassLoader and loads a jar to it. - * @return The loaded classes into the new URLClassLoader instance - * @author Cafebabe - * @throws IOException - * @throws ClassNotFoundException - */ - public static List> loadAllClassesIntoClassLoader() throws ClassNotFoundException, IOException { - return loadClassesIntoClassLoader(getLoadedClasses()); - } + while (e.hasMoreElements()) { + JarEntry je = (JarEntry) e.nextElement(); + if (je.isDirectory() || !je.getName().endsWith(".class")) continue; + String className = je.getName().replace("/", ".").replace(".class", ""); + className = className.replace('/', '.'); + ret.add(cl.loadClass(className)); - /** - * Creates a new instance of the ClassNode loader. - */ - public static void createNewClassNodeLoaderInstance() { - the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear(); - the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader(); - } + } + jarFile.close(); - /** - * Used to start a plugin from file. - * - * @param plugin - * the file of the plugin - */ - public static void startPlugin(File plugin) { - the.bytecode.club.bytecodeviewer.BytecodeViewer.startPlugin(plugin); - } + return ret; - /** - * Used to load classes/jars into 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) { - the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files, recentFiles); - } + } - /** - * Returns the currently opened class node, if nothing is opened it'll return null. - * @return The opened class node or a null if nothing is opened - */ - public static ClassNode getCurrentlyOpenedClassNode() { - return the.bytecode.club.bytecodeviewer.BytecodeViewer.getCurrentlyOpenedClassNode(); - } - - /** - * Used to load a ClassNode. - * - * @param name - * the full name of the ClassNode - * @return the ClassNode - */ - public static ClassNode getClassNode(String name) { - return the.bytecode.club.bytecodeviewer.BytecodeViewer - .getClassNode(name); - } - /** - * Used to grab the loaded ClassNodes. - * - * @return the loaded classes - */ - public static ArrayList getLoadedClasses() { - return the.bytecode.club.bytecodeviewer.BytecodeViewer - .getLoadedClasses(); - } + /** + * Re-instances the URLClassLoader and loads a jar to it. + * @return The loaded classes into the new URLClassLoader instance + * @author Cafebabe + * @throws IOException + * @throws ClassNotFoundException + */ + public static List> loadAllClassesIntoClassLoader() throws ClassNotFoundException, IOException { + return loadClassesIntoClassLoader(getLoadedClasses()); + } - /** - * Used to insert a Bytecode Hook using EZ-Injection. - * - * @param hook - */ - public static void insertHook(BytecodeHook hook) { - EZInjection.hookArray.add(hook); - } + /** + * Creates a new instance of the ClassNode loader. + */ + public static void createNewClassNodeLoaderInstance() { + the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear(); + the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader(); + } - /** - * This will ask the user if they really want to reset the workspace, then - * it'll reset the work space. - * - * @param ask - * if it should ask the user about resetting the workspace - */ - public static void resetWorkSpace(boolean ask) { - the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask); - } + /** + * Used to start a plugin from file. + * + * @param plugin + * the file of the plugin + */ + public static void startPlugin(File plugin) { + the.bytecode.club.bytecodeviewer.BytecodeViewer.startPlugin(plugin); + } - /** - * If true, it will display the busy icon, if false it will remove it if - * it's displayed. - * - * @param busy - * if it should display the busy icon or not - */ - public static void setBusy(boolean busy) { - the.bytecode.club.bytecodeviewer.BytecodeViewer.viewer.setIcon(busy); - } + /** + * Used to load classes/jars into 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) { + the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files, recentFiles); + } - /** - * Sends a small window popup with the defined message. - * - * @param message - * the message you want to display - */ - public static void showMessage(String message) { - the.bytecode.club.bytecodeviewer.BytecodeViewer.showMessage(message); - } - - /** - * Returns the wrapped Krakatau Decompiler instance. - * @return The wrapped Krakatau Decompiler instance - */ - public static Decompiler getKrakatauDecompiler() { - return Decompiler.krakatau; - } - - /** - * Returns the wrapped Procyon Decompiler instance. - * @return The wrapped Procyon Decompiler instance - */ - public static Decompiler getProcyonDecompiler() { - return Decompiler.procyon; - } - - /** - * Returns the wrapped CFR Decompiler instance. - * @return The wrapped CFR Decompiler instance - */ - public static Decompiler getCFRDecompiler() { - return Decompiler.cfr; - } - - /** - * Returns the wrapped FernFlower Decompiler instance. - * @return The wrapped FernFlower Decompiler instance - */ - public static Decompiler getFernFlowerDecompiler() { - return Decompiler.fernflower; - } - - /** - * Returns the wrapped Krakatau Disassembler instance. - * @return The wrapped Krakatau Disassembler instance - */ - public static Decompiler getKrakatauDisassembler() { - return Decompiler.krakatauDA; - } - - /** - * Returns the wrapped Krakatau Assembler instance. - * @return The wrapped Krakatau Assembler instance - */ - public static the.bytecode.club.bytecodeviewer.compilers.Compiler getKrakatauCompiler() { - return the.bytecode.club.bytecodeviewer.compilers.Compiler.krakatau; - } - - /** - * Returns the wrapped Smali Assembler instance. - * @return The wrapped Smali Assembler instance - */ - public static the.bytecode.club.bytecodeviewer.compilers.Compiler getSmaliCompiler() { - return the.bytecode.club.bytecodeviewer.compilers.Compiler.smali; - } - - /** - * Returns the wrapped JD-GUI Decompiler instance. - * @return The wrapped JD-GUI Decompiler instance - */ - public static the.bytecode.club.bytecodeviewer.decompilers.Decompiler getDJGUIDecompiler() { - return the.bytecode.club.bytecodeviewer.decompilers.Decompiler.jdgui; - } + /** + * Returns the currently opened class node, if nothing is opened it'll return null. + * @return The opened class node or a null if nothing is opened + */ + public static ClassNode getCurrentlyOpenedClassNode() { + return the.bytecode.club.bytecodeviewer.BytecodeViewer.getCurrentlyOpenedClassNode(); + } + + /** + * Used to load a ClassNode. + * + * @param name + * the full name of the ClassNode + * @return the ClassNode + */ + public static ClassNode getClassNode(String name) { + return the.bytecode.club.bytecodeviewer.BytecodeViewer.getClassNode(name); + } + + /** + * Used to grab the loaded ClassNodes. + * + * @return the loaded classes + */ + public static ArrayList getLoadedClasses() { + return the.bytecode.club.bytecodeviewer.BytecodeViewer.getLoadedClasses(); + } + + /** + * Used to insert a Bytecode Hook using EZ-Injection. + * + * @param hook + */ + public static void insertHook(BytecodeHook hook) { + EZInjection.hookArray.add(hook); + } + + /** + * This will ask the user if they really want to reset the workspace, then + * it'll reset the work space. + * + * @param ask + * if it should ask the user about resetting the workspace + */ + public static void resetWorkSpace(boolean ask) { + the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask); + } + + /** + * If true, it will display the busy icon, if false it will remove it if + * it's displayed. + * + * @param busy + * if it should display the busy icon or not + */ + public static void setBusy(boolean busy) { + the.bytecode.club.bytecodeviewer.BytecodeViewer.viewer.setIcon(busy); + } + + /** + * Sends a small window popup with the defined message. + * + * @param message + * the message you want to display + */ + public static void showMessage(String message) { + the.bytecode.club.bytecodeviewer.BytecodeViewer.showMessage(message); + } + + /** + * Returns the wrapped Krakatau Decompiler instance. + * @return The wrapped Krakatau Decompiler instance + */ + public static Decompiler getKrakatauDecompiler() { + return Decompiler.KRAKATAU; + } + + /** + * Returns the wrapped Procyon Decompiler instance. + * @return The wrapped Procyon Decompiler instance + */ + public static Decompiler getProcyonDecompiler() { + return Decompiler.PROCYON; + } + + /** + * Returns the wrapped CFR Decompiler instance. + * @return The wrapped CFR Decompiler instance + */ + public static Decompiler getCFRDecompiler() { + return Decompiler.CFR; + } + + /** + * Returns the wrapped FernFlower Decompiler instance. + * @return The wrapped FernFlower Decompiler instance + */ + public static Decompiler getFernFlowerDecompiler() { + return Decompiler.FERNFLOWER; + } + + /** + * Returns the wrapped Krakatau Disassembler instance. + * @return The wrapped Krakatau Disassembler instance + */ + public static Decompiler getKrakatauDisassembler() { + return Decompiler.KRAKATAU_DA; + } + + /** + * Returns the wrapped Krakatau Assembler instance. + * @return The wrapped Krakatau Assembler instance + */ + public static the.bytecode.club.bytecodeviewer.compilers.Compiler getKrakatauCompiler() { + return the.bytecode.club.bytecodeviewer.compilers.Compiler.krakatau; + } + + /** + * Returns the wrapped Smali Assembler instance. + * @return The wrapped Smali Assembler instance + */ + public static the.bytecode.club.bytecodeviewer.compilers.Compiler getSmaliCompiler() { + return the.bytecode.club.bytecodeviewer.compilers.Compiler.smali; + } + + /** + * Returns the wrapped JD-GUI Decompiler instance. + * @return The wrapped JD-GUI Decompiler instance + */ + public static the.bytecode.club.bytecodeviewer.decompilers.Decompiler getDJGUIDecompiler() { + return the.bytecode.club.bytecodeviewer.decompilers.Decompiler.JDGUI; + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/ClassNodeLoader.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/ClassNodeLoader.java index 9c05d2d6..df5faec7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/ClassNodeLoader.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/ClassNodeLoader.java @@ -1,5 +1,8 @@ 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; @@ -9,9 +12,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.tree.ClassNode; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -38,6 +38,10 @@ import org.objectweb.asm.tree.ClassNode; public final class ClassNodeLoader extends ClassLoader { + public ClassNodeLoader() { + super(ClassLoader.getSystemClassLoader()); + } + private HashMap classes = new HashMap(); /** diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java index 19563763..33ae9357 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java @@ -1,18 +1,17 @@ package the.bytecode.club.bytecodeviewer.api; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Resources; + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.io.PrintWriter; import java.io.StringWriter; -import javax.swing.JFrame; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.Resources; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -79,7 +78,6 @@ public class ExceptionUI extends JFrame { } private void setup(Throwable e, String author) { - this.setIconImages(Resources.iconList); setSize(new Dimension(600, 400)); setTitle("Bytecode Viewer " + BytecodeViewer.version diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/Plugin.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/Plugin.java index 5ea5700e..8475ba8b 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/Plugin.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/Plugin.java @@ -1,11 +1,10 @@ package the.bytecode.club.bytecodeviewer.api; -import java.util.ArrayList; - import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -37,11 +36,11 @@ public abstract class Plugin extends Thread { public void run() { BytecodeViewer.viewer.setIcon(true); try { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { + if(BytecodeViewer.getLoadedBytes().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); return; } - execute(BytecodeViewer.getLoadedClasses()); + execute(BytecodeViewer.loadAllClasses()); } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } finally { diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/PluginConsole.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/PluginConsole.java index b8db5db1..35e3d118 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/PluginConsole.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/PluginConsole.java @@ -1,30 +1,25 @@ package the.bytecode.club.bytecodeviewer.api; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JFrame; -import javax.swing.JTextField; - -import java.awt.Color; -import java.awt.Dimension; - -import javax.swing.JScrollPane; - -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; - -import javax.swing.JTextArea; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Resources; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Highlighter; import javax.swing.text.JTextComponent; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -255,10 +250,8 @@ public class PluginConsole extends JFrame { * the string you want to append */ public void appendText(String t) { - textArea.setText((textArea.getText().isEmpty() ? "" : textArea - .getText() + "\r\n") - + t); - textArea.setCaretPosition(0); + textArea.append(t + "\r\n"); + textArea.setCaretPosition(textArea.getText().length()); } /** diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java index 39e051f0..32fe9649 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/JavaCompiler.java @@ -1,16 +1,17 @@ package the.bytecode.club.bytecodeviewer.compilers; +import org.apache.commons.io.FileUtils; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.MiscUtils; +import the.bytecode.club.bytecodeviewer.Settings; + 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.JarUtils; -import the.bytecode.club.bytecodeviewer.MiscUtils; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -40,27 +41,31 @@ public class JavaCompiler extends Compiler { @Override public byte[] compile(String contents, String name) { - String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs; - String fileStart2 = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs; + String fileStart = BytecodeViewer.tempDir.getAbsolutePath() + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs; + String fileStart2 = BytecodeViewer.tempDir.getAbsolutePath() + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs; File java = new File(fileStart + BytecodeViewer.fs + name + ".java"); File clazz = new File(fileStart2 + BytecodeViewer.fs + name + ".class"); - File cp = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "cpath_"+MiscUtils.randomString(12)+".jar"); + File cp = new File(BytecodeViewer.tempDir, "cpath_"+MiscUtils.randomString(12)+".jar"); File tempD = new File(fileStart + BytecodeViewer.fs + name.substring(0,name.length() - name.split("/")[name.split("/").length-1].length())); tempD.mkdirs(); new File(fileStart2).mkdirs(); - if(BytecodeViewer.javac.equals("")) { + if(Settings.JAVAC_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded."+BytecodeViewer.nl+"(C:/programfiles/Java/JRE_xx/bin/javac.exe)"); BytecodeViewer.viewer.javac(); } - if(BytecodeViewer.javac.equals("")) { + if(Settings.JAVAC_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set Javac!"); return null; } - - DiskWriter.replaceFile(java.getAbsolutePath(), contents, false); - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), cp.getAbsolutePath()); + + try { + FileUtils.write(java, contents, "UTF-8", false); + } catch (IOException e) { + e.printStackTrace(); + } + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), cp.getAbsolutePath()); boolean cont = true; BytecodeViewer.sm.stopBlocking(); @@ -68,18 +73,18 @@ public class JavaCompiler extends Compiler { String log = ""; ProcessBuilder pb; - if(BytecodeViewer.library.isEmpty()) { + if(Settings.PATH.isEmpty()) { pb = new ProcessBuilder( - BytecodeViewer.javac, + Settings.JAVAC_LOCATION.get(), "-d", fileStart2, "-classpath", cp.getAbsolutePath(), java.getAbsolutePath() ); } else { pb = new ProcessBuilder( - BytecodeViewer.javac, + Settings.JAVAC_LOCATION.get(), "-d", fileStart2, - "-classpath", cp.getAbsolutePath()+";"+BytecodeViewer.library, + "-classpath", cp.getAbsolutePath()+";"+Settings.PATH.get(), java.getAbsolutePath() ); } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/KrakatauAssembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/KrakatauAssembler.java index b677eace..6f50137e 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/KrakatauAssembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/KrakatauAssembler.java @@ -1,14 +1,16 @@ package the.bytecode.club.bytecodeviewer.compilers; -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; - -import me.konloch.kontainer.io.DiskWriter; +import org.apache.commons.io.FileUtils; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.MiscUtils; +import the.bytecode.club.bytecodeviewer.Settings; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -38,12 +40,12 @@ public class KrakatauAssembler extends Compiler { @Override public byte[] compile(String contents, String name) { - if(BytecodeViewer.python.equals("")) { + if(Settings.PYTHON2_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); BytecodeViewer.viewer.pythonC(); } - - if(BytecodeViewer.python.equals("")) { + + if(Settings.PYTHON2_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set Python!"); return null; } @@ -51,24 +53,28 @@ public class KrakatauAssembler extends Compiler { String origName = name; name = MiscUtils.randomString(20); - File tempD = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); + File tempD = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); tempD.mkdir(); File tempJ = new File(tempD.getAbsolutePath() + BytecodeViewer.fs+name+".j"); - DiskWriter.replaceFile(tempJ.getAbsolutePath(), contents, true); - - final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); + try { + FileUtils.write(tempJ, contents, "UTF-8", false); + } catch (IOException e) { + e.printStackTrace(); + } + + final File tempDirectory = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); tempDirectory.mkdir(); - final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar"); - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); + final File tempJar = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar"); + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath()); BytecodeViewer.sm.stopBlocking(); String log = ""; try { ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python, + Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3 - BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "assemble.py", + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "assemble.py", "-out", tempDirectory.getAbsolutePath(), tempJ.getAbsolutePath() diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/SmaliAssembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/SmaliAssembler.java index 8053b5b2..eff95ec0 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/compilers/SmaliAssembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/compilers/SmaliAssembler.java @@ -1,13 +1,13 @@ package the.bytecode.club.bytecodeviewer.compilers; -import java.io.File; - -import me.konloch.kontainer.io.DiskWriter; +import org.apache.commons.io.FileUtils; +import org.zeroturnaround.zip.ZipUtil; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Dex2Jar; import the.bytecode.club.bytecodeviewer.Enjarify; import the.bytecode.club.bytecodeviewer.MiscUtils; -import the.bytecode.club.bytecodeviewer.ZipUtils; + +import java.io.File; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -38,7 +38,7 @@ public class SmaliAssembler extends Compiler { @Override public byte[] compile(String contents, String name) { - String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"; + String fileStart = BytecodeViewer.tempDir.getAbsoluteFile() + BytecodeViewer.fs + "temp"; int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex"); final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder"+BytecodeViewer.fs); @@ -50,7 +50,7 @@ public class SmaliAssembler extends Compiler { File tempJarFolder = new File(fileStart + fileNumber + "-jar"+BytecodeViewer.fs); try { - DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false); + FileUtils.write(tempSmali, contents, "UTF-8", false); } catch (final Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } @@ -68,7 +68,7 @@ public class SmaliAssembler extends Compiler { Enjarify.apk2Jar(tempDex, tempJar); try { - ZipUtils.unzipFilesToPath(tempJar.getAbsolutePath(), tempJarFolder.getAbsolutePath()); + ZipUtil.unpack(tempJar, tempJarFolder); File outputClass = null; boolean found = false; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/CFRDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/CFRDecompiler.java index 4e20dc53..8571825f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/CFRDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/CFRDecompiler.java @@ -16,15 +16,20 @@ import org.benf.cfr.reader.util.bytestream.BaseByteData; import org.benf.cfr.reader.util.getopt.GetOptParser; import org.benf.cfr.reader.util.getopt.Options; import org.benf.cfr.reader.util.getopt.OptionsImpl; -import org.benf.cfr.reader.util.output.*; +import org.benf.cfr.reader.util.output.Dumper; +import org.benf.cfr.reader.util.output.FileDumper; +import org.benf.cfr.reader.util.output.IllegalIdentifierDump; +import org.benf.cfr.reader.util.output.NopSummaryDumper; +import org.benf.cfr.reader.util.output.SummaryDumper; +import org.benf.cfr.reader.util.output.ToStringDumper; import org.objectweb.asm.tree.ClassNode; import org.zeroturnaround.zip.ZipUtil; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.DecompilerSettings; import the.bytecode.club.bytecodeviewer.JarUtils; import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; @@ -54,6 +59,22 @@ import java.util.List; */ public class CFRDecompiler extends Decompiler { + public CFRDecompiler() { + for (Settings setting : Settings.values()) { + settings.registerSetting(setting); + } + } + + @Override + public DecompilerSettings getSettings() { + return settings; + } + + @Override + public String getName() { + return "CFR"; + } + @Override public String decompileClassNode(ClassNode cn, byte[] b) { try { @@ -62,11 +83,7 @@ public class CFRDecompiler extends Decompiler { DCCommonState dcCommonState = new DCCommonState(options, classFileSource); return doClass(dcCommonState, b); } catch (Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); - return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception; + return parseException(e); } } @@ -76,129 +93,41 @@ public class CFRDecompiler extends Decompiler { Path outputDir = Files.createTempDirectory("cfr_output"); Path tempJar = Files.createTempFile("cfr_input", ".jar"); File output = new File(zipName); - JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.toAbsolutePath().toString()); - Options options = new GetOptParser().parse(generateMainMethod(), OptionsImpl.getFactory()); - ClassFileSourceImpl classFileSource = new ClassFileSourceImpl(options); - DCCommonState dcCommonState = new DCCommonState(options, classFileSource); - doJar(dcCommonState, tempJar.toAbsolutePath(), outputDir.toAbsolutePath()); - ZipUtil.pack(outputDir.toFile(), output); - FileUtils.deleteDirectory(outputDir.toFile()); - Files.delete(tempJar); + try { + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.toAbsolutePath().toString()); + Options options = new GetOptParser().parse(generateMainMethod(), OptionsImpl.getFactory()); + ClassFileSourceImpl classFileSource = new ClassFileSourceImpl(options); + DCCommonState dcCommonState = new DCCommonState(options, classFileSource); + doJar(dcCommonState, tempJar.toAbsolutePath(), outputDir.toAbsolutePath()); + ZipUtil.pack(outputDir.toFile(), output); + } catch (Exception e) { + handleException(e); + } finally { + try { + FileUtils.deleteDirectory(outputDir.toFile()); + } catch (IOException e) { + handleException(e); + } + try { + Files.delete(tempJar); + } catch (IOException e) { + handleException(e); + } + } } catch (Exception e) { - e.printStackTrace(); //TODO How to handle exceptions again? + handleException(e); } } public String[] generateMainMethod() { - return new String[]{ - "bytecodeviewer", - "--decodeenumswitch", - String.valueOf(BytecodeViewer.viewer.decodeenumswitch - .isSelected()), - "--sugarenums", - String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()), - "--decodestringswitch", - String.valueOf(BytecodeViewer.viewer.decodestringswitch - .isSelected()), - "--arrayiter", - String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()), - "--collectioniter", - String.valueOf(BytecodeViewer.viewer.collectioniter - .isSelected()), - "--innerclasses", - String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()), - "--removeboilerplate", - String.valueOf(BytecodeViewer.viewer.removeboilerplate - .isSelected()), - "--removeinnerclasssynthetics", - String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics - .isSelected()), - "--decodelambdas", - String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()), - "--hidebridgemethods", - String.valueOf(BytecodeViewer.viewer.hidebridgemethods - .isSelected()), - "--liftconstructorinit", - String.valueOf(BytecodeViewer.viewer.liftconstructorinit - .isSelected()), - "--removedeadmethods", - String.valueOf(BytecodeViewer.viewer.removedeadmethods - .isSelected()), - "--removebadgenerics", - String.valueOf(BytecodeViewer.viewer.removebadgenerics - .isSelected()), - "--sugarasserts", - String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()), - "--sugarboxing", - String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()), - "--showversion", - String.valueOf(BytecodeViewer.viewer.showversion.isSelected()), - "--decodefinally", - String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()), - "--tidymonitors", - String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()), - "--lenient", - String.valueOf(BytecodeViewer.viewer.lenient.isSelected()), - "--dumpclasspath", - String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()), - "--comments", - String.valueOf(BytecodeViewer.viewer.comments.isSelected()), - "--forcetopsort", - String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()), - "--forcetopsortaggress", - String.valueOf(BytecodeViewer.viewer.forcetopsortaggress - .isSelected()), - "--stringbuffer", - String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()), - "--stringbuilder", - String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()), - "--silent", - String.valueOf(BytecodeViewer.viewer.silent.isSelected()), - "--recover", - String.valueOf(BytecodeViewer.viewer.recover.isSelected()), - "--eclipse", - String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()), - "--override", - String.valueOf(BytecodeViewer.viewer.override.isSelected()), - "--showinferrable", - String.valueOf(BytecodeViewer.viewer.showinferrable - .isSelected()), - "--aexagg", - String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()), - "--forcecondpropagate", - String.valueOf(BytecodeViewer.viewer.forcecondpropagate - .isSelected()), - "--hideutf", - String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()), - "--hidelongstrings", - String.valueOf(BytecodeViewer.viewer.hidelongstrings - .isSelected()), - "--commentmonitors", - String.valueOf(BytecodeViewer.viewer.commentmonitor - .isSelected()), - "--allowcorrecting", - String.valueOf(BytecodeViewer.viewer.allowcorrecting - .isSelected()), - "--labelledblocks", - String.valueOf(BytecodeViewer.viewer.labelledblocks - .isSelected()), - "--j14classobj", - String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()), - "--hidelangimports", - String.valueOf(BytecodeViewer.viewer.hidelangimports - .isSelected()), - "--recovertypeclash", - String.valueOf(BytecodeViewer.viewer.recoverytypeclash - .isSelected()), - "--recovertypehints", - String.valueOf(BytecodeViewer.viewer.recoverytypehints - .isSelected()), - "--forcereturningifs", - String.valueOf(BytecodeViewer.viewer.forceturningifs - .isSelected()), - "--forloopaggcapture", - String.valueOf(BytecodeViewer.viewer.forloopaggcapture - .isSelected()),}; + String[] result = new String[getSettings().size() * 2 + 1]; + result[0] = "bytecodeviewer"; + int index = 1; + for (Settings setting : Settings.values()) { + result[index++] = "--" + setting.getParam(); + result[index++] = String.valueOf(getSettings().isSelected(setting)); + } + return result; } public static String doClass(DCCommonState dcCommonState, byte[] content1) throws Exception { @@ -287,4 +216,76 @@ public class CFRDecompiler extends Decompiler { } } } + + public enum Settings implements DecompilerSettings.Setting { + DECODE_ENUM_SWITCH("decodeenumswitch", "Decode Enum Switch", true), + SUGAR_ENUMS("sugarenums", "SugarEnums", true), + DECODE_STRING_SWITCH("decodestringswitch", "Decode String Switch", true), + ARRAYITER("arrayiter", "Arrayiter", true), + COLLECTIONITER("collectioniter", "Collectioniter", true), + INNER_CLASSES("innerclasses", "Inner Classes", true), + REMOVE_BOILER_PLATE("removeboilerplate", "Remove Boiler Plate", true), + REMOVE_INNER_CLASS_SYNTHETICS("removeinnerclasssynthetics", "Remove Inner Class Synthetics", true), + DECODE_LAMBDAS("decodelambdas", "Decode Lambdas", true), + HIDE_BRIDGE_METHODS("hidebridgemethods", "Hide Bridge Methods", true), + LIFT_CONSTRUCTOR_INIT("liftconstructorinit", "Lift Constructor Init", true), + REMOVE_DEAD_METHODS("removedeadmethods", "Remove Dead Methods", true), + REMOVE_BAD_GENERICS("removebadgenerics", "Remove Bad Generics", true), + SUGAR_ASSERTS("sugarasserts", "Sugar Asserts", true), + SUGAR_BOXING("sugarboxing", "Sugar Boxing", true), + SHOW_VERSION("showversion", "Show Version", true), + DECODE_FINALLY("decodefinally", "Decode Finally", true), + TIDY_MONITORS("tidymonitors", "Tidy Monitors", true), + LENIENT("lenient", "Lenient"), + DUMP_CLASS_PATH("dumpclasspath", "Dump Classpath"), + COMMENTS("comments", "Comments", true), + FORCE_TOP_SORT("forcetopsort", "Force Top Sort", true), + FORCE_TOP_SORT_AGGRESSIVE("forcetopsortaggress", "Force Top Sort Aggressive", true), + STRINGBUFFER("stringbuffer", "StringBuffer"), + STRINGBUILDER("stringbuilder", "StringBuilder", true), + SILENT("silent", "Silent", true), + RECOVER("recover", "Recover", true), + ECLIPSE("eclipse", "Eclipse", true), + OVERRIDE("override", "Override", true), + SHOW_INFERRABLE("showinferrable", "Show Inferrable", true), + FORCE_AGGRESSIVE_EXCEPTION_AGG("aexagg", "Force Aggressive Exception Aggregation", true), + FORCE_COND_PROPAGATE("forcecondpropagate", "Force Conditional Propogation", true), + HIDE_UTF("hideutf", "Hide UTF", true), + HIDE_LONG_STRINGS("hidelongstrings", "Hide Long Strings"), + COMMENT_MONITORS("commentmonitors", "Comment Monitors"), + ALLOW_CORRECTING("allowcorrecting", "Allow Correcting", true), + LABELLED_BLOCKS("labelledblocks", "Labelled Blocks", true), + J14_CLASS_OBJ("j14classobj", "Java 1.4 Class Objects"), + HIDE_LANG_IMPORTS("hidelangimports", "Hide Lang Imports", true), + RECOVER_TYPE_CLASH("recovertypeclash", "Recover Type Clash", true), + RECOVER_TYPE_HINTS("recovertypehints", "Recover Type Hints", true), + FORCE_RETURNING_IFS("forcereturningifs", "Force Returning Ifs", true), + FOR_LOOP_AGG_CAPTURE("forloopaggcapture", "For Loop Aggressive Capture", true); + + private String name; + private String param; + private boolean on; + + Settings(String param, String name) { + this(param, name, false); + } + + Settings(String param, String name, boolean on) { + this.name = name; + this.param = param; + this.on = on; + } + + public String getText() { + return name; + } + + public boolean isDefaultOn() { + return on; + } + + public String getParam() { + return param; + } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java index d6efdf7a..a2030290 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java @@ -1,44 +1,128 @@ package the.bytecode.club.bytecodeviewer.decompilers; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; - +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.DecompilerSettings; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * Used to represent all of the decompilers/disassemblers BCV contains. - * + * * @author Konloch - * + * */ public abstract class Decompiler { - public final static Decompiler bytecode = new ClassNodeDecompiler(); - public final static Decompiler fernflower = new FernFlowerDecompiler(); - public final static Decompiler procyon = new ProcyonDecompiler(); - public final static Decompiler cfr = new CFRDecompiler(); - public final static Decompiler krakatau = new KrakatauDecompiler(); - public final static Decompiler krakatauDA = new KrakatauDisassembler(); - public final static Decompiler smali = new SmaliDisassembler(); - public final static Decompiler jdgui = new JDGUIDecompiler(); - - public abstract String decompileClassNode(ClassNode cn, byte[] b); - public abstract void decompileToZip(String zipName); + private static final Map BY_NAME = new HashMap<>(); + + public final static Decompiler BYTECODE = new ClassNodeDecompiler(); + public final static Decompiler FERNFLOWER = new FernFlowerDecompiler(); + public final static Decompiler PROCYON = new ProcyonDecompiler(); + public final static Decompiler CFR = new CFRDecompiler(); + public final static Decompiler KRAKATAU = new KrakatauDecompiler(); + public final static Decompiler JDGUI = new JDGUIDecompiler(); + public final static Decompiler KRAKATAU_DA = new KrakatauDisassembler(); + public final static Decompiler SMALI = new SmaliDisassembler(); + public final static Decompiler HEXCODE = new Decompiler() { + @Override + public String decompileClassNode(ClassNode cn, byte[] b) { + throw new IllegalArgumentException(); + } + + @Override + public void decompileToZip(String zipName) { + throw new IllegalArgumentException(); + } + + @Override + public String getName() { + return "Hexcode"; + } + + @Override + public DecompilerSettings getSettings() { + throw new IllegalArgumentException(); + } + }; + + public Decompiler() { + BY_NAME.put(getName().toLowerCase().replace(' ', '-'), this); + } + + protected DecompilerSettings settings = new DecompilerSettings(this); + + public abstract String decompileClassNode(ClassNode cn, byte[] b); + + public abstract void decompileToZip(String zipName); + + public abstract String getName(); + + public DecompilerSettings getSettings() { + return settings; + } + + protected String parseException(Throwable e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + e.printStackTrace(); + String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); + return getName() + " encountered a problem! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + + BytecodeViewer.nl + + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + + BytecodeViewer.nl + + exception; + } + + protected void handleException(Exception e) { + new ExceptionUI(e); + } + + protected byte[] fixBytes(byte[] in) { + ClassReader reader = new ClassReader(in); + ClassNode node = new ClassNode(); + reader.accept(node, ClassReader.EXPAND_FRAMES); + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + node.accept(writer); + return writer.toByteArray(); + } + + public static void ensureInitted() { + // Just to make sure the classes is loaded so all decompilers are loaded + } + + public static Decompiler getByName(String name) { + return BY_NAME.get(name.toLowerCase().replace(' ', '-')); + } + + public static Collection getAllDecompilers() { + return Collections.unmodifiableCollection(BY_NAME.values()); + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java index fdfc54cc..4d20e861 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/FernFlowerDecompiler.java @@ -7,15 +7,14 @@ import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger; import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider; import org.jetbrains.java.decompiler.main.extern.IResultSaver; import org.objectweb.asm.tree.ClassNode; -import org.zeroturnaround.zip.ZipUtil; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.DecompilerSettings; import the.bytecode.club.bytecodeviewer.JarUtils; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -48,74 +47,89 @@ import java.util.jar.Manifest; public class FernFlowerDecompiler extends Decompiler { + public FernFlowerDecompiler() { + for (Settings setting : Settings.values()) { + settings.registerSetting(setting); + } + } + @Override - public String decompileClassNode(final ClassNode cn, final byte[] b) { - Map options = main(generateMainMethod()); - - final AtomicReference result = new AtomicReference(); - result.set(null); - - BaseDecompiler baseDecompiler = new BaseDecompiler(new IBytecodeProvider() { - @Override - public byte[] getBytecode(String s, String s1) throws IOException { - byte[] clone = new byte[b.length]; - System.arraycopy(b, 0, clone, 0, b.length); - return clone; - } - }, new IResultSaver() { - @Override - public void saveFolder(String s) { - - } - - @Override - public void copyFile(String s, String s1, String s2) { - - } - - @Override - public void saveClassFile(String s, String s1, String s2, String s3, int[] ints) { - result.set(s3); - } - - @Override - public void createArchive(String s, String s1, Manifest manifest) { - - } - - @Override - public void saveDirEntry(String s, String s1, String s2) { - - } - - @Override - public void copyEntry(String s, String s1, String s2, String s3) { - - } - - @Override - public void saveClassEntry(String s, String s1, String s2, String s3, String s4) { - } - - @Override - public void closeArchive(String s, String s1) { - - } - }, options, new PrintStreamLogger(System.out)); + public String getName() { + return "FernFlower"; + } + @Override + public String decompileClassNode(final ClassNode cn, byte[] b) { try { - baseDecompiler.addSpace(new File("fernflower.class"), true); - baseDecompiler.decompileContext(); - } catch (IOException e) { - e.printStackTrace(); - } - - while (true) { - if (result.get() != null) { - break; + if (cn.version < 49) { + b = fixBytes(b); } + final byte[] bytesToUse = b; + + Map options = main(generateMainMethod()); + + final AtomicReference result = new AtomicReference(); + result.set(null); + + BaseDecompiler baseDecompiler = new BaseDecompiler(new IBytecodeProvider() { + @Override + public byte[] getBytecode(String s, String s1) throws IOException { + byte[] clone = new byte[bytesToUse.length]; + System.arraycopy(bytesToUse, 0, clone, 0, bytesToUse.length); + return clone; + } + }, new IResultSaver() { + @Override + public void saveFolder(String s) { + + } + + @Override + public void copyFile(String s, String s1, String s2) { + + } + + @Override + public void saveClassFile(String s, String s1, String s2, String s3, int[] ints) { + result.set(s3); + } + + @Override + public void createArchive(String s, String s1, Manifest manifest) { + + } + + @Override + public void saveDirEntry(String s, String s1, String s2) { + + } + + @Override + public void copyEntry(String s, String s1, String s2, String s3) { + + } + + @Override + public void saveClassEntry(String s, String s1, String s2, String s3, String s4) { + } + + @Override + public void closeArchive(String s, String s1) { + + } + }, options, new PrintStreamLogger(System.out)); + + baseDecompiler.addSpace(new File(cn.name + ".class"), true); + baseDecompiler.decompileContext(); + while (true) { + if (result.get() != null) { + break; + } + } + return result.get(); + } catch (Exception e) { + return parseException(e); } - return result.get(); } @Override @@ -132,7 +146,7 @@ public class FernFlowerDecompiler extends Decompiler { Files.delete(tempJar); FileUtils.deleteDirectory(outputDir.toFile()); } catch (Exception e) { - e.printStackTrace(); + handleException(e); } } @@ -160,29 +174,62 @@ public class FernFlowerDecompiler extends Decompiler { } private String[] generateMainMethod() { - 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()) - }; + String[] result = new String[getSettings().size()]; + int index = 0; + for (Settings setting : Settings.values()) { + result[index++] = String.format("-%s=%s", setting.getParam(), getSettings().isSelected(setting) ? "1" : "0"); + } + return result; } - private String r(boolean b) { - return b ? "1" : "0"; + public enum Settings implements DecompilerSettings.Setting { + HIDE_BRIDGE_METHODS("rbr", "Hide Bridge Methods", true), + HIDE_SYNTHETIC_CLASS_MEMBERS("rsy", "Hide Synthetic Class Members"), + DECOMPILE_INNER_CLASSES("din", "Decompile Inner Classes", true), + COLLAPSE_14_CLASS_REFERENCES("dc4", "Collapse 1.4 Class References", true), + DECOMPILE_ASSERTIONS("das", "Decompile Assertions", true), + HIDE_EMPTY_SUPER_INVOCATION("hes", "Hide Empty Super Invocation", true), + HIDE_EMPTY_DEFAULT_CONSTRUCTOR("hec", "Hide Empty Default Constructor", true), + DECOMPILE_GENERIC_SIGNATURES("dgs", "Decompile Generic Signatures"), + ASSUME_RETURN_NOT_THROWING_EXCEPTIONS("ner", "Assume return not throwing exceptions", true), + DECOMPILE_ENUMS("den", "Decompile enumerations", true), + REMOVE_GETCLASS("rgn", "Remove getClass()", true), + OUTPUT_NUMBERIC_LITERALS("lit", "Output numeric literals 'as-is'"), + ENCODE_UNICODE("asc", "Encode non-ASCII as unicode escapes"), + INT_1_AS_BOOLEAN_TRUE("bto", "Assume int 1 is boolean true", true), + ALLOW_NOT_SET_SYNTHETIC("nns", "Allow not set synthetic attribute", true), + NAMELESS_TYPES_AS_OBJECT("uto", "Consider nameless types as java.lang.Object", true), + RECOVER_VARIABLE_NAMES("udv", "Recover variable names", true), + REMOVE_EMPTY_EXCEPTIONS("rer", "Remove empty exceptions", true), + DEINLINE_FINALLY("fdi", "De-inline finally", true), + RENAME_AMBIGIOUS_MEMBERS("ren", "Rename ambigious members"), + REMOVE_INTELLIJ_NOTNULL("inn", "Remove IntelliJ @NotNull", true), + DECOMPILE_LAMBDA_TO_ANONYMOUS("lac", "Decompile lambdas to anonymous classes"); + + private String name; + private String param; + private boolean on; + + Settings(String param, String name) { + this(param, name, false); + } + + Settings(String param, String name, boolean on) { + this.name = name; + this.param = param; + this.on = on; + } + + public String getText() { + return name; + } + + public boolean isDefaultOn() { + return on; + } + + public String getParam() { + return param; + } } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/JDGUIDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/JDGUIDecompiler.java index 89f9a0aa..0f48ac2b 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/JDGUIDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/JDGUIDecompiler.java @@ -4,21 +4,33 @@ import jd.cli.preferences.CommonPreferences; import jd.cli.printer.text.PlainTextPrinter; import jd.core.loader.Loader; import jd.core.loader.LoaderException; +import jd.core.model.classfile.ClassFile; +import jd.core.model.classfile.ConstantPool; +import jd.core.model.classfile.attribute.AttributeInnerClasses; +import jd.core.model.classfile.attribute.InnerClass; +import jd.core.model.reference.ReferenceMap; +import jd.core.preferences.Preferences; +import jd.core.printer.Printer; import jd.core.process.DecompilerImpl; -import org.apache.commons.io.FileUtils; -import org.benf.cfr.reader.state.ClassFileSourceImpl; -import org.benf.cfr.reader.state.DCCommonState; -import org.benf.cfr.reader.util.getopt.GetOptParser; -import org.benf.cfr.reader.util.getopt.Options; -import org.benf.cfr.reader.util.getopt.OptionsImpl; +import jd.core.process.analyzer.classfile.ClassFileAnalyzer; +import jd.core.process.analyzer.classfile.ReferenceAnalyzer; +import jd.core.process.deserializer.ClassFileDeserializer; +import jd.core.process.layouter.ClassFileLayouter; +import jd.core.process.writer.ClassFileWriter; import org.objectweb.asm.tree.ClassNode; -import org.zeroturnaround.zip.ZipUtil; import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.JarUtils; -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -46,23 +58,25 @@ import java.util.zip.ZipOutputStream; * * @author Konloch * @author JD-Core developers - * */ public class JDGUIDecompiler extends Decompiler { + @Override + public String getName() { + return "JDGUI"; + } @Override - public String decompileClassNode(ClassNode cn, final byte[] b) { + public String decompileClassNode(ClassNode cn, byte[] b) { try { + if (cn.version < 49) { + b = fixBytes(b); + } ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); decompile(b, outputStream); return outputStream.toString("UTF-8"); } catch (Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); - return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception; + return parseException(e); } } @@ -92,7 +106,7 @@ public class JDGUIDecompiler extends Decompiler { } zipOutputStream.close(); } catch (Exception e) { - e.printStackTrace(); //TODO How to handle exceptions again? + handleException(e); } } @@ -119,6 +133,7 @@ public class JDGUIDecompiler extends Decompiler { return true; } }; + new DecompilerImpl().decompile(preferences, customLoader, new PlainTextPrinter(preferences, new PrintStream(to, false, "UTF-8")), "BytecodeViewer.class"); } } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDecompiler.java index 0395137d..6625fee7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDecompiler.java @@ -1,185 +1,179 @@ package the.bytecode.club.bytecodeviewer.decompilers; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.objectweb.asm.tree.ClassNode; +import org.zeroturnaround.zip.ZipUtil; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.MiscUtils; +import the.bytecode.club.bytecodeviewer.Settings; + 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.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.MiscUtils; -import the.bytecode.club.bytecodeviewer.ZipUtils; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * Krakatau Java Decompiler Wrapper, requires Python 2.7 - * - * @author Konloch * + * @author Konloch */ public class KrakatauDecompiler extends Decompiler { + @Override + public String getName() { + return "Krakatau"; + } - public String quick() { - if(BytecodeViewer.library.isEmpty()) - return ""; - else - return ";"+BytecodeViewer.library; - } - - public String decompileClassNode(ClassNode cn, byte[] b) { - if(BytecodeViewer.python.equals("")) { - BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); - BytecodeViewer.viewer.pythonC(); - } - if(BytecodeViewer.rt.equals("")) { - BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)"); - BytecodeViewer.viewer.rtC(); - } + public String quick() { + if (Settings.PATH.isEmpty()) return ""; + else return ";" + Settings.PATH.get(); + } - if(BytecodeViewer.python.equals("")) { - BytecodeViewer.showMessage("You need to set Python!"); - return "Set your paths"; - } + public String decompileClassNode(ClassNode cn, byte[] b) { + if (Settings.PYTHON2_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); + BytecodeViewer.viewer.pythonC(); + } + if (Settings.RT_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)"); + BytecodeViewer.viewer.rtC(); + } - if(BytecodeViewer.rt.equals("")) { - BytecodeViewer.showMessage("You need to set RT.jar!"); - return "Set your paths"; - } - - String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl; - - final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); - tempDirectory.mkdir(); - final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar"); - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath()); - - BytecodeViewer.sm.stopBlocking(); - try { - ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python, - "-O", //love you storyyeller <3 - BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py", - "-skip", //love you storyyeller <3 - "-nauto", - "-path", - BytecodeViewer.rt+";"+tempJar.getAbsolutePath()+quick(), - "-out", - tempDirectory.getAbsolutePath(), - cn.name+".class" - ); + if (Settings.PYTHON2_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set Python!"); + return "Set your paths"; + } - Process process = pb.start(); - BytecodeViewer.createdProcesses.add(process); - - //Read out dir output - InputStream is = process.getInputStream(); - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr); - String log = "Process:"+BytecodeViewer.nl+BytecodeViewer.nl; - String line; - while ((line = br.readLine()) != null) { - log += BytecodeViewer.nl + line; - } - br.close(); + if (Settings.RT_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set RT.jar!"); + return "Set your paths"; + } - log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl; - is = process.getErrorStream(); - isr = new InputStreamReader(is); - br = new BufferedReader(isr); - while ((line = br.readLine()) != null) { - log += BytecodeViewer.nl + line; - } - br.close(); - - int exitValue = process.waitFor(); - log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue; - s = log; + String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl; - s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".java"); - tempDirectory.delete(); - tempJar.delete(); - } catch(Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - s += BytecodeViewer.nl+"Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); - } finally { - BytecodeViewer.sm.setBlocking(); - } - - return s; - } - public void decompileToZip(String zipName) { - if(BytecodeViewer.python.equals("")) { - BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); - BytecodeViewer.viewer.pythonC(); - } - if(BytecodeViewer.rt.equals("")) { - BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)"); - BytecodeViewer.viewer.rtC(); - } - - String ran = MiscUtils.randomString(32); - final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs); - tempDirectory.mkdir(); - final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar"); - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); - - BytecodeViewer.sm.stopBlocking(); - try { - ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python, - "-O", //love you storyyeller <3 - BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py", - "-skip", //love you storyyeller <3 - "-nauto", - "-path", - BytecodeViewer.rt+";"+tempJar.getAbsolutePath(), - "-out", - tempDirectory.getAbsolutePath(), - tempJar.getAbsolutePath() - ); + try { + final Path outputJar = Files.createTempFile("kdeout", ".zip"); + final Path inputJar = Files.createTempFile("kdein", ".jar"); + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), inputJar.toAbsolutePath().toString()); - Process process = pb.start(); - BytecodeViewer.createdProcesses.add(process); - process.waitFor(); - MiscUtils.printProcess(process); - - // ZipUtils.zipDirectory(tempDirectory, new File(zipName)); - ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran); - - //tempDirectory.delete(); - tempJar.delete(); - } catch(Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } finally { - BytecodeViewer.sm.setBlocking(); - } - } + BytecodeViewer.sm.stopBlocking(); + ProcessBuilder pb = new ProcessBuilder(Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3 + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "decompile.py", "-skip", //love you storyyeller <3 + "-nauto", "-path", Settings.RT_LOCATION.get() + ";" + inputJar.toAbsolutePath().toString() + quick(), "-out", outputJar.toAbsolutePath().toString(), cn.name + ".class"); + Process process = pb.start(); + BytecodeViewer.createdProcesses.add(process); + + //Read out dir output + InputStream is = process.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String log = "Process:" + BytecodeViewer.nl + BytecodeViewer.nl; + String line; + while ((line = br.readLine()) != null) { + log += BytecodeViewer.nl + line; + } + br.close(); + + log += BytecodeViewer.nl + BytecodeViewer.nl + "Error:" + BytecodeViewer.nl + BytecodeViewer.nl; + is = process.getErrorStream(); + isr = new InputStreamReader(is); + br = new BufferedReader(isr); + while ((line = br.readLine()) != null) { + log += BytecodeViewer.nl + line; + } + br.close(); + + int exitValue = process.waitFor(); + log += BytecodeViewer.nl + BytecodeViewer.nl + "Exit Value is " + exitValue; + s = log; + + ZipFile zipFile= new ZipFile(outputJar.toFile()); + Enumeration entries = zipFile.entries(); + byte[] data = null; + while (entries.hasMoreElements()) { + ZipEntry next = entries.nextElement(); + if (next.getName().equals(cn.name + ".java")) { + data = IOUtils.toByteArray(zipFile.getInputStream(next)); + } + } + zipFile.close(); + Files.delete(inputJar); + Files.delete(outputJar); + return new String(data, "UTF-8"); + } catch (Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + e.printStackTrace(); + s += BytecodeViewer.nl + "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); + } finally { + BytecodeViewer.sm.setBlocking(); + } + + return s; + } + + public void decompileToZip(String zipName) { + if (Settings.PYTHON2_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); + BytecodeViewer.viewer.pythonC(); + } + if (Settings.RT_LOCATION.isEmpty()) { + BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)"); + BytecodeViewer.viewer.rtC(); + } + + + try { + File tempDir = Files.createTempDirectory("krakatauoutput").toFile(); + File tempJar = new File(tempDir, "temp.jar"); + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath()); + + BytecodeViewer.sm.stopBlocking(); + ProcessBuilder pb = new ProcessBuilder(Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3 + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "decompile.py", "-skip", //love you storyyeller <3 + "-nauto", "-path", Settings.RT_LOCATION.get() + ";" + tempJar.getAbsolutePath(), "-out", tempDir.getAbsolutePath(), tempJar.getAbsolutePath()); + + Process process = pb.start(); + BytecodeViewer.createdProcesses.add(process); + MiscUtils.printProcess(process); + process.waitFor(); + + tempJar.delete(); + ZipUtil.pack(tempDir, new File(zipName)); + FileUtils.deleteDirectory(tempDir); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } finally { + BytecodeViewer.sm.setBlocking(); + } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDisassembler.java index 5d1c32a0..9209406e 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/KrakatauDisassembler.java @@ -1,20 +1,25 @@ package the.bytecode.club.bytecodeviewer.decompilers; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.objectweb.asm.tree.ClassNode; +import org.zeroturnaround.zip.ZipUtil; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.MiscUtils; +import the.bytecode.club.bytecodeviewer.Settings; + 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.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.MiscUtils; -import the.bytecode.club.bytecodeviewer.ZipUtils; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -36,47 +41,49 @@ import the.bytecode.club.bytecodeviewer.ZipUtils; /** * Krakatau Java Disassembler Wrapper, requires Python 2.7 - * + * * @author Konloch * */ public class KrakatauDisassembler extends Decompiler { + @Override + public String getName() { + return "Krakatau Disassembler"; + } public String decompileClassNode(ClassNode cn, byte[] b) { - if(BytecodeViewer.python.equals("")) { + if(Settings.PYTHON2_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); BytecodeViewer.viewer.pythonC(); } - - if(BytecodeViewer.python.equals("")) { + + if(Settings.PYTHON2_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set Python!"); return "Set your paths"; } - + String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl; - - final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs); - tempDirectory.mkdir(); - final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar"); - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); - - BytecodeViewer.sm.stopBlocking(); try { + final Path outputJar = Files.createTempFile("kdisout", ".zip"); + final Path inputJar = Files.createTempFile("kdisin", ".jar"); + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), inputJar.toAbsolutePath().toString()); + + BytecodeViewer.sm.stopBlocking(); ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python, + Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3 - BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "disassemble.py", + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "disassemble.py", "-path", - tempJar.getAbsolutePath(), + inputJar.toAbsolutePath().toString(), "-out", - tempDirectory.getAbsolutePath(), + outputJar.toAbsolutePath().toString(), cn.name+".class" ); Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); - + //Read out dir output InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); @@ -96,15 +103,24 @@ public class KrakatauDisassembler extends Decompiler { log += BytecodeViewer.nl + line; } br.close(); - + int exitValue = process.waitFor(); log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue; s = log; - - //if the motherfucker failed this'll fail, aka wont set. - s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".j"); - tempDirectory.delete(); - tempJar.delete(); + + ZipFile zipFile= new ZipFile(outputJar.toFile()); + Enumeration entries = zipFile.entries(); + byte[] data = null; + while (entries.hasMoreElements()) { + ZipEntry next = entries.nextElement(); + if (next.getName().equals(cn.name + ".j")) { + data = IOUtils.toByteArray(zipFile.getInputStream(next)); + } + } + zipFile.close(); + Files.delete(inputJar); + Files.delete(outputJar); + return new String(data, "UTF-8"); } catch(Exception e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); @@ -117,25 +133,25 @@ public class KrakatauDisassembler extends Decompiler { } @Override public void decompileToZip(String zipName) { - if(BytecodeViewer.python.equals("")) { + if(Settings.PYTHON2_LOCATION.isEmpty()) { BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path."); BytecodeViewer.viewer.pythonC(); } - + String ran = MiscUtils.randomString(32); - final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs); + final File tempDirectory = new File(BytecodeViewer.tempDir, ran + BytecodeViewer.fs); tempDirectory.mkdir(); - final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar"); - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); - + final File tempJar = new File(BytecodeViewer.tempDir, "temp.jar"); + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath()); + BytecodeViewer.sm.stopBlocking(); try { ProcessBuilder pb = new ProcessBuilder( - BytecodeViewer.python, + Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3 - BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "disassemble.py", + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "disassemble.py", "-path", - BytecodeViewer.rt+";"+tempJar.getAbsolutePath(), + Settings.RT_LOCATION.get()+";"+tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath() @@ -144,10 +160,9 @@ public class KrakatauDisassembler extends Decompiler { Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); process.waitFor(); - - // ZipUtils.zipDirectory(tempDirectory, new File(zipName)); - ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran); - + + ZipUtil.pack(tempDirectory, new File(zipName)); + //tempDirectory.delete(); tempJar.delete(); } catch(Exception e) { diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/ProcyonDecompiler.java index 61691254..b190a1fc 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/ProcyonDecompiler.java @@ -1,19 +1,34 @@ package the.bytecode.club.bytecodeviewer.decompilers; +import com.beust.jcommander.JCommander; import com.strobel.assembler.InputTypeLoader; -import com.strobel.assembler.metadata.*; +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.core.StringUtilities; +import com.strobel.decompiler.CommandLineOptions; import com.strobel.decompiler.DecompilationOptions; import com.strobel.decompiler.DecompilerSettings; import com.strobel.decompiler.PlainTextOutput; -import com.strobel.decompiler.languages.java.JavaFormattingOptions; +import com.strobel.decompiler.languages.Languages; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.MiscUtils; -import java.io.*; -import java.util.*; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipException; @@ -42,126 +57,127 @@ import java.util.zip.ZipOutputStream; * * @author Konloch * @author DeathMarine - * */ public class ProcyonDecompiler extends Decompiler { + public ProcyonDecompiler() { + for (Settings setting : Settings.values()) { + settings.registerSetting(setting); + } + } + + @Override + public String getName() { + return "Procyon"; + } + public DecompilerSettings getDecompilerSettings() { + CommandLineOptions options = new CommandLineOptions(); + JCommander jCommander = new JCommander(options); + String[] args = new String[Settings.values().length * 2]; + int index = 0; + for (the.bytecode.club.bytecodeviewer.DecompilerSettings.Setting setting : Settings.values()) { + args[index++] = "--" + setting.getParam(); + args[index++] = String.valueOf(getSettings().isSelected(setting)); + } + jCommander.parse(args); DecompilerSettings settings = new DecompilerSettings(); - settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6 - .isSelected()); - settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11 - .isSelected()); - settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine - .isSelected()); - settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3 - .isSelected()); - settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4 - .isSelected()); - settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7 - .isSelected()); - settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences - .isSelected()); - settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables - .isSelected()); - settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8 - .isSelected()); - settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9 - .isSelected()); - settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10 - .isSelected()); - settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2 - .isSelected()); - settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5 - .isSelected()); - settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1 - .isSelected()); - settings.setFormattingOptions(JavaFormattingOptions.createDefault()); + settings.setFlattenSwitchBlocks(options.getFlattenSwitchBlocks()); + settings.setForceExplicitImports(!options.getCollapseImports()); + settings.setForceExplicitTypeArguments(options.getForceExplicitTypeArguments()); + settings.setRetainRedundantCasts(options.getRetainRedundantCasts()); + settings.setShowSyntheticMembers(options.getShowSyntheticMembers()); + settings.setExcludeNestedTypes(options.getExcludeNestedTypes()); + settings.setOutputDirectory(options.getOutputDirectory()); + settings.setIncludeLineNumbersInBytecode(options.getIncludeLineNumbers()); + settings.setRetainPointlessSwitches(options.getRetainPointlessSwitches()); + settings.setUnicodeOutputEnabled(options.isUnicodeOutputEnabled()); + settings.setMergeVariables(options.getMergeVariables()); + settings.setShowDebugLineNumbers(options.getShowDebugLineNumbers()); + settings.setSimplifyMemberReferences(options.getSimplifyMemberReferences()); + settings.setDisableForEachTransforms(options.getDisableForEachTransforms()); + settings.setTypeLoader(new InputTypeLoader()); + if (options.isRawBytecode()) { + settings.setLanguage(Languages.bytecode()); + } else if (options.isBytecodeAst()) { + settings.setLanguage(options.isUnoptimized() ? Languages.bytecodeAstUnoptimized() : Languages.bytecodeAst()); + } return settings; } @Override - public String decompileClassNode(ClassNode cn, final byte[] b) { - String exception = ""; + public String decompileClassNode(final ClassNode cn, byte[] b) { try { - String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs - + "temp"; - - final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class"); - - try { - final FileOutputStream fos = new FileOutputStream(tempClass); - - fos.write(b); - - fos.close(); - } catch (final IOException e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + if (cn.version < 49) { + b = fixBytes(b); } - + final byte[] bytesToUse = b; + final Map loadedClasses = BytecodeViewer.getLoadedBytes(); DecompilerSettings settings = getDecompilerSettings(); - MetadataSystem metadataSystem = new MetadataSystem(new InputTypeLoader()); - TypeReference type = metadataSystem.lookupType(tempClass.getCanonicalPath()); + MetadataSystem metadataSystem = new MetadataSystem(new ITypeLoader() { + private InputTypeLoader backLoader = new InputTypeLoader(); + @Override + public boolean tryLoadType(String s, Buffer buffer) { + if (s.equals(cn.name)) { + buffer.putByteArray(bytesToUse, 0, bytesToUse.length); + buffer.position(0); + return true; + } else { + byte[] toUse = loadedClasses.get(s + ".class"); + if (toUse != null) { + buffer.putByteArray(toUse, 0, toUse.length); + buffer.position(0); + return true; + } else { + return backLoader.tryLoadType(s, buffer); + } + } + } + }); + TypeReference type = metadataSystem.lookupType(cn.name); DecompilationOptions decompilationOptions = new DecompilationOptions(); decompilationOptions.setSettings(DecompilerSettings.javaDefaults()); decompilationOptions.setFullDecompilation(true); - TypeDefinition resolvedType = null; if (type == null || ((resolvedType = type.resolve()) == null)) { throw new Exception("Unable to resolve type."); } StringWriter stringwriter = new StringWriter(); - settings.getLanguage().decompileType(resolvedType, - new PlainTextOutput(stringwriter), decompilationOptions); + settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions); String decompiledSource = stringwriter.toString(); - return decompiledSource; - } catch (Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - - exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); + } catch (Throwable e) { + return parseException(e); } - return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception; } @Override public void decompileToZip(String zipName) { - File tempZip = new File(BytecodeViewer.tempDirectory - + BytecodeViewer.fs + "temp.jar"); - if (tempZip.exists()) - tempZip.delete(); + File tempZip = new File(BytecodeViewer.tempDir, "temp.jar"); + if (tempZip.exists()) tempZip.delete(); - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), - tempZip.getAbsolutePath()); + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempZip.getAbsolutePath()); try { doSaveJarDecompiled(tempZip, new File(zipName)); } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + handleException(e); } } /** - * * @author DeathMarine - * */ - private void doSaveJarDecompiled(File inFile, File outFile) - throws Exception { + 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(); - MetadataSystem metadataSystem = new MetadataSystem(typeLoader); - ITypeLoader jarLoader = new JarTypeLoader(jfile); - typeLoader.getTypeLoaders().add(jarLoader); + MetadataSystem metadataSystem = new MetadataSystem(new JarTypeLoader(jfile)); DecompilationOptions decompilationOptions = new DecompilationOptions(); decompilationOptions.setSettings(settings); @@ -172,24 +188,18 @@ public class ProcyonDecompiler extends Decompiler { while (ent.hasMoreElements()) { JarEntry entry = ent.nextElement(); if (entry.getName().endsWith(".class")) { - JarEntry etn = new JarEntry(entry.getName().replace( - ".class", ".java")); + 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); + String internalName = StringUtilities.removeRight(entry.getName(), ".class"); + TypeReference type = metadataSystem.lookupType(internalName); TypeDefinition resolvedType = null; - 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 { out.closeEntry(); @@ -198,8 +208,7 @@ public class ProcyonDecompiler extends Decompiler { } 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 { @@ -229,36 +238,44 @@ public class ProcyonDecompiler extends Decompiler { } } - /** - * - * @author DeathMarine - * - */ - public final class LuytenTypeLoader implements ITypeLoader { - private final List _typeLoaders; + public enum Settings implements the.bytecode.club.bytecodeviewer.DecompilerSettings.Setting { + SHOW_DEBUG_LINE_NUMBERS("debug-line-numbers", "Show Debug Line Numbers"), + SIMPLIFY_MEMBER_REFERENCES("simplify-member-references", "Simplify Member References"), + MERGE_VARIABLES("merge-variables", "Merge Variables"), + UNICODE_OUTPUT("unicode", "Allow Unicode Output"), + RETAIN_POINTLESS_SWITCHES("retain-pointless-switches", "Retain pointless switches"), + INCLUDE_LINE_NUMBERS_IN_BYTECODE("with-line-numbers", "Include line numbers in bytecode"), + RETAIN_REDUNDANT_CASTS("retain-explicit-casts", "Retain redundant casts"), + SHOW_SYNTHETIC_MEMBERS("show-synthetic", "Show synthetic members"), + FORCE_EXPLICIT_TYPE_ARGS("explicit-type-arguments", "Force explicit type arguments"), + FORCE_EXPLICIT_IMPORTS("explicit-imports", "Force explicit imports"), + FLATTEN_SWITCH_BLOCKS("flatten-switch-blocks", "Flatten switch blocks"), + EXCLUDE_NESTED_TYPES("exclude-nested", "Exclude nested types"); - public LuytenTypeLoader() { - _typeLoaders = new ArrayList(); - _typeLoaders.add(new InputTypeLoader()); + private String name; + private String param; + private boolean on; + + Settings(String param, String name) { + this(param, name, false); } - public final List getTypeLoaders() { - return _typeLoaders; + Settings(String param, String name, boolean on) { + this.name = name; + this.param = param; + this.on = on; } - @Override - public boolean tryLoadType(final String internalName, - final Buffer buffer) { - for (final ITypeLoader typeLoader : _typeLoaders) { - if (typeLoader.tryLoadType(internalName, buffer)) { - return true; - } + public String getText() { + return name; + } - buffer.reset(); - } + public boolean isDefaultOn() { + return on; + } - return false; + public String getParam() { + return param; } } - } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java index dd3f86ed..1230d42f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/SmaliDisassembler.java @@ -1,100 +1,103 @@ package the.bytecode.club.bytecodeviewer.decompilers; +import org.apache.commons.io.FileUtils; +import org.objectweb.asm.tree.ClassNode; +import org.zeroturnaround.zip.ZipUtil; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Dex2Jar; +import the.bytecode.club.bytecodeviewer.MiscUtils; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import me.konloch.kontainer.io.DiskReader; - -import org.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.Dex2Jar; -import the.bytecode.club.bytecodeviewer.MiscUtils; -import the.bytecode.club.bytecodeviewer.ZipUtils; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * Smali Disassembler Wrapper - * + * * @author Konloch * */ public class SmaliDisassembler extends Decompiler { - - public String decompileClassNode(ClassNode cn, byte[] b) { - String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs - + "temp"; - - String start = MiscUtils.getUniqueName(fileStart, ".class"); + @Override + public String getName() { + return "Smali"; + } - final File tempClass = new File(start + ".class"); - final File tempZip = new File(start + ".jar"); - final File tempDex = new File(start + ".dex"); - final File tempSmali = new File(start + "-smali"); //output directory - - try { - final FileOutputStream fos = new FileOutputStream(tempClass); + public String decompileClassNode(ClassNode cn, byte[] b) { + String fileStart = BytecodeViewer.tempDir.getAbsolutePath()+ BytecodeViewer.fs + + "temp"; - fos.write(b); + String start = MiscUtils.getUniqueName(fileStart, ".class"); - fos.close(); - } catch (final IOException e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - - ZipUtils.zipFile(tempClass, tempZip); + final File tempClass = new File(start + ".class"); + final File tempZip = new File(start + ".jar"); + final File tempDex = new File(start + ".dex"); + final File tempSmali = new File(start + "-smali"); //output directory - Dex2Jar.saveAsDex(tempZip, tempDex); - - try { - org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()}); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - - File outputSmali = null; - - boolean found = false; - File current = tempSmali; - while(!found) { - File f = current.listFiles()[0]; - if(f.isDirectory()) - current = f; - else { - outputSmali = f; - found = true; - } - - } - try { - return DiskReader.loadAsString(outputSmali.getAbsolutePath()); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - - return null; - } + try { + final FileOutputStream fos = new FileOutputStream(tempClass); - @Override public void decompileToZip(String zipName) { - - } + fos.write(b); + + fos.close(); + } catch (final IOException e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + + ZipUtil.packEntry(tempClass, tempZip); + + Dex2Jar.saveAsDex(tempZip, tempDex); + + try { + org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()}); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + + File outputSmali = null; + + boolean found = false; + File current = tempSmali; + while (!found) { + File f = current.listFiles()[0]; + if (f.isDirectory()) + current = f; + else { + outputSmali = f; + found = true; + } + + } + try { + return FileUtils.readFileToString(outputSmali, "UTF-8"); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + + return null; + } + + @Override + public void decompileToZip(String zipName) { + + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/ClassNodeDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/ClassNodeDecompiler.java index 4d476963..ec9f71e0 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/ClassNodeDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/ClassNodeDecompiler.java @@ -1,159 +1,188 @@ 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.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InnerClassNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.DecompilerSettings; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; +import java.util.ArrayList; +import java.util.List; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** - * + * * @author Konloch * @author Bibl - * + * */ public class ClassNodeDecompiler extends Decompiler { - public String decompileClassNode(ClassNode cn, byte[] b) { - return decompile(new PrefixedStringBuilder(), - new ArrayList(), cn).toString(); - } + public ClassNodeDecompiler() { + for (Settings setting : Settings.values()) { + settings.registerSetting(setting); + } + } - protected static PrefixedStringBuilder decompile( - PrefixedStringBuilder sb, ArrayList decompiledClasses, - ClassNode cn) { - ArrayList 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")) { - sb.append(" extends "); - sb.append(cn.superName); - } + @Override + public String getName() { + return "Bytecode"; + } - int amountOfInterfaces = cn.interfaces.size(); - if (amountOfInterfaces > 0) { - sb.append(" implements "); - sb.append(cn.interfaces.get(0)); - if (amountOfInterfaces > 1) { - // sb.append(","); - } - for (int i = 1; i < amountOfInterfaces; i++) { - sb.append(", "); - sb.append(cn.interfaces.get(i)); - } - } - sb.append(" {"); - sb.append(BytecodeViewer.nl); - for (FieldNode fn : (List) cn.fields) { - sb.append(BytecodeViewer.nl); - sb.append(" "); - FieldNodeDecompiler.decompile(sb, fn); - } - if (cn.fields.size() > 0) { - sb.append(BytecodeViewer.nl); - } - for (MethodNode mn : (List) cn.methods) { - sb.append(BytecodeViewer.nl); - MethodNodeDecompiler.decompile(sb, mn, cn); - } + public String decompileClassNode(ClassNode cn, byte[] b) { + return decompile(new PrefixedStringBuilder(), new ArrayList(), cn).toString(); + } - for (Object o : cn.innerClasses) { - InnerClassNode innerClassNode = (InnerClassNode) o; - String innerClassName = innerClassNode.name; - if ((innerClassName != null) - && !decompiledClasses.contains(innerClassName)) { - decompiledClasses.add(innerClassName); - ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName); - if (cn1 != null) { - sb.appendPrefix(" "); - sb.append(BytecodeViewer.nl + BytecodeViewer.nl); - sb = decompile(sb, decompiledClasses, cn1); - sb.trimPrefix(5); - sb.append(BytecodeViewer.nl); - } else { - unableToDecompile.add(innerClassName); - } - } - } + protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, ArrayList decompiledClasses, ClassNode cn) { + ArrayList 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")) { + sb.append(" extends "); + sb.append(cn.superName); + } - if (!unableToDecompile.isEmpty()) { - sb.append("//the following inner classes couldn't be decompiled: "); - for (String s : unableToDecompile) { - sb.append(s); - sb.append(" "); - } - sb.append(BytecodeViewer.nl); - } + int amountOfInterfaces = cn.interfaces.size(); + if (amountOfInterfaces > 0) { + sb.append(" implements "); + sb.append(cn.interfaces.get(0)); + if (amountOfInterfaces > 1) { + // sb.append(","); + } + for (int i = 1; i < amountOfInterfaces; i++) { + sb.append(", "); + sb.append(cn.interfaces.get(i)); + } + } + sb.append(" {"); + sb.append(BytecodeViewer.nl); + for (FieldNode fn : (List) cn.fields) { + sb.append(BytecodeViewer.nl); + sb.append(" "); + FieldNodeDecompiler.decompile(sb, fn); + } + if (cn.fields.size() > 0) { + sb.append(BytecodeViewer.nl); + } + for (MethodNode mn : (List) cn.methods) { + sb.append(BytecodeViewer.nl); + MethodNodeDecompiler.decompile(sb, mn, cn); + } - sb.append("}"); - // System.out.println("Wrote end for " + cn.name + - // " with prefix length: " + sb.prefix.length()); - return sb; - } + for (Object o : cn.innerClasses) { + InnerClassNode innerClassNode = (InnerClassNode) o; + String innerClassName = innerClassNode.name; + if ((innerClassName != null) && !decompiledClasses.contains(innerClassName)) { + decompiledClasses.add(innerClassName); + ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName); + if (cn1 != null) { + sb.appendPrefix(" "); + sb.append(BytecodeViewer.nl + BytecodeViewer.nl); + sb = decompile(sb, decompiledClasses, cn1); + sb.trimPrefix(5); + sb.append(BytecodeViewer.nl); + } else { + unableToDecompile.add(innerClassName); + } + } + } - public static String getAccessString(int access) { - List tokens = new ArrayList(); - if ((access & Opcodes.ACC_PUBLIC) != 0) - tokens.add("public"); - if ((access & Opcodes.ACC_PRIVATE) != 0) - tokens.add("private"); - if ((access & Opcodes.ACC_PROTECTED) != 0) - tokens.add("protected"); - if ((access & Opcodes.ACC_FINAL) != 0) - tokens.add("final"); - if ((access & Opcodes.ACC_SYNTHETIC) != 0) - tokens.add("synthetic"); - // if ((access & Opcodes.ACC_SUPER) != 0) - // tokens.add("super"); implied by invokespecial insn - if ((access & Opcodes.ACC_ABSTRACT) != 0) - tokens.add("abstract"); - if ((access & Opcodes.ACC_INTERFACE) != 0) - tokens.add("interface"); - if ((access & Opcodes.ACC_ENUM) != 0) - tokens.add("enum"); - if ((access & Opcodes.ACC_ANNOTATION) != 0) - tokens.add("annotation"); - if (!tokens.contains("interface") && !tokens.contains("enum") - && !tokens.contains("annotation")) - tokens.add("class"); - if (tokens.size() == 0) - return "[Error parsing]"; + if (!unableToDecompile.isEmpty()) { + sb.append("//the following inner classes couldn't be decompiled: "); + for (String s : unableToDecompile) { + sb.append(s); + sb.append(" "); + } + sb.append(BytecodeViewer.nl); + } - // hackery delimeters - StringBuilder sb = new StringBuilder(tokens.get(0)); - for (int i = 1; i < tokens.size(); i++) { - sb.append(" "); - sb.append(tokens.get(i)); - } - return sb.toString(); - } + sb.append("}"); + // System.out.println("Wrote end for " + cn.name + + // " with prefix length: " + sb.prefix.length()); + return sb; + } - @Override public void decompileToZip(String zipName) { } + public static String getAccessString(int access) { + List tokens = new ArrayList(); + if ((access & Opcodes.ACC_PUBLIC) != 0) tokens.add("public"); + if ((access & Opcodes.ACC_PRIVATE) != 0) tokens.add("private"); + if ((access & Opcodes.ACC_PROTECTED) != 0) tokens.add("protected"); + if ((access & Opcodes.ACC_FINAL) != 0) tokens.add("final"); + if ((access & Opcodes.ACC_SYNTHETIC) != 0) tokens.add("synthetic"); + // if ((access & Opcodes.ACC_SUPER) != 0) + // tokens.add("super"); implied by invokespecial insn + if ((access & Opcodes.ACC_ABSTRACT) != 0) tokens.add("abstract"); + if ((access & Opcodes.ACC_INTERFACE) != 0) tokens.add("interface"); + if ((access & Opcodes.ACC_ENUM) != 0) tokens.add("enum"); + if ((access & Opcodes.ACC_ANNOTATION) != 0) tokens.add("annotation"); + if (!tokens.contains("interface") && !tokens.contains("enum") && !tokens.contains("annotation")) + tokens.add("class"); + if (tokens.size() == 0) return "[Error parsing]"; + + // hackery delimeters + StringBuilder sb = new StringBuilder(tokens.get(0)); + for (int i = 1; i < tokens.size(); i++) { + sb.append(" "); + sb.append(tokens.get(i)); + } + return sb.toString(); + } + + @Override + public void decompileToZip(String zipName) { + } + + public enum Settings implements DecompilerSettings.Setting { + DEBUG_HELPERS("debug-helpers", "Debug Helpers", true), + APPEND_BRACKETS_TO_LABELS("append-brackets-to-labels", "Append Brackets to Labels", true); + + private String name; + private String param; + private boolean on; + + Settings(String param, String name) { + this(param, name, false); + } + + Settings(String param, String name, boolean on) { + this.name = name; + this.param = param; + this.on = on; + } + + public String getText() { + return name; + } + + public boolean isDefaultOn() { + return on; + } + + public String getParam() { + return param; + } + } } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/FieldNodeDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/FieldNodeDecompiler.java index f54eaba7..9cf4da55 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/FieldNodeDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/FieldNodeDecompiler.java @@ -1,12 +1,12 @@ 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; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPattern.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPattern.java index d68cc538..9c30a47f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPattern.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPattern.java @@ -1,7 +1,16 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode; -import java.util.Arrays; - +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 org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.FieldInsnNode; @@ -15,17 +24,7 @@ import org.objectweb.asm.tree.MultiANewArrayInsnNode; import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.VarInsnNode; -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; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java index 31aa786c..e9e90231 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java @@ -1,16 +1,6 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - +import eu.bibl.banalysis.asm.desc.OpcodeInfo; import org.apache.commons.lang3.StringEscapeUtils; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; @@ -30,325 +20,306 @@ import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.TableSwitchInsnNode; import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.VarInsnNode; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import eu.bibl.banalysis.asm.desc.OpcodeInfo; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** - * + * * @author Konloch * @author Bibl - * + * */ public class InstructionPrinter { - /** The MethodNode to print **/ - protected MethodNode mNode; - private TypeAndName[] args; + /** The MethodNode to print **/ + protected MethodNode mNode; + private TypeAndName[] args; - protected int[] pattern; - protected boolean match; - protected InstructionSearcher searcher; + protected int[] pattern; + protected boolean match; + protected InstructionSearcher searcher; - protected List matchedInsns; - protected Map labels; + protected List matchedInsns; + protected Map labels; - public InstructionPrinter(MethodNode m, TypeAndName[] args) { - this.args = args; - mNode = m; - labels = new HashMap(); - // matchedInsns = new ArrayList(); // ingnored because - // match = false - match = false; - } + public InstructionPrinter(MethodNode m, TypeAndName[] args) { + this.args = args; + mNode = m; + labels = new HashMap(); + // matchedInsns = new ArrayList(); // ingnored because + // match = false + match = false; + } - public InstructionPrinter(MethodNode m, InstructionPattern pattern, - TypeAndName[] args) { - this.args = args; - mNode = m; - labels = new HashMap(); - searcher = new InstructionSearcher(m.instructions, pattern); - match = searcher.search(); - if (match) { - for (AbstractInsnNode[] ains : searcher.getMatches()) { - for (AbstractInsnNode ain : ains) { - matchedInsns.add(ain); - } - } - } - } + public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args) { + this.args = args; + mNode = m; + labels = new HashMap(); + searcher = new InstructionSearcher(m.instructions, pattern); + match = searcher.search(); + if (match) { + for (AbstractInsnNode[] ains : searcher.getMatches()) { + for (AbstractInsnNode ain : ains) { + matchedInsns.add(ain); + } + } + } + } - /** - * Creates the print - * - * @return The print as an ArrayList - */ - public ArrayList createPrint() { - ArrayList info = new ArrayList(); - ListIterator it = mNode.instructions.iterator(); - boolean firstLabel = false; - while (it.hasNext()) { - AbstractInsnNode ain = (AbstractInsnNode) it.next(); - String line = ""; - if (ain instanceof VarInsnNode) { - line = printVarInsnNode((VarInsnNode) ain, it); - } else if (ain instanceof IntInsnNode) { - line = printIntInsnNode((IntInsnNode) ain, it); - } else if (ain instanceof FieldInsnNode) { - line = printFieldInsnNode((FieldInsnNode) ain, it); - } else if (ain instanceof MethodInsnNode) { - line = printMethodInsnNode((MethodInsnNode) ain, it); - } else if (ain instanceof LdcInsnNode) { - line = printLdcInsnNode((LdcInsnNode) ain, it); - } else if (ain instanceof InsnNode) { - line = printInsnNode((InsnNode) ain, it); - } else if (ain instanceof JumpInsnNode) { - line = printJumpInsnNode((JumpInsnNode) ain, it); - } else if (ain instanceof LineNumberNode) { - line = printLineNumberNode((LineNumberNode) ain, it); - } else if (ain instanceof LabelNode) { - if (firstLabel - && BytecodeViewer.viewer.chckbxmntmAppendBrackets - .isSelected()) - info.add("}"); + /** + * Creates the print + * + * @return The print as an ArrayList + */ + public ArrayList createPrint() { + ArrayList info = new ArrayList(); + ListIterator it = mNode.instructions.iterator(); + boolean firstLabel = false; + while (it.hasNext()) { + AbstractInsnNode ain = (AbstractInsnNode) it.next(); + String line = ""; + if (ain instanceof VarInsnNode) { + line = printVarInsnNode((VarInsnNode) ain, it); + } else if (ain instanceof IntInsnNode) { + line = printIntInsnNode((IntInsnNode) ain, it); + } else if (ain instanceof FieldInsnNode) { + line = printFieldInsnNode((FieldInsnNode) ain, it); + } else if (ain instanceof MethodInsnNode) { + line = printMethodInsnNode((MethodInsnNode) ain, it); + } else if (ain instanceof LdcInsnNode) { + line = printLdcInsnNode((LdcInsnNode) ain, it); + } else if (ain instanceof InsnNode) { + line = printInsnNode((InsnNode) ain, it); + } else if (ain instanceof JumpInsnNode) { + line = printJumpInsnNode((JumpInsnNode) ain, it); + } else if (ain instanceof LineNumberNode) { + line = printLineNumberNode((LineNumberNode) ain, it); + } else if (ain instanceof LabelNode) { + if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS)) + info.add("}"); - line = printLabelnode((LabelNode) ain); + line = printLabelnode((LabelNode) ain); - if (BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()) { - if (!firstLabel) - firstLabel = true; - line += " {"; - } - } else if (ain instanceof TypeInsnNode) { - line = printTypeInsnNode((TypeInsnNode) ain); - } else if (ain instanceof FrameNode) { - line = ""; - } else if (ain instanceof IincInsnNode) { - line = printIincInsnNode((IincInsnNode) ain); - } else if (ain instanceof TableSwitchInsnNode) { - line = printTableSwitchInsnNode((TableSwitchInsnNode) ain); - } else if (ain instanceof LookupSwitchInsnNode) { - line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain); - } else if (ain instanceof InvokeDynamicInsnNode) { - line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain); - } else { - line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " - + ain.toString(); - } - if (!line.equals("")) { - if (match) - if (matchedInsns.contains(ain)) - line = " -> " + line; + if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS)) { + if (!firstLabel) firstLabel = true; + line += " {"; + } + } else if (ain instanceof TypeInsnNode) { + line = printTypeInsnNode((TypeInsnNode) ain); + } else if (ain instanceof FrameNode) { + line = ""; + } else if (ain instanceof IincInsnNode) { + line = printIincInsnNode((IincInsnNode) ain); + } else if (ain instanceof TableSwitchInsnNode) { + line = printTableSwitchInsnNode((TableSwitchInsnNode) ain); + } else if (ain instanceof LookupSwitchInsnNode) { + line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain); + } else if (ain instanceof InvokeDynamicInsnNode) { + line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain); + } else { + line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain.toString(); + } + if (!line.equals("")) { + if (match) if (matchedInsns.contains(ain)) line = " -> " + line; - info.add(line); - } - } - if (firstLabel - && BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()) - info.add("}"); - return info; - } + info.add(line); + } + } + if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS)) info.add("}"); + return info; + } - protected String printVarInsnNode(VarInsnNode vin, ListIterator it) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(vin.getOpcode())); - sb.append(vin.var); - if (BytecodeViewer.viewer.debugHelpers.isSelected()) { - if (vin.var == 0 && !Modifier.isStatic(mNode.access)) { - sb.append(" // reference to self"); - } else { - final int refIndex = vin.var - - (Modifier.isStatic(mNode.access) ? 0 : 1); - if (refIndex >= 0 && refIndex < args.length - 1) { - sb.append(" // reference to " + args[refIndex].name); - } - } - } + protected String printVarInsnNode(VarInsnNode vin, ListIterator it) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(vin.getOpcode())); + sb.append(vin.var); + if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS)) { + if (vin.var == 0 && !Modifier.isStatic(mNode.access)) { + sb.append(" // reference to self"); + } else { + final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1); + if (refIndex >= 0 && refIndex < args.length - 1) { + sb.append(" // reference to " + args[refIndex].name); + } + } + } - return sb.toString(); - } + return sb.toString(); + } - protected String printIntInsnNode(IntInsnNode iin, ListIterator it) { - return nameOpcode(iin.getOpcode()) + " " + iin.operand; - } + protected String printIntInsnNode(IntInsnNode iin, ListIterator it) { + return nameOpcode(iin.getOpcode()) + " " + iin.operand; + } - protected String printFieldInsnNode(FieldInsnNode fin, ListIterator it) { - String desc = Type.getType(fin.desc).getClassName(); - if (desc == null || desc.equals("null")) - desc = fin.desc; - return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name - + ":" + desc; - } + protected String printFieldInsnNode(FieldInsnNode fin, ListIterator it) { + String desc = Type.getType(fin.desc).getClassName(); + if (desc == null || desc.equals("null")) desc = fin.desc; + return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name + ":" + desc; + } - protected String printMethodInsnNode(MethodInsnNode min, ListIterator it) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " " - + min.name + "("); + protected String printMethodInsnNode(MethodInsnNode min, ListIterator it) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " " + min.name + "("); - String desc = min.desc; - try { - if(Type.getType(min.desc) != null) - desc = Type.getType(min.desc).getClassName(); + String desc = min.desc; + try { + if (Type.getType(min.desc) != null) desc = Type.getType(min.desc).getClassName(); - if (desc == null || desc.equals("null")) - desc = min.desc; - } catch(java.lang.ArrayIndexOutOfBoundsException e) { - - } - - sb.append(desc); + if (desc == null || desc.equals("null")) desc = min.desc; + } catch (java.lang.ArrayIndexOutOfBoundsException e) { - sb.append(");"); + } - return sb.toString(); - } + sb.append(desc); - protected String printLdcInsnNode(LdcInsnNode ldc, ListIterator it) { - if (ldc.cst instanceof String) - return nameOpcode(ldc.getOpcode()) + " \"" - + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" - + ldc.cst.getClass().getCanonicalName() + ")"; + sb.append(");"); - return nameOpcode(ldc.getOpcode()) + " " - + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" - + ldc.cst.getClass().getCanonicalName() + ")"; - } + return sb.toString(); + } - protected String printInsnNode(InsnNode in, ListIterator it) { - return nameOpcode(in.getOpcode()); - } + protected String printLdcInsnNode(LdcInsnNode ldc, ListIterator it) { + if (ldc.cst instanceof String) + return nameOpcode(ldc.getOpcode()) + " \"" + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" + ldc.cst.getClass().getCanonicalName() + ")"; - protected String printJumpInsnNode(JumpInsnNode jin, ListIterator it) { - String line = nameOpcode(jin.getOpcode()) + " L" - + resolveLabel(jin.label); - return line; - } + return nameOpcode(ldc.getOpcode()) + " " + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" + ldc.cst.getClass().getCanonicalName() + ")"; + } - protected String printLineNumberNode(LineNumberNode lin, ListIterator it) { - return ""; - } + protected String printInsnNode(InsnNode in, ListIterator it) { + return nameOpcode(in.getOpcode()); + } - protected String printLabelnode(LabelNode label) { - return "L" + resolveLabel(label); - } + protected String printJumpInsnNode(JumpInsnNode jin, ListIterator it) { + String line = nameOpcode(jin.getOpcode()) + " L" + resolveLabel(jin.label); + return line; + } - protected String printTypeInsnNode(TypeInsnNode tin) { - try { - String desc = tin.desc; - try { - if(Type.getType(tin.desc) != null) - desc = Type.getType(tin.desc).getClassName(); + protected String printLineNumberNode(LineNumberNode lin, ListIterator it) { + return ""; + } - if (desc == null || desc.equals("null")) - desc = tin.desc; - } catch(java.lang.ArrayIndexOutOfBoundsException e) { - - } - return nameOpcode(tin.getOpcode()) + " " + desc; - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - return "//error"; - } + protected String printLabelnode(LabelNode label) { + return "L" + resolveLabel(label); + } - protected String printIincInsnNode(IincInsnNode iin) { - return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr; - } + protected String printTypeInsnNode(TypeInsnNode tin) { + try { + String desc = tin.desc; + try { + if (Type.getType(tin.desc) != null) desc = Type.getType(tin.desc).getClassName(); - protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) { - String line = nameOpcode(tin.getOpcode()) + " \n"; - List labels = tin.labels; - int count = 0; - for (int i = tin.min; i < tin.max+1; i++) { - line += " val: " + i + " -> " + "L" - + resolveLabel((LabelNode) labels.get(count++)) + "\n"; - } - line += " default" + " -> L" + resolveLabel(tin.dflt) - + ""; - return line; - } + if (desc == null || desc.equals("null")) desc = tin.desc; + } catch (java.lang.ArrayIndexOutOfBoundsException e) { - protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) { - String line = nameOpcode(lin.getOpcode()) + ": \n"; - List keys = lin.keys; - List labels = lin.labels; + } + return nameOpcode(tin.getOpcode()) + " " + desc; + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + return "//error"; + } - for (int i = 0; i < keys.size(); i++) { - int key = (Integer) keys.get(i); - LabelNode label = (LabelNode) labels.get(i); - line += " val: " + key + " -> " + "L" - + resolveLabel(label) + "\n"; - } - line += " default" + " -> L" + resolveLabel(lin.dflt) - + ""; - return line; - } + protected String printIincInsnNode(IincInsnNode iin) { + return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr; + } - protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) { - StringBuilder sb = new StringBuilder(); - sb.append(nameOpcode(idin.getOpcode()) + " " + idin.bsm.getName() + "("); + protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) { + String line = nameOpcode(tin.getOpcode()) + " \n"; + List labels = tin.labels; + int count = 0; + for (int i = tin.min; i < tin.max + 1; i++) { + line += " val: " + i + " -> " + "L" + resolveLabel((LabelNode) labels.get(count++)) + "\n"; + } + line += " default" + " -> L" + resolveLabel(tin.dflt) + ""; + return line; + } - String desc = idin.desc; - String partedDesc = idin.desc.substring(2); - try { - if(Type.getType(partedDesc) != null) - desc = Type.getType(partedDesc).getClassName(); + protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) { + String line = nameOpcode(lin.getOpcode()) + ": \n"; + List keys = lin.keys; + List labels = lin.labels; - if (desc == null || desc.equals("null")) - desc = idin.desc; - } catch(java.lang.ArrayIndexOutOfBoundsException e) { + for (int i = 0; i < keys.size(); i++) { + int key = (Integer) keys.get(i); + LabelNode label = (LabelNode) labels.get(i); + line += " val: " + key + " -> " + "L" + resolveLabel(label) + "\n"; + } + line += " default" + " -> L" + resolveLabel(lin.dflt) + ""; + return line; + } - } + protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) { + StringBuilder sb = new StringBuilder(); + sb.append(nameOpcode(idin.getOpcode()) + " " + idin.bsm.getName() + "("); - sb.append(desc); + String desc = idin.desc; + String partedDesc = idin.desc.substring(2); + try { + if (Type.getType(partedDesc) != null) desc = Type.getType(partedDesc).getClassName(); - sb.append(");"); + if (desc == null || desc.equals("null")) desc = idin.desc; + } catch (java.lang.ArrayIndexOutOfBoundsException e) { - return sb.toString(); - } + } - protected String nameOpcode(int opcode) { - return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase(); - } + sb.append(desc); - protected int resolveLabel(LabelNode label) { - if (labels.containsKey(label)) { - return labels.get(label); - } else { - int newLabelIndex = labels.size() + 1; - labels.put(label, newLabelIndex); - return newLabelIndex; - } - } + sb.append(");"); - public static void saveTo(File file, InstructionPrinter printer) { - try { - BufferedWriter bw = new BufferedWriter(new FileWriter(file)); - for (String s : printer.createPrint()) { - bw.write(s); - bw.newLine(); - } - bw.close(); - } catch (IOException e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } + return sb.toString(); + } + + protected String nameOpcode(int opcode) { + return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase(); + } + + protected int resolveLabel(LabelNode label) { + if (labels.containsKey(label)) { + return labels.get(label); + } else { + int newLabelIndex = labels.size() + 1; + labels.put(label, newLabelIndex); + return newLabelIndex; + } + } + + public static void saveTo(File file, InstructionPrinter printer) { + try { + BufferedWriter bw = new BufferedWriter(new FileWriter(file)); + for (String s : printer.createPrint()) { + bw.write(s); + bw.newLine(); + } + bw.close(); + } catch (IOException e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionSearcher.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionSearcher.java index 3c562b60..e13bb714 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionSearcher.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionSearcher.java @@ -1,14 +1,14 @@ 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; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java index 94e72202..05463daa 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/bytecode/MethodNodeDecompiler.java @@ -1,9 +1,5 @@ package the.bytecode.club.bytecodeviewer.decompilers.bytecode; -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; @@ -11,9 +7,12 @@ 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 the.bytecode.club.bytecodeviewer.decompilers.bytecode.TypeAndName; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -112,7 +111,7 @@ public class MethodNodeDecompiler { sb.append(" {"); - if (BytecodeViewer.viewer.debugHelpers.isSelected()) { + if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS)) { if (m.name.equals("")) sb.append(" // "); else if (m.name.equals("")) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java index 92af25a9..a4cf4ac4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java @@ -2,9 +2,15 @@ package the.bytecode.club.bytecodeviewer.gui; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Resources; +import the.bytecode.club.bytecodeviewer.Settings; -import javax.swing.*; -import java.awt.*; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.Toolkit; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * @@ -28,11 +34,10 @@ import java.awt.*; * The about frame. * * @author Konloch - * */ - public class AboutWindow extends JFrame { - JTextArea textArea = new JTextArea(); + private static final long serialVersionUID = -8230501978224923296L; + private JTextArea textArea = new JTextArea(); public AboutWindow() { this.setIconImages(Resources.iconList); @@ -54,20 +59,21 @@ public class AboutWindow extends JFrame { public void setVisible(boolean b) { super.setVisible(b); textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue())); - textArea.setText("Bytecode Viewer " + BytecodeViewer.version + " is an open source program developed and maintained by Konloch (konloch@gmail.com) 100% free and open sourced licensed under GPL v3 CopyLeft\r\n\r\n" + + textArea.setText("Bytecode Viewer " + BytecodeViewer.version + " is an open source program developed and maintained by Konloch (konloch@gmail.com) and samczsun 100% free and open sourced licensed under GPL v3 CopyLeft" + BytecodeViewer.nl + + BytecodeViewer.nl + "Settings:" + BytecodeViewer.nl + " Preview Copy: " + BytecodeViewer.previewCopy + BytecodeViewer.nl + - " Java: " + BytecodeViewer.java + BytecodeViewer.nl + - " Javac: " + BytecodeViewer.javac + BytecodeViewer.nl + + " Java: " + Settings.JAVA_LOCATION.get() + BytecodeViewer.nl + + " Javac: " + Settings.JAVAC_LOCATION.get() + BytecodeViewer.nl + " BCV Dir: " + BytecodeViewer.getBCVDirectory() + BytecodeViewer.nl + - " Python 2.7 (or PyPy): " + BytecodeViewer.python + BytecodeViewer.nl + - " Python 3.X (or PyPy): " + BytecodeViewer.python3 + BytecodeViewer.nl + - " RT.jar:" + BytecodeViewer.rt + BytecodeViewer.nl + - " Optional Lib: " + BytecodeViewer.library + BytecodeViewer.nl + + " Python 2.7 (or PyPy): " + Settings.PYTHON2_LOCATION.get() + BytecodeViewer.nl + + " Python 3.X (or PyPy): " + Settings.PYTHON3_LOCATION.get() + BytecodeViewer.nl + + " RT.jar:" + Settings.RT_LOCATION.get() + BytecodeViewer.nl + + " Optional Lib: " + Settings.PATH.get() + BytecodeViewer.nl + " BCV Krakatau: v" + BytecodeViewer.krakatauVersion + BytecodeViewer.nl + - " Krakatau Dir: " + BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.nl + + " Krakatau Dir: " + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.nl + " BCV Enjarify: v" + BytecodeViewer.enjarifyVersion + BytecodeViewer.nl + - " Enjarify Dir: " + BytecodeViewer.enjarifyWorkingDirectory + BytecodeViewer.nl + BytecodeViewer.nl + + " Enjarify Dir: " + BytecodeViewer.enjarifyDirectory.getAbsolutePath()+ BytecodeViewer.nl + BytecodeViewer.nl + "Command Line Input:" + BytecodeViewer.nl + " -help Displays the help menu" + BytecodeViewer.nl + " -list Displays the available decompilers" + BytecodeViewer.nl + @@ -82,11 +88,24 @@ public class AboutWindow extends JFrame { " CTRL + W: Closes the currently opened tab" + BytecodeViewer.nl + " CTRL + T: Compile" + BytecodeViewer.nl + " CTRL + S: Save classes as zip" + BytecodeViewer.nl + - " CTRL + R: Run (EZ-Inject) - dynamically load the classes and invoke a main class" + - "\r\n\r\nCode from various projects has been used, including but not limited to:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSynaxPane by Robert Futrell\r\n Commons IO by Apache\r\n ASM by OW2\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n CFIDE by Bibl\r\n Smali by JesusFreke\r\n Dex2Jar by pxb1..?\r\n Krakatau by Storyyeller\r\n JD-GUI + JD-Core by The Java-Decompiler Team\r\n Enjarify by Storyyeller\r\n\r\nIf you're interested in Java Reverse Engineering, join The Bytecode Club - https://the.bytecode.club"); - + " CTRL + R: Run (EZ-Inject) - dynamically load the classes and invoke a main class" + BytecodeViewer.nl + + BytecodeViewer.nl + + "Code from various projects has been used, including but not limited to:" + BytecodeViewer.nl + + " J-RET by WaterWolf" + BytecodeViewer.nl + + " JHexPane by Sam Koivu" + BytecodeViewer.nl + + " RSynaxPane by Robert Futrell" + BytecodeViewer.nl + + " Commons IO by Apache" + BytecodeViewer.nl + + " ASM by OW2" + BytecodeViewer.nl + + " FernFlower by Stiver" + BytecodeViewer.nl + + " Procyon by Mstrobel" + BytecodeViewer.nl + + " CFR by Lee Benfield" + BytecodeViewer.nl + + " CFIDE by Bibl" + BytecodeViewer.nl + + " Smali by JesusFreke" + BytecodeViewer.nl + + " Dex2Jar by pxb1..?" + BytecodeViewer.nl + + " Krakatau by Storyyeller" + BytecodeViewer.nl + + " JD-GUI + JD-Core by The Java-Decompiler Team" + BytecodeViewer.nl + + " Enjarify by Storyyeller" + BytecodeViewer.nl + + BytecodeViewer.nl + + "If you're interested in Java Reverse Engineering, join The Bytecode Club - https://the.bytecode.club"); } - - private static final long serialVersionUID = -8230501978224923296L; - } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/AllatoriStringDecrypterOptions.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/AllatoriStringDecrypterOptions.java index 60842357..489022e6 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/AllatoriStringDecrypterOptions.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/AllatoriStringDecrypterOptions.java @@ -1,17 +1,16 @@ package the.bytecode.club.bytecodeviewer.gui; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import the.bytecode.club.bytecodeviewer.Resources; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTextField; - -import the.bytecode.club.bytecodeviewer.Resources; -import the.bytecode.club.bytecodeviewer.plugin.PluginManager; -import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java index 7aa9d5f6..79c629b0 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java @@ -1,10 +1,29 @@ package the.bytecode.club.bytecodeviewer.gui; +import com.jhe.hexed.JHexEditor; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rtextarea.RTextScrollPane; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Resources; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; + +import javax.swing.ButtonGroup; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSplitPane; +import javax.swing.JTextField; +import javax.swing.text.DefaultHighlighter; +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; -import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; @@ -14,58 +33,26 @@ import java.awt.event.HierarchyListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; - -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JSplitPane; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; -import javax.swing.text.AbstractDocument; -import javax.swing.text.BoxView; -import javax.swing.text.ComponentView; -import javax.swing.text.DefaultHighlighter; -import javax.swing.text.Element; -import javax.swing.text.Highlighter; -import javax.swing.text.IconView; -import javax.swing.text.JTextComponent; -import javax.swing.text.LabelView; -import javax.swing.text.StyleConstants; -import javax.swing.text.StyledEditorKit; -import javax.swing.text.View; -import javax.swing.text.ViewFactory; -import javax.swing.text.html.ParagraphView; - -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; -import org.fife.ui.rtextarea.RTextScrollPane; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Type; -import org.objectweb.asm.tree.ClassNode; - -import com.jhe.hexed.JHexEditor; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.Resources; -import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; +import java.util.Arrays; +import java.util.List; +import java.util.Map; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** @@ -73,1561 +60,394 @@ import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; * * @author Konloch * @author WaterWolf - * */ public class ClassViewer extends Viewer { - - public void setPanes() { - if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel())) - pane1 = 0; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel())) - pane1 = 1; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel())) - pane1 = 2; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel())) - pane1 = 3; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel())) - pane1 = 4; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel())) - pane1 = 5; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel())) - pane1 = 6; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel())) - pane1 = 7; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel())) - pane1 = 8; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1JDGUI.getModel())) - pane1 = 9; - - if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel())) - pane2 = 0; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel())) - pane2 = 1; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel())) - pane2 = 2; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel())) - pane2 = 3; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel())) - pane2 = 4; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel())) - pane2 = 5; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel())) - pane2 = 6; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel())) - pane2 = 7; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel())) - pane2 = 8; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2JDGUI.getModel())) - pane2 = 9; - - if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel())) - pane3 = 0; - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel())) - pane3 = 1; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3CFR.getModel())) - pane3 = 2; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3Fern.getModel())) - pane3 = 3; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel())) - pane3 = 4; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel())) - pane3 = 5; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3Smali.getModel())) - pane3 = 6; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel())) - pane3 = 7; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel())) - pane3 = 8; - else if (BytecodeViewer.viewer.panelGroup3 .isSelected(BytecodeViewer.viewer.panel3JDGUI.getModel())) - pane3 = 9; - } - - public boolean isPanel1Editable() { - setPanes(); - - if(pane1 == 1 && BytecodeViewer.viewer.panel1Proc_E.isSelected()) - return true; - if(pane1 == 2 && BytecodeViewer.viewer.panel1CFR_E.isSelected()) - return true; - if(pane1 == 3 && BytecodeViewer.viewer.panel1Fern_E.isSelected()) - return true; - if(pane1 == 6 && BytecodeViewer.viewer.panel1Smali_E.isSelected()) - return true; - if(pane1 == 9 && BytecodeViewer.viewer.panel1JDGUI_E.isSelected()) - return true; - if((pane1 == 7 || pane1 == 8) && BytecodeViewer.viewer.panel1Krakatau_E.isSelected()) - return true; - - - return false; - } - - public boolean isPanel2Editable() { - setPanes(); - - if(pane2 == 1 && BytecodeViewer.viewer.panel2Proc_E.isSelected()) - return true; - if(pane2 == 2 && BytecodeViewer.viewer.panel2CFR_E.isSelected()) - return true; - if(pane2 == 3 && BytecodeViewer.viewer.panel2Fern_E.isSelected()) - return true; - if(pane2 == 6 && BytecodeViewer.viewer.panel2Smali_E.isSelected()) - return true; - if(pane2 == 9 && BytecodeViewer.viewer.panel2JDGUI_E.isSelected()) - return true; - if((pane2 == 7 || pane2 == 8) && BytecodeViewer.viewer.panel2Krakatau_E.isSelected()) - return true; - - - return false; - } - - public boolean isPanel3Editable() { - setPanes(); - - if(pane3 == 1 && BytecodeViewer.viewer.panel3Proc_E.isSelected()) - return true; - if(pane3 == 2 && BytecodeViewer.viewer.panel3CFR_E.isSelected()) - return true; - if(pane3 == 3 && BytecodeViewer.viewer.panel3Fern_E.isSelected()) - return true; - if(pane3 == 6 && BytecodeViewer.viewer.panel3Smali_E.isSelected()) - return true; - if(pane3 == 9 && BytecodeViewer.viewer.panel3JDGUI_E.isSelected()) - return true; - if((pane3 == 7 || pane3 == 8) && BytecodeViewer.viewer.panel3Krakatau_E.isSelected()) - return true; - - - return false; - } - - /** - * Whoever wrote this function, THANK YOU! - * - * @param splitter - * @param proportion - * @return - */ - public static JSplitPane setDividerLocation(final JSplitPane splitter, - final double proportion) { - if (splitter.isShowing()) { - if (splitter.getWidth() > 0 && splitter.getHeight() > 0) { - splitter.setDividerLocation(proportion); - } else { - splitter.addComponentListener(new ComponentAdapter() { - @Override - public void componentResized(ComponentEvent ce) { - splitter.removeComponentListener(this); - setDividerLocation(splitter, proportion); - } - }); - } - } else { - splitter.addHierarchyListener(new HierarchyListener() { - @Override - public void hierarchyChanged(HierarchyEvent e) { - if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 - && splitter.isShowing()) { - splitter.removeHierarchyListener(this); - setDividerLocation(splitter, proportion); - } - } - }); - } - return splitter; - } - - private static final long serialVersionUID = -8650495368920680024L; - ArrayList lnData = new ArrayList(); - String name; - JSplitPane sp; - JSplitPane sp2; - public JPanel panel1Search = new JPanel(new BorderLayout()); - public JPanel panel2Search = new JPanel(new BorderLayout()); - public JPanel panel3Search = new JPanel(new BorderLayout()); - public JCheckBox check1 = new JCheckBox("Exact"); - public JCheckBox check2 = new JCheckBox("Exact"); - public JCheckBox check3 = new JCheckBox("Exact"); - public JPanel panel1 = new JPanel(new BorderLayout()); - public JPanel panel2 = new JPanel(new BorderLayout()); - public JPanel panel3 = new JPanel(new BorderLayout()); - int pane1 = -1; - int pane2 = -1; - int pane3 = -1; - public RSyntaxTextArea smali1 = null; - public RSyntaxTextArea smali2 = null; - public RSyntaxTextArea smali3 = null; - public RSyntaxTextArea krakatau1 = null; - public RSyntaxTextArea krakatau2 = null; - public RSyntaxTextArea krakatau3 = null; - public RSyntaxTextArea java1 = null; - public RSyntaxTextArea java2 = null; - public RSyntaxTextArea java3 = null; - - /** - * This was really interesting to write. - * - * @author Konloch - * - */ - public void search(int pane, String search, boolean next) { - try { - Component[] com = null; - if (pane == 0) // bytecode - com = panel1.getComponents(); - else if (pane == 1) - com = panel2.getComponents(); - else if (pane == 2) - com = panel3.getComponents(); - - if (com == null) // someone fucked up, lets prevent a nullpointer. - return; - - for (Component c : com) { - if (c instanceof RTextScrollPane) { - RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane) c) - .getViewport().getComponent(0); - - if (search.isEmpty()) { - highlight(pane, area, ""); - return; - } - - int startLine = area.getDocument().getDefaultRootElement() - .getElementIndex(area.getCaretPosition()) + 1; - int currentLine = 1; - boolean canSearch = false; - String[] test = null; - if (area.getText().split("\n").length >= 2) - test = area.getText().split("\n"); - else - test = area.getText().split("\r"); - int lastGoodLine = -1; - int firstPos = -1; - boolean found = false; - - if (next) { - for (String s : test) { - if (pane == 0 && !check1.isSelected() || pane == 1 - && !check2.isSelected()) { - s = s.toLowerCase(); - search = search.toLowerCase(); - } - - if (currentLine == startLine) { - canSearch = true; - } else if (s.contains(search)) { - if (canSearch) { - area.setCaretPosition(area.getDocument() - .getDefaultRootElement() - .getElement(currentLine - 1) - .getStartOffset()); - canSearch = false; - found = true; - } - - if (firstPos == -1) - firstPos = currentLine; - } - - currentLine++; - } - - if (!found && firstPos != -1) { - area.setCaretPosition(area.getDocument() - .getDefaultRootElement() - .getElement(firstPos - 1).getStartOffset()); - } - } else { - canSearch = true; - for (String s : test) { - if (pane == 0 && !check1.isSelected() || pane == 1 - && !check2.isSelected() || pane == 2 - && !check3.isSelected()) { - s = s.toLowerCase(); - search = search.toLowerCase(); - } - - if (s.contains(search)) { - if (lastGoodLine != -1 && canSearch) - area.setCaretPosition(area.getDocument() - .getDefaultRootElement() - .getElement(lastGoodLine - 1) - .getStartOffset()); - - lastGoodLine = currentLine; - - if (currentLine >= startLine) - canSearch = false; - } - currentLine++; - } - - if (lastGoodLine != -1 - && area.getDocument() - .getDefaultRootElement() - .getElementIndex( - area.getCaretPosition()) + 1 == startLine) { - area.setCaretPosition(area.getDocument() - .getDefaultRootElement() - .getElement(lastGoodLine - 1) - .getStartOffset()); - } - } - highlight(pane, area, search); - } - } - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - - private DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter( - new Color(255, 62, 150)); - - public void highlight(int pane, JTextComponent textComp, String pattern) { - if (pattern.isEmpty()) { - textComp.getHighlighter().removeAllHighlights(); - return; - } - - try { - Highlighter hilite = textComp.getHighlighter(); - hilite.removeAllHighlights(); - javax.swing.text.Document doc = textComp.getDocument(); - String text = doc.getText(0, doc.getLength()); - int pos = 0; - - if ((pane == 0 && !check1.isSelected()) || pane == 1 - && !check2.isSelected() || pane == 2 - && !check3.isSelected()) { - pattern = pattern.toLowerCase(); - text = text.toLowerCase(); - } - - // Search for pattern - while ((pos = text.indexOf(pattern, pos)) >= 0) { - // Create highlighter using private painter and apply around - // pattern - hilite.addHighlight(pos, pos + pattern.length(), painter); - pos += pattern.length(); - } - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - - final JTextField field1 = new JTextField(); - final JTextField field2 = new JTextField(); - final JTextField field3 = new JTextField(); - public ClassViewer(final String name, final ClassNode cn) { - JButton byteSearchNext = new JButton(); - JButton byteSearchPrev = new JButton(); - JPanel byteButtonPane = new JPanel(new BorderLayout()); - byteButtonPane.add(byteSearchNext, BorderLayout.WEST); - byteButtonPane.add(byteSearchPrev, BorderLayout.EAST); - byteSearchNext.setIcon(Resources.nextIcon); - byteSearchPrev.setIcon(Resources.prevIcon); - panel1Search.add(byteButtonPane, BorderLayout.WEST); - panel1Search.add(field1, BorderLayout.CENTER); - panel1Search.add(check1, BorderLayout.EAST); - byteSearchNext.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(0, field1.getText(), true); - } - }); - byteSearchPrev.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(0, field1.getText(), false); - } - }); - field1.addKeyListener(new KeyListener() { - @Override - public void keyReleased(KeyEvent arg0) { - if (arg0.getKeyCode() == KeyEvent.VK_ENTER) - search(0, field1.getText(), true); - } - - @Override - public void keyPressed(KeyEvent arg0) { - } - - @Override - public void keyTyped(KeyEvent arg0) { - } - }); - - JButton searchNext2 = new JButton(); - JButton searchPrev2 = new JButton(); - JPanel buttonPane2 = new JPanel(new BorderLayout()); - buttonPane2.add(searchNext2, BorderLayout.WEST); - buttonPane2.add(searchPrev2, BorderLayout.EAST); - searchNext2.setIcon(Resources.nextIcon); - searchPrev2.setIcon(Resources.prevIcon); - panel2Search.add(buttonPane2, BorderLayout.WEST); - panel2Search.add(field2, BorderLayout.CENTER); - panel2Search.add(check2, BorderLayout.EAST); - searchNext2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(1, field2.getText(), true); - } - }); - searchPrev2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(1, field2.getText(), false); - } - }); - field2.addKeyListener(new KeyListener() { - @Override - public void keyReleased(KeyEvent arg0) { - if (arg0.getKeyCode() == KeyEvent.VK_ENTER) - search(1, field2.getText(), true); - } - - @Override - public void keyPressed(KeyEvent arg0) { - } - - @Override - public void keyTyped(KeyEvent arg0) { - } - }); - - JButton searchNext3 = new JButton(); - JButton searchPrev3 = new JButton(); - JPanel buttonPane3 = new JPanel(new BorderLayout()); - buttonPane3.add(searchNext3, BorderLayout.WEST); - buttonPane3.add(searchPrev3, BorderLayout.EAST); - searchNext3.setIcon(Resources.nextIcon); - searchPrev3.setIcon(Resources.prevIcon); - panel3Search.add(buttonPane3, BorderLayout.WEST); - panel3Search.add(field3, BorderLayout.CENTER); - panel3Search.add(check3, BorderLayout.EAST); - searchNext3.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(2, field3.getText(), true); - } - }); - searchPrev3.addActionListener(new ActionListener() { - @Override - public void actionPerformed(final ActionEvent arg0) { - search(2, field3.getText(), false); - } - }); - field3.addKeyListener(new KeyListener() { - @Override - public void keyReleased(KeyEvent arg0) { - if (arg0.getKeyCode() == KeyEvent.VK_ENTER) - search(2, field3.getText(), true); - } - - @Override - public void keyPressed(KeyEvent arg0) { - } - - @Override - public void keyTyped(KeyEvent arg0) { - } - }); - - this.name = name; - this.cn = cn; - this.setName(name); - this.setLayout(new BorderLayout()); - - this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2); - final ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - JHexEditor hex = new JHexEditor(cw.toByteArray()); - this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, panel3); - this.add(sp2, BorderLayout.CENTER); - - hex.setMaximumSize(new Dimension(0, Integer.MAX_VALUE)); - hex.setSize(0, Integer.MAX_VALUE); - - BytecodeViewer.viewer.setIcon(true); - startPaneUpdater(null); - this.addComponentListener(new ComponentAdapter() { - public void componentResized(ComponentEvent e) { - resetDivider(); - } - }); - } - - public void resetDivider() { - sp.setResizeWeight(0.5); - if (pane2 != 0 && pane1 != 0) - sp = setDividerLocation(sp, 0.5); - else if (pane1 != 0) - sp = setDividerLocation(sp, 1); - else if(pane2 != 0) { - sp.setResizeWeight(1); - sp = setDividerLocation(sp, 0); - } else - sp = setDividerLocation(sp, 0); - if (pane3 != 0) { - sp2.setResizeWeight(0.7); - sp2 = setDividerLocation(sp2, 0.7); - if ((pane2 == 0 && pane1 != 0) || (pane1 == 0 && pane2 != 0)) - sp2 = setDividerLocation(sp2, 0.5); - else if (pane1 == 0 && pane2 == 0) - sp2 = setDividerLocation(sp2, 0); - } else { - sp.setResizeWeight(1); - sp2.setResizeWeight(0); - sp2 = setDividerLocation(sp2, 1); - } - } - - PaneUpdaterThread t1; - PaneUpdaterThread t2; - PaneUpdaterThread t3; - - public void startPaneUpdater(final JButton button) { - this.cn = BytecodeViewer.getClassNode(cn.name); //update the classnode - setPanes(); - - panel1.removeAll(); - panel2.removeAll(); - panel3.removeAll(); - smali1 = null; - smali2 = null; - smali3 = null; - java1 = null; - java2 = null; - java3 = null; - - if(this.cn == null) { - panel1.add(new JLabel("This file has been removed from the reload.")); - panel2.add(new JLabel("This file has been removed from the reload.")); - panel3.add(new JLabel("This file has been removed from the reload.")); - return; - } - - if (pane1 != 0 && pane1 != 5) - panel1.add(panel1Search, BorderLayout.NORTH); - if (pane2 != 0 && pane2 != 5) - panel2.add(panel2Search, BorderLayout.NORTH); - if (pane3 != 0 && pane3 != 5) - panel3.add(panel3Search, BorderLayout.NORTH); - - final ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch(Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { } - } - final byte[] b = cw.toByteArray(); - Thread t1 = new PaneUpdaterThread() { - @Override - public void doShit() { - try { - if (pane1 == 1) { // procyon - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.procyon.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Procyon Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - java1 = panelArea; - } - - if (pane1 == 2) {// cfr - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.cfr.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("CFR Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - java1 = panelArea; - } - - if (pane1 == 3) {// fern - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.fernflower.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("FernFlower Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - java1 = panelArea; - } - - if (pane1 == 4) {// bytecode - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.bytecode.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(false); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Bytecode Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - } - - if (pane1 == 5) {// hex - final ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - final JHexEditor hex = new JHexEditor(cw.toByteArray()); - hex.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(hex); - } - }); - } - - if (pane1 == 6) {//smali bytecode - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.smali.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - smali1 = panelArea; - smali1.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Smali Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - } - - if (pane1 == 7) {// krakatau - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatau.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - java1 = panelArea; - } - - - - if (pane1 == 8) {// kraktau bytecode - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatauDA.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - krakatau1 = panelArea; - krakatau1.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Disassembler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - } - - if (pane1 == 9) {// JD-GUI - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.jdgui.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel1Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field1.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("JD-GUI Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel1.add(scrollPane); - } - }); - - java1 = panelArea; - } - } catch(java.lang.IndexOutOfBoundsException | java.lang.NullPointerException e) { - //ignore - } catch(Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } finally { - resetDivider(); - BytecodeViewer.viewer.setIcon(false); - if(button != null) - button.setEnabled(true); - } - } - }; - - - Thread t2 = new PaneUpdaterThread() { - @Override - public void doShit() { - try { - if (pane2 == 1) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.procyon.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Procyon Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - java2 = panelArea; - } - - if (pane2 == 2) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.cfr.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("CFR Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - java2 = panelArea; - } - - if (pane2 == 3) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.fernflower.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("FernFlower Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - java2 = panelArea; - } - - if (pane2 == 4) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.bytecode.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(false); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Bytecode Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - } - - if (pane2 == 5) { - final ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - final JHexEditor hex = new JHexEditor(cw.toByteArray()); - hex.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(hex); - } - }); - } - - if (pane2 == 6) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.smali.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - smali2 = panelArea; - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Smali Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - } - - if (pane2 == 7) {// krakatau - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatau.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - java2 = panelArea; - } - - if (pane2 == 8) {// kraktau bytecode - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatauDA.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - krakatau2 = panelArea; - krakatau2.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Disassembler")); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - } - - if (pane2 == 9) {// JD-GUI - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.jdgui.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel2Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field2.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("JD-GUI Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel2.add(scrollPane); - } - }); - - java2 = panelArea; - } - } catch(java.lang.IndexOutOfBoundsException | java.lang.NullPointerException e) { - //ignore - } catch(Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } finally { - resetDivider(); - BytecodeViewer.viewer.setIcon(false); - if(button != null) - button.setEnabled(true); - } - } - }; - - - - Thread t3 = new PaneUpdaterThread() { - @Override - public void doShit() { - try { - if (pane3 == 1) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.procyon.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Procyon Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - - java3 = panelArea; - } - - if (pane3 == 2) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.cfr.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("CFR Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - - java3 = panelArea; - } - - if (pane3 == 3) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.fernflower.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("FernFlower Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - - java3 = panelArea; - } - - if (pane3 == 4) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.bytecode.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(false); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Bytecode Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - } - - if (pane3 == 5) { - final ClassWriter cw = new ClassWriter(0); - cn.accept(cw); - final JHexEditor hex = new JHexEditor(cw.toByteArray()); - hex.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(hex); - } - }); - - } - - if (pane3 == 6) { - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); - panelArea.setText(Decompiler.smali.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - smali3 = panelArea; - smali3.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Smali Decompiler - Editable: " + panelArea.isEditable())); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - - } - - if (pane3 == 7) {// krakatau - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatau.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Decompiler - Editable: " + panelArea.isEditable())); - java3 = panelArea; - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - } - - if (pane3 == 8) {// kraktau bytecode - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.krakatauDA.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - krakatau3 = panelArea; - krakatau3.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("Krakatau Disassembler")); - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - - } - - if (pane3 == 9) {// JD-GUI - RSyntaxTextArea panelArea = new RSyntaxTextArea(); - panelArea - .setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - panelArea.setCodeFoldingEnabled(true); - panelArea.setAntiAliasingEnabled(true); - final RTextScrollPane scrollPane = new RTextScrollPane( - panelArea); - panelArea.setText(Decompiler.jdgui.decompileClassNode(cn,b)); - panelArea.setCaretPosition(0); - panelArea.setEditable(isPanel3Editable()); - panelArea.addKeyListener(new KeyListener() { - public void keyPressed(KeyEvent e) { - if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { - field3.requestFocus(); - } - - BytecodeViewer.checkHotKey(e); - } - @Override public void keyReleased(KeyEvent arg0) { } - @Override public void keyTyped(KeyEvent arg0) { } - }); - scrollPane.setColumnHeaderView(new JLabel("JD-GUI Decompiler - Editable: " + panelArea.isEditable())); - java3 = panelArea; - panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); - - SwingUtilities.invokeLater(new Runnable() { - public void run() { - panel3.add(scrollPane); - } - }); - } - } catch(java.lang.IndexOutOfBoundsException | java.lang.NullPointerException e) { - //ignore - } catch(Exception e) { - //new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } finally { - resetDivider(); - BytecodeViewer.viewer.setIcon(false); - if(button != null) - button.setEnabled(true); - } - } - }; - - if(pane1 > 0) - t1.start(); - if(pane2 > 0) - t2.start(); - if(pane3 > 0) - t3.start(); - } - - public Object[] getSmali() { - if(smali1 != null) - return new Object[]{cn, smali1.getText()}; - if(smali2 != null) - return new Object[]{cn, smali2.getText()}; - if(smali3 != null) - return new Object[]{cn, smali3.getText()}; - - return null; - } - - public Object[] getKrakatau() { - if(krakatau1 != null) - return new Object[]{cn, krakatau1.getText()}; - if(krakatau2 != null) - return new Object[]{cn, krakatau2.getText()}; - if(krakatau3 != null) - return new Object[]{cn, krakatau3.getText()}; - - return null; - } - - public Object[] getJava() { - if(java1 != null) - return new Object[]{cn, java1.getText()}; - if(java2 != null) - return new Object[]{cn, java2.getText()}; - if(java3 != null) - return new Object[]{cn, java3.getText()}; - - return null; - } - - public static class MethodData { - public String name, desc; - public int srcLN, bytecodeLN; - - @Override - public boolean equals(final Object o) { - return equals((MethodData) o); - } - - public boolean equals(final MethodData md) { - return this.name.equals(md.name) && this.desc.equals(md.desc); - } - - public String constructPattern() { - final StringBuffer pattern = new StringBuffer(); - pattern.append(name + " *\\("); - final org.objectweb.asm.Type[] types = org.objectweb.asm.Type - .getArgumentTypes(desc); - pattern.append("(.*)"); - for (int i = 0; i < types.length; i++) { - final Type type = types[i]; - final String clazzName = type.getClassName(); - pattern.append(clazzName.substring(clazzName.lastIndexOf(".") + 1) - + "(.*)"); - } - pattern.append("\\) *\\{"); - return pattern.toString(); - } - } - - class WrapEditorKit extends StyledEditorKit { - private static final long serialVersionUID = 1719109651258205346L; - ViewFactory defaultFactory = new WrapColumnFactory(); - - @Override - public ViewFactory getViewFactory() { - return defaultFactory; - } - } - - class WrapColumnFactory implements ViewFactory { - public View create(final Element elem) { - final String kind = elem.getName(); - if (kind != null) { - if (kind.equals(AbstractDocument.ParagraphElementName)) - return new NoWrapParagraphView(elem); - else if (kind.equals(AbstractDocument.SectionElementName)) - return new BoxView(elem, View.Y_AXIS); - else if (kind.equals(StyleConstants.ComponentElementName)) - return new ComponentView(elem); - else if (kind.equals(StyleConstants.IconElementName)) - return new IconView(elem); - } - - return new LabelView(elem); - } - } - - public class NoWrapParagraphView extends ParagraphView { - public NoWrapParagraphView(final Element elem) { - super(elem); - } - - @Override - public void layout(final int width, final int height) { - super.layout(Short.MAX_VALUE, height); - } - - @Override - public float getMinimumSpan(final int axis) { - return super.getPreferredSpan(axis); - } - } - + private static final long serialVersionUID = -8650495368920680024L; + private List decompileThreads = new ArrayList<>(); + + public void setPanes() { + for (int i = 0; i < BytecodeViewer.viewer.allPanes.size(); i++) { + ButtonGroup group = BytecodeViewer.viewer.allPanes.get(i); + for (Map.Entry entry : BytecodeViewer.viewer.allDecompilers.get(group).entrySet()) { + if (group.isSelected(entry.getKey().getModel())) { + decompilers.set(i, entry.getValue()); + } + } + } + } + + public boolean isPaneEditable(int pane) { + setPanes(); + ButtonGroup buttonGroup = BytecodeViewer.viewer.allPanes.get(pane); + Decompiler selected = decompilers.get(pane); + if (buttonGroup != null && BytecodeViewer.viewer.editButtons.get(buttonGroup) != null && BytecodeViewer.viewer.editButtons.get(buttonGroup).get(selected)!= null && BytecodeViewer.viewer.editButtons.get(buttonGroup).get(selected).isSelected()) { + return true; + } + return false; + } + + public void requestFocus(int pane) { + this.fields.get(pane).requestFocus(); + } + + public void updatePane(int pane, RSyntaxTextArea text, Decompiler decompiler) { + if (decompiler == Decompiler.KRAKATAU_DA) { + krakataus.set(pane, text); + } else if (decompiler == Decompiler.SMALI) { + smalis.set(pane, text); + } else { + javas.set(pane, text); + } + } + + /** + * Whoever wrote this function, THANK YOU! + * + * @param splitter + * @param proportion + * @return + */ + public static JSplitPane setDividerLocation(final JSplitPane splitter, + final double proportion) { + if (splitter.isShowing()) { + if (splitter.getWidth() > 0 && splitter.getHeight() > 0) { + splitter.setDividerLocation(proportion); + } else { + splitter.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent ce) { + splitter.removeComponentListener(this); + setDividerLocation(splitter, proportion); + } + }); + } + } else { + splitter.addHierarchyListener(new HierarchyListener() { + @Override + public void hierarchyChanged(HierarchyEvent e) { + if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 + && splitter.isShowing()) { + splitter.removeHierarchyListener(this); + setDividerLocation(splitter, proportion); + } + } + }); + } + return splitter; + } + + String name; + JSplitPane sp; + JSplitPane sp2; + public List decompilers = Arrays.asList(null, null, null); + public List panels = Arrays.asList(new JPanel(new BorderLayout()), new JPanel(new BorderLayout()), new JPanel(new BorderLayout())); + public List searches = Arrays.asList(new JPanel(new BorderLayout()), new JPanel(new BorderLayout()), new JPanel(new BorderLayout())); + public List exacts = Arrays.asList(new JCheckBox("Exact"), new JCheckBox("Exact"), new JCheckBox("Exact")); + public List fields = Arrays.asList(new JTextField(), new JTextField(), new JTextField()); + public List javas = Arrays.asList(null, null, null); + public List smalis = Arrays.asList(null, null, null); + public List krakataus = Arrays.asList(null, null, null); + + /** + * This was really interesting to write. + * + * @author Konloch + */ + public void search(int pane, String search, boolean next) { + try { + Component[] com = panels.get(pane).getComponents(); + for (Component c : com) { + if (c instanceof RTextScrollPane) { + RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane) c) + .getViewport().getComponent(0); + + if (search.isEmpty()) { + highlight(pane, area, ""); + return; + } + + int startLine = area.getDocument().getDefaultRootElement() + .getElementIndex(area.getCaretPosition()) + 1; + int currentLine = 1; + boolean canSearch = false; + String[] test = null; + if (area.getText().split("\n").length >= 2) + test = area.getText().split("\n"); + else + test = area.getText().split("\r"); + int lastGoodLine = -1; + int firstPos = -1; + boolean found = false; + + if (next) { + for (String s : test) { + if (pane == 0 && !exacts.get(0).isSelected() || pane == 1 + && !exacts.get(1).isSelected()) { + s = s.toLowerCase(); + search = search.toLowerCase(); + } + + if (currentLine == startLine) { + canSearch = true; + } else if (s.contains(search)) { + if (canSearch) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement() + .getElement(currentLine - 1) + .getStartOffset()); + canSearch = false; + found = true; + } + + if (firstPos == -1) + firstPos = currentLine; + } + + currentLine++; + } + + if (!found && firstPos != -1) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement() + .getElement(firstPos - 1).getStartOffset()); + } + } else { + canSearch = true; + for (String s : test) { + if (pane == 0 && !exacts.get(0).isSelected() || pane == 1 + && !exacts.get(1).isSelected() || pane == 2 + && !exacts.get(2).isSelected()) { + s = s.toLowerCase(); + search = search.toLowerCase(); + } + + if (s.contains(search)) { + if (lastGoodLine != -1 && canSearch) + area.setCaretPosition(area.getDocument() + .getDefaultRootElement() + .getElement(lastGoodLine - 1) + .getStartOffset()); + + lastGoodLine = currentLine; + + if (currentLine >= startLine) + canSearch = false; + } + currentLine++; + } + + if (lastGoodLine != -1 + && area.getDocument() + .getDefaultRootElement() + .getElementIndex( + area.getCaretPosition()) + 1 == startLine) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement() + .getElement(lastGoodLine - 1) + .getStartOffset()); + } + } + highlight(pane, area, search); + } + } + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + + private DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter( + new Color(255, 62, 150)); + + public void highlight(int pane, JTextComponent textComp, String pattern) { + if (pattern.isEmpty()) { + textComp.getHighlighter().removeAllHighlights(); + return; + } + + try { + Highlighter hilite = textComp.getHighlighter(); + hilite.removeAllHighlights(); + javax.swing.text.Document doc = textComp.getDocument(); + String text = doc.getText(0, doc.getLength()); + int pos = 0; + + if ((pane == 0 && !exacts.get(0).isSelected()) || pane == 1 + && !exacts.get(1).isSelected() || pane == 2 + && !exacts.get(2).isSelected()) { + pattern = pattern.toLowerCase(); + text = text.toLowerCase(); + } + + // Search for pattern + while ((pos = text.indexOf(pattern, pos)) >= 0) { + // Create highlighter using private painter and apply around + // pattern + hilite.addHighlight(pos, pos + pattern.length(), painter); + pos += pattern.length(); + } + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + + public ClassViewer(final String name, final ClassNode cn) { + for (int i = 0; i < panels.size(); i++) { + final JTextField textField = fields.get(i); + JPanel searchPanel = searches.get(i); + JCheckBox checkBox = exacts.get(i); + JButton byteSearchNext = new JButton(); + JButton byteSearchPrev = new JButton(); + JPanel byteButtonPane = new JPanel(new BorderLayout()); + byteButtonPane.add(byteSearchNext, BorderLayout.WEST); + byteButtonPane.add(byteSearchPrev, BorderLayout.EAST); + byteSearchNext.setIcon(Resources.nextIcon); + byteSearchPrev.setIcon(Resources.prevIcon); + searchPanel.add(byteButtonPane, BorderLayout.WEST); + searchPanel.add(textField, BorderLayout.CENTER); + searchPanel.add(checkBox, BorderLayout.EAST); + byteSearchNext.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + search(0, textField.getText(), true); + } + }); + byteSearchPrev.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + search(0, textField.getText(), false); + } + }); + textField.addKeyListener(new KeyListener() { + @Override + public void keyReleased(KeyEvent arg0) { + if (arg0.getKeyCode() == KeyEvent.VK_ENTER) + search(0, textField.getText(), true); + } + + @Override + public void keyPressed(KeyEvent arg0) { + } + + @Override + public void keyTyped(KeyEvent arg0) { + } + }); + } + + this.name = name; + this.cn = cn; + this.setName(name); + this.setLayout(new BorderLayout()); + + this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panels.get(0), panels.get(1)); + JHexEditor hex = new JHexEditor(BytecodeViewer.getClassBytes(cn.name + ".class")); + this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, panels.get(2)); + this.add(sp2, BorderLayout.CENTER); + + hex.setMaximumSize(new Dimension(0, Integer.MAX_VALUE)); + hex.setSize(0, Integer.MAX_VALUE); + + BytecodeViewer.viewer.setIcon(true); + startPaneUpdater(null); + this.addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + resetDivider(); + } + }); + } + + public void resetDivider() { + sp.setResizeWeight(0.5); + if (decompilers.get(1) != null && decompilers.get(0) != null) + sp = setDividerLocation(sp, 0.5); + else if (decompilers.get(0) != null) + sp = setDividerLocation(sp, 1); + else if (decompilers.get(1) != null) { + sp.setResizeWeight(1); + sp = setDividerLocation(sp, 0); + } else + sp = setDividerLocation(sp, 0); + if (decompilers.get(2) != null) { + sp2.setResizeWeight(0.7); + sp2 = setDividerLocation(sp2, 0.7); + if ((decompilers.get(1) == null && decompilers.get(0) != null) || (decompilers.get(0) == null && decompilers.get(1) != null)) + sp2 = setDividerLocation(sp2, 0.5); + else if (decompilers.get(0) == null && decompilers.get(1) == null) + sp2 = setDividerLocation(sp2, 0); + } else { + sp.setResizeWeight(1); + sp2.setResizeWeight(0); + sp2 = setDividerLocation(sp2, 1); + } + } + + public void startPaneUpdater(final JButton button) { + this.cn = BytecodeViewer.getClassNode(cn.name); //update the classnode + setPanes(); + + for (JPanel jpanel : panels) { + jpanel.removeAll(); + } + for (int i = 0; i < javas.size(); i++) { + javas.set(i, null); + } + for (int i = 0; i < smalis.size(); i++) { + smalis.set(i, null); + } + + if (this.cn == null) { + for (JPanel jpanel : panels) { + jpanel.add(new JLabel("This file has been removed from the reload.")); + } + return; + } + + for (int i = 0; i < decompilers.size(); i++) { + if (decompilers.get(i) != null) { + if (decompilers.get(i) != Decompiler.HEXCODE) { + panels.get(i).add(searches.get(i), BorderLayout.NORTH); + } + PaneUpdaterThread t = new PaneUpdaterThread(this, decompilers.get(i), i, panels.get(i), button); + decompileThreads.add(t); + t.start(); + } + } + } + + public Object[] getSmali() { + for (int i = 0; i < smalis.size(); i++) { + RSyntaxTextArea text = smalis.get(i); + if (text != null) { + return new Object[]{cn, text.getText()}; + } + } + return null; + } + + public Object[] getKrakatau() { + for (int i = 0; i < krakataus.size(); i++) { + RSyntaxTextArea text = krakataus.get(i); + if (text != null) { + return new Object[]{cn, text.getText()}; + } + } + return null; + } + + public Object[] getJava() { + for (int i = 0; i < javas.size(); i++) { + RSyntaxTextArea text = javas.get(i); + if (text != null) { + return new Object[]{cn, text.getText()}; + } + } + return null; + } + + public void reset() { + for (Thread t : decompileThreads) { + t.stop(); + } + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ExportJar.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ExportJar.java index 7749d23b..9be94922 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ExportJar.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ExportJar.java @@ -1,19 +1,17 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.JFrame; -import java.awt.Dimension; -import javax.swing.JButton; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.JarUtils; -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; - import javax.swing.BoxLayout; -import javax.swing.JScrollPane; +import javax.swing.JButton; +import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JScrollPane; import javax.swing.JTextArea; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileChooser.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileChooser.java new file mode 100644 index 00000000..4579f257 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileChooser.java @@ -0,0 +1,50 @@ +package the.bytecode.club.bytecodeviewer.gui; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Settings; + +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileFilter; +import java.io.File; + +public class FileChooser { + private Settings target; + private String message; + + public FileChooser(Settings target, String message) { + this.target = target; + this.message = message; + } + + public void run() { + File currentFile = new File(target.get() == null || target.get().isEmpty() ? System.getProperty("user.home") : target.get()); + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return true; + } + + @Override + public String getDescription() { + return message; + } + }); + if (currentFile.isDirectory()) { + fc.setCurrentDirectory(currentFile); + } else { + fc.setSelectedFile(currentFile); + } + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + + int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + if (returnVal == JFileChooser.APPROVE_OPTION) { + try { + target.set(fc.getSelectedFile().getAbsolutePath()); + } catch (Exception e1) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); + } + } + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java index c6c968d1..7e6fa308 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileNavigationPane.java @@ -1,18 +1,46 @@ package the.bytecode.club.bytecodeviewer.gui; import org.objectweb.asm.tree.ClassNode; -import the.bytecode.club.bytecodeviewer.*; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.FileChangeNotifier; +import the.bytecode.club.bytecodeviewer.FileContainer; +import the.bytecode.club.bytecodeviewer.FileDrop; +import the.bytecode.club.bytecodeviewer.Resources; -import javax.swing.*; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.*; -import java.awt.*; -import java.awt.event.*; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.Iterator; import java.util.Map.Entry; /*************************************************************************** @@ -53,7 +81,7 @@ public class FileNavigationPane extends VisibleComponent implements FileDrop.Lis MyTreeNode treeRoot = new MyTreeNode("Loaded Files:"); MyTree tree = new MyTree(treeRoot); final JTextField quickSearch = new JTextField(quickSearchText); - public KeyAdapter search = new KeyAdapter() { + public transient KeyAdapter search = new KeyAdapter() { @Override public void keyPressed(final KeyEvent ke) { if (ke.getKeyCode() == KeyEvent.VK_ENTER) { diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileViewer.java index d1082ed2..c2b578cb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/FileViewer.java @@ -1,5 +1,24 @@ package the.bytecode.club.bytecodeviewer.gui; +import com.jhe.hexed.JHexEditor; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; +import org.imgscalr.Scalr; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Resources; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.text.DefaultHighlighter; +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; @@ -14,28 +33,6 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; -import javax.imageio.ImageIO; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JTextField; -import javax.swing.text.DefaultHighlighter; -import javax.swing.text.Highlighter; -import javax.swing.text.JTextComponent; - -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; -import org.fife.ui.rtextarea.RTextScrollPane; -import org.imgscalr.Scalr; - -import com.jhe.hexed.JHexEditor; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.Resources; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/GraphicialReflectionKit.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/GraphicialReflectionKit.java index 6ca41e87..ea6349a5 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/GraphicialReflectionKit.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/GraphicialReflectionKit.java @@ -1,12 +1,12 @@ package the.bytecode.club.bytecodeviewer.gui; +import the.bytecode.club.bytecodeviewer.Resources; + import javax.swing.JFrame; -import java.awt.Dimension; +import javax.swing.JPanel; import javax.swing.JTabbedPane; import java.awt.BorderLayout; -import javax.swing.JPanel; - -import the.bytecode.club.bytecodeviewer.Resources; +import java.awt.Dimension; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java index fa20fcd2..85deb597 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -1,2197 +1,1319 @@ package the.bytecode.club.bytecodeviewer.gui; -import java.awt.Component; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Frame; -import java.awt.KeyEventDispatcher; -import java.awt.KeyboardFocusManager; -import java.awt.event.*; -import java.io.File; -import java.util.ArrayList; - -import javax.swing.*; -import javax.swing.filechooser.FileFilter; - -import me.konloch.kontainer.io.DiskWriter; - -import org.objectweb.asm.ClassWriter; +import org.apache.commons.io.FileUtils; import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.DecompilerSettings; import the.bytecode.club.bytecodeviewer.Dex2Jar; import the.bytecode.club.bytecodeviewer.FileChangeNotifier; import the.bytecode.club.bytecodeviewer.FileContainer; import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.MiscUtils; import the.bytecode.club.bytecodeviewer.Resources; +import the.bytecode.club.bytecodeviewer.Settings; +import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; +import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler; +import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler; +import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameClasses; 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.preinstalled.CodeSequenceDiagram; -import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ShowAllStrings; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ShowMainMethods; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZKMStringDecrypter; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZStringArrayDecrypter; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSeparator; +import javax.swing.JSpinner; +import javax.swing.JSplitPane; +import javax.swing.JTextField; +import javax.swing.SpinnerNumberModel; +import javax.swing.SwingUtilities; +import javax.swing.filechooser.FileFilter; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.KeyEventDispatcher; +import java.awt.KeyboardFocusManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * The main file for the GUI.n - * - * @author Konloch * + * @author Konloch */ public class MainViewerGUI extends JFrame implements FileChangeNotifier { - public void pythonC() { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return true; - } + public void pythonC() { + new FileChooser(Settings.PYTHON2_LOCATION, "Python (Or PyPy for speed) 2.7 Executable").run(); + } - @Override - public String getDescription() { - return "Python (Or PyPy for speed) 2.7 Executable"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + public void javac() { + new FileChooser(Settings.JAVAC_LOCATION, "javac executable (Requires JDK 'C:/Program Files/Java/jdk_xx/bin/javac.exe')").run(); + } - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.python = fc.getSelectedFile().getAbsolutePath(); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } + public void java() { + new FileChooser(Settings.JAVA_LOCATION, "Java Executable (Requires JRE/JDK 'C:/Program Files/Java/jre_xx/bin/java.exe')").run(); + } - public void javac() { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return true; - } + public void pythonC3() { + new FileChooser(Settings.PYTHON3_LOCATION, "Python (Or PyPy for speed) 3.x Executable").run(); + } - @Override - public String getDescription() { - return "Javac Executable (Requires JDK 'C:/programfiles/Java/JRE_xx/bin/javac.exe)"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + public void rtC() { + new FileChooser(Settings.RT_LOCATION, "Java rt.jar").run(); + } - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.javac = fc.getSelectedFile().getAbsolutePath(); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } - - public void java() { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return true; - } - - @Override - public String getDescription() { - return "Java Executable (Inside Of JRE/JDK 'C:/programfiles/Java/JRE_xx/bin/java.exe')"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); - - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.java = fc.getSelectedFile().getAbsolutePath(); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } - - public void pythonC3() { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return true; - } - - @Override - public String getDescription() { - return "Python (Or PyPy for speed) 3.x Executable"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); - - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.python3 = fc.getSelectedFile().getAbsolutePath(); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } - - public void library() {; - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory(); - } - - @Override - public String getDescription() { - return "Optional Library Folder"; - } - }); - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - final JTextField text = new JTextField(); - text.setText(BytecodeViewer.library); - final JDialog dialog = new JDialog(); - dialog.setModal(true); - dialog.add(text); - dialog.setSize(500, 100); - dialog.setLocationRelativeTo(BytecodeViewer.viewer); - dialog.addWindowListener(new WindowListener() { - @Override - public void windowOpened(WindowEvent e) { - - } + public void library() { + final JTextField text = new JTextField(); + text.setText(Settings.PATH.get()); + final JDialog dialog = new JDialog(); + dialog.setModal(true); + dialog.add(text); + dialog.setSize(500, 100); + dialog.setLocationRelativeTo(BytecodeViewer.viewer); + dialog.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - BytecodeViewer.library = text.getText(); - } - @Override - public void windowClosed(WindowEvent e) { - } - @Override - public void windowIconified(WindowEvent e) { - - } - @Override - public void windowDeiconified(WindowEvent e) { - - } - @Override - public void windowActivated(WindowEvent e) { - - } - @Override - public void windowDeactivated(WindowEvent e) { - + Settings.PATH.set(text.getText()); } }); dialog.setVisible(true); -// int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); -// -// if (returnVal == JFileChooser.APPROVE_OPTION) -// try { -// BytecodeViewer.library = fc.getSelectedFile().getAbsolutePath(); -// } catch (Exception e1) { -// new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); -// } - } - + } - public void rtC() { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return true; - } + public static final long serialVersionUID = 1851409230530948543L; - @Override - public String getDescription() { - return "JRE RT Library"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + private final ActionListener listener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (refreshOnChange.isSelected()) { + if (workPane.getCurrentViewer() == null) return; + workPane.refreshClass.doClick(); + } + } + }; - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.rt = fc.getSelectedFile().getAbsolutePath(); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } + private JMenu generateDecompilerMenu(Decompiler decompiler, int panelId) { + ButtonGroup group = allPanes.get(panelId); + JMenu menu = new JMenu(decompiler.getName()); + JRadioButtonMenuItem java = new JRadioButtonMenuItem(decompiler == Decompiler.SMALI ? "Smali" : "Java"); + java.addActionListener(listener); + JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode"); + JCheckBoxMenuItem editable = new JCheckBoxMenuItem("Editable"); + JSeparator separator = new JSeparator(); + menu.add(java); + group.add(java); + allDecompilers.get(group).put(java, decompiler); + allDecompilersRev.get(group).put(decompiler, java); + if (decompiler == Decompiler.KRAKATAU) { + menu.add(bytecode); + group.add(bytecode); + bytecode.addActionListener(listener); + allDecompilers.get(group).put(bytecode, Decompiler.KRAKATAU_DA); + } + menu.add(separator); + menu.add(editable); + editButtons.get(group).put(decompiler, editable); + return menu; + } - public static final long serialVersionUID = 1851409230530948543L; - public JCheckBoxMenuItem debugHelpers = new JCheckBoxMenuItem("Debug Helpers"); - public JSplitPane sp1; - public JSplitPane sp2; - static ArrayList rfComps = new ArrayList(); - public JCheckBoxMenuItem rbr = new JCheckBoxMenuItem("Hide bridge methods"); - public JCheckBoxMenuItem rsy = new JCheckBoxMenuItem( - "Hide synthetic class members"); - public JCheckBoxMenuItem din = new JCheckBoxMenuItem( - "Decompile inner classes"); - public JCheckBoxMenuItem dc4 = new JCheckBoxMenuItem( - "Collapse 1.4 class references"); - public JCheckBoxMenuItem das = new JCheckBoxMenuItem("Decompile assertions"); - public JCheckBoxMenuItem hes = new JCheckBoxMenuItem( - "Hide empty super invocation"); - public JCheckBoxMenuItem hdc = new JCheckBoxMenuItem( - "Hide empty default constructor"); - public JCheckBoxMenuItem dgs = new JCheckBoxMenuItem( - "Decompile generic signatures"); - public JCheckBoxMenuItem ner = new JCheckBoxMenuItem( - "Assume return not throwing exceptions"); - public JCheckBoxMenuItem den = new JCheckBoxMenuItem( - "Decompile enumerations"); - public JCheckBoxMenuItem rgn = new JCheckBoxMenuItem( - "Remove getClass() invocation"); - public JCheckBoxMenuItem bto = new JCheckBoxMenuItem( - "Interpret int 1 as boolean true"); - public JCheckBoxMenuItem nns = new JCheckBoxMenuItem( - "Allow for not set synthetic attribute"); - public JCheckBoxMenuItem uto = new JCheckBoxMenuItem( - "Consider nameless types as java.lang.Object"); - public JCheckBoxMenuItem udv = new JCheckBoxMenuItem( - "Reconstruct variable names from debug info"); - public JCheckBoxMenuItem rer = new JCheckBoxMenuItem( - "Remove empty exception ranges"); - public JCheckBoxMenuItem fdi = new JCheckBoxMenuItem( - "Deinline finally structures"); - public JCheckBoxMenuItem asc = new JCheckBoxMenuItem( - "Allow only ASCII characters in strings"); - public final JMenuItem mntmNewWorkspace = new JMenuItem("New Workspace"); - public JMenu mnRecentFiles = new JMenu("Recent Files"); - public final JMenuItem mntmNewMenuItem = new JMenuItem( - "Decompile & Save All Classes.."); - public final JMenuItem mntmAbout = new JMenuItem("About"); - public final JSeparator separator_3 = new JSeparator(); - public final JMenu mnNewMenu_1 = new JMenu("Plugins"); - public final JMenuItem mntmStartExternalPlugin = new JMenuItem( - "Open Plugin.."); - public final JSeparator separator_4 = new JSeparator(); - public JMenu mnRecentPlugins = new JMenu("Recent Plugins"); - public final JSeparator separator_5 = new JSeparator(); - public final JMenuItem mntmStartZkmString = new JMenuItem( - "ZKM String Decrypter"); - public final JMenuItem mntmNewMenuItem_1 = new JMenuItem( - "Malicious Code Scanner"); - public final JMenuItem mntmNewMenuItem_2 = new JMenuItem( - "Allatori String Decrypter"); - public final JMenuItem mntmShowAllStrings = new JMenuItem( - "Show All Strings"); - public final JMenuItem mntmShowMainMethods = new JMenuItem( - "Show Main Methods"); - public final JMenuItem mntmNewMenuItem_3 = new JMenuItem("Save As Runnable Jar.."); - public JMenuBar menuBar = new JMenuBar(); - public final JMenuItem mntmReplaceStrings = new JMenuItem( - "Replace Strings"); - public final JMenuItem mntmNewMenuItem_4 = new JMenuItem(""); - public final JMenu mnNewMenu_3 = new JMenu("CFR"); - public final JMenu mnNewMenu_4 = new JMenu("Procyon"); - public final JCheckBoxMenuItem decodeenumswitch = new JCheckBoxMenuItem( - "Decode Enum Switch"); - public final JCheckBoxMenuItem sugarenums = new JCheckBoxMenuItem( - "SugarEnums"); - public final JCheckBoxMenuItem decodestringswitch = new JCheckBoxMenuItem( - "Decode String Switch"); - public final JCheckBoxMenuItem arrayiter = new JCheckBoxMenuItem( - "Arrayiter"); - public final JCheckBoxMenuItem collectioniter = new JCheckBoxMenuItem( - "Collectioniter"); - public final JCheckBoxMenuItem innerclasses = new JCheckBoxMenuItem( - "Inner Classes"); - public final JCheckBoxMenuItem removeboilerplate = new JCheckBoxMenuItem( - "Remove Boiler Plate"); - public final JCheckBoxMenuItem removeinnerclasssynthetics = new JCheckBoxMenuItem( - "Remove Inner Class Synthetics"); - public final JCheckBoxMenuItem decodelambdas = new JCheckBoxMenuItem( - "Decode Lambdas"); - public final JCheckBoxMenuItem hidebridgemethods = new JCheckBoxMenuItem( - "Hide Bridge Methods"); - public final JCheckBoxMenuItem liftconstructorinit = new JCheckBoxMenuItem( - "Lift Constructor Init"); - public final JCheckBoxMenuItem removedeadmethods = new JCheckBoxMenuItem( - "Remove Dead Methods"); - public final JCheckBoxMenuItem removebadgenerics = new JCheckBoxMenuItem( - "Remove Bad Generics"); - public final JCheckBoxMenuItem sugarasserts = new JCheckBoxMenuItem( - "Sugar Asserts"); - public final JCheckBoxMenuItem sugarboxing = new JCheckBoxMenuItem( - "Sugar Boxing"); - public final JCheckBoxMenuItem showversion = new JCheckBoxMenuItem( - "Show Version"); - public final JCheckBoxMenuItem decodefinally = new JCheckBoxMenuItem( - "Decode Finally"); - public final JCheckBoxMenuItem tidymonitors = new JCheckBoxMenuItem( - "Tidy Monitors"); - public final JCheckBoxMenuItem lenient = new JCheckBoxMenuItem("Lenient"); - public final JCheckBoxMenuItem dumpclasspath = new JCheckBoxMenuItem( - "Dump Classpath"); - public final JCheckBoxMenuItem comments = new JCheckBoxMenuItem("Comments"); - public final JCheckBoxMenuItem forcetopsort = new JCheckBoxMenuItem( - "Force Top Sort"); - public final JCheckBoxMenuItem forcetopsortaggress = new JCheckBoxMenuItem( - "Force Top Sort Aggress"); - public final JCheckBoxMenuItem stringbuffer = new JCheckBoxMenuItem( - "String Buffer"); - public final JCheckBoxMenuItem stringbuilder = new JCheckBoxMenuItem( - "String Builder"); - public final JCheckBoxMenuItem silent = new JCheckBoxMenuItem("Silent"); - public final JCheckBoxMenuItem recover = new JCheckBoxMenuItem("Recover"); - public final JCheckBoxMenuItem eclipse = new JCheckBoxMenuItem("Eclipse"); - public final JCheckBoxMenuItem override = new JCheckBoxMenuItem("Override"); - public final JCheckBoxMenuItem showinferrable = new JCheckBoxMenuItem( - "Show Inferrable"); - public final JCheckBoxMenuItem aexagg = new JCheckBoxMenuItem("Aexagg"); - public final JCheckBoxMenuItem forcecondpropagate = new JCheckBoxMenuItem( - "Force Cond Propagate"); - public final JCheckBoxMenuItem hideutf = new JCheckBoxMenuItem("Hide UTF"); - public final JCheckBoxMenuItem hidelongstrings = new JCheckBoxMenuItem( - "Hide Long Strings"); - public final JCheckBoxMenuItem commentmonitor = new JCheckBoxMenuItem( - "Comment Monitors"); - public final JCheckBoxMenuItem allowcorrecting = new JCheckBoxMenuItem( - "Allow Correcting"); - public final JCheckBoxMenuItem labelledblocks = new JCheckBoxMenuItem( - "Labelled Blocks"); - public final JCheckBoxMenuItem j14classobj = new JCheckBoxMenuItem( - "J14ClassOBJ"); - public final JCheckBoxMenuItem hidelangimports = new JCheckBoxMenuItem( - "Hide Lang Imports"); - public final JCheckBoxMenuItem recoverytypeclash = new JCheckBoxMenuItem( - "Recover Type Clash"); - public final JCheckBoxMenuItem recoverytypehints = new JCheckBoxMenuItem( - "Recover Type Hints"); - public final JCheckBoxMenuItem forceturningifs = new JCheckBoxMenuItem( - "Force Returning IFs"); - public final JCheckBoxMenuItem forloopaggcapture = new JCheckBoxMenuItem( - "For Loop AGG Capture"); - public final JCheckBoxMenuItem forceexceptionprune = new JCheckBoxMenuItem( - "Force Exception Prune"); - public final JCheckBoxMenuItem chckbxmntmShowDebugLine = new JCheckBoxMenuItem( - "Show Debug Line Numbers"); - public final JCheckBoxMenuItem chckbxmntmSimplifyMemberReferences = new JCheckBoxMenuItem( - "Simplify Member References"); - public final JCheckBoxMenuItem mnMergeVariables = new JCheckBoxMenuItem( - "Merge Variables"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_1 = new JCheckBoxMenuItem( - "Unicode Output Enabled"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_2 = new JCheckBoxMenuItem( - "Retain Pointless Switches"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_3 = new JCheckBoxMenuItem( - "Include Line Numbers In Bytecode"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_4 = new JCheckBoxMenuItem( - "Include Error Diagnostics"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_5 = new JCheckBoxMenuItem( - "Retain Redundant Casts"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_6 = new JCheckBoxMenuItem( - "Always Generate Exception Variable For Catch Blocks"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_7 = new JCheckBoxMenuItem( - "Show Synthetic Members"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_8 = new JCheckBoxMenuItem( - "Force Explicit Type Arguments"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_9 = new JCheckBoxMenuItem( - "Force Explicit Imports"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_10 = new JCheckBoxMenuItem( - "Flatten Switch Blocks"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_11 = new JCheckBoxMenuItem( - "Exclude Nested Types"); - public final JCheckBoxMenuItem chckbxmntmAppendBrackets = new JCheckBoxMenuItem( - "Append Brackets To Labels"); - public final JCheckBoxMenuItem chckbxmntmNewCheckItem_12 = new JCheckBoxMenuItem( - "Update Check"); - public final JMenu mnNewMenu_5 = new JMenu("Obfuscate"); - public final JMenuItem mntmNewMenuItem_6 = new JMenuItem("Rename Fields"); - public final JMenuItem mntmNewMenuItem_7 = new JMenuItem("Rename Methods"); - public final JMenuItem mntmNewMenuItem_8 = new JMenuItem( - "Move All Classes Into Root Package"); - public final JMenuItem mntmNewMenuItem_9 = new JMenuItem("Control Flow"); - public final JMenuItem mntmNewMenuItem_10 = new JMenuItem("Junk Code"); - public final ButtonGroup obfuscatorGroup = new ButtonGroup(); - public final JRadioButtonMenuItem strongObf = new JRadioButtonMenuItem( - "Strong Obfuscation"); - public final JRadioButtonMenuItem lightObf = new JRadioButtonMenuItem( - "Light Obfuscation"); - public final JMenuItem mntmNewMenuItem_11 = new JMenuItem("Rename Classes"); - public final JSeparator separator_2 = new JSeparator(); - public final JMenu mnNewMenu_6 = new JMenu("View"); - public final JMenu mnNewMenu_7 = new JMenu("Pane 1"); - public final JRadioButtonMenuItem panel1None = new JRadioButtonMenuItem( - "None"); - public final JRadioButtonMenuItem panel1Hexcode = new JRadioButtonMenuItem( - "Hexcode"); - public final JRadioButtonMenuItem panel1Bytecode = new JRadioButtonMenuItem( - "Bytecode"); - public final JRadioButtonMenuItem panel1Fern = new JRadioButtonMenuItem( - "Java"); - public final JRadioButtonMenuItem panel1CFR = new JRadioButtonMenuItem( - "Java"); - public final JRadioButtonMenuItem panel1Proc = new JRadioButtonMenuItem( - "Java"); - public final JMenuItem mntmNewMenuItem_12 = new JMenuItem("Decompile & Save Opened Class.."); - public WorkPane workPane = new WorkPane(this); - public final JMenu mnSettings = new JMenu("Settings"); - public final JSeparator separator_6 = new JSeparator(); - public final JCheckBoxMenuItem refreshOnChange = new JCheckBoxMenuItem("Refresh On View Change"); - public AboutWindow aboutWindow = new AboutWindow(); - - public FileNavigationPane cn = new FileNavigationPane(this); - - public boolean isMaximized = false; - - public void removed(boolean busy) { - if (busy) { - this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - for (Component c : this.getComponents()) - c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + private JMenu generatePane(int id) { + JMenu menu = new JMenu("Pane " + (id + 1)); + JRadioButtonMenuItem none = new JRadioButtonMenuItem("None"); + JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode"); + JRadioButtonMenuItem hexcode = new JRadioButtonMenuItem("Hexcode"); + ButtonGroup group = allPanes.get(id); - sp1.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - sp2.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + group.add(none); + group.add(bytecode); + group.add(hexcode); + allDecompilers.get(group).put(none, null); + allDecompilersRev.get(group).put(null, none); + allDecompilers.get(group).put(bytecode, Decompiler.BYTECODE); + allDecompilersRev.get(group).put(Decompiler.BYTECODE, bytecode); + allDecompilers.get(group).put(hexcode, Decompiler.HEXCODE); + allDecompilersRev.get(group).put(Decompiler.HEXCODE, hexcode); - for (VisibleComponent c : rfComps) { - c.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - if (c instanceof WorkPane) { - WorkPane w = (WorkPane) c; - for (Component c2 : w.tabs.getComponents()) - c2.setCursor(Cursor - .getPredefinedCursor(Cursor.WAIT_CURSOR)); - } - } - } else { - this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - for (Component c : this.getComponents()) - c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + menu.add(none); + menu.add(new JSeparator()); + menu.add(generateDecompilerMenu(Decompiler.PROCYON, id)); + menu.add(generateDecompilerMenu(Decompiler.CFR, id)); + menu.add(generateDecompilerMenu(Decompiler.JDGUI, id)); + menu.add(generateDecompilerMenu(Decompiler.FERNFLOWER, id)); + menu.add(generateDecompilerMenu(Decompiler.KRAKATAU, id)); + menu.add(new JSeparator()); + menu.add(generateDecompilerMenu(Decompiler.SMALI, id)); + menu.add(new JSeparator()); + menu.add(bytecode); + menu.add(hexcode); + return menu; + } - sp1.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - sp2.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - - for (VisibleComponent c : rfComps) { - c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - if (c instanceof WorkPane) { - WorkPane w = (WorkPane) c; - for (Component c2 : w.tabs.getComponents()) - c2.setCursor(Cursor - .getPredefinedCursor(Cursor.DEFAULT_CURSOR)); - } - } - } - } - public class Test implements KeyEventDispatcher { @Override public boolean dispatchKeyEvent(KeyEvent e) { - BytecodeViewer.checkHotKey(e); + BytecodeViewer.checkHotKey(e); return false; } } + public FileNavigationPane cn = new FileNavigationPane(this); + public boolean isMaximized = false; + public JSplitPane sp1; + public JSplitPane sp2; + static ArrayList rfComps = new ArrayList(); + public final JMenuItem mntmNewWorkspace = new JMenuItem("New Workspace"); + public JMenu mnRecentFiles = new JMenu("Recent Files"); + public final JMenuItem mntmNewMenuItem = new JMenuItem("Decompile & Save All Classes.."); + public final JMenuItem mntmAbout = new JMenuItem("About"); + public final JMenuItem mntmStartExternalPlugin = new JMenuItem("Open Plugin.."); + public JMenu mnRecentPlugins = new JMenu("Recent Plugins"); + public final JMenuItem mntmStartZkmString = new JMenuItem("ZKM String Decrypter"); + public final JMenuItem mntmNewMenuItem_1 = new JMenuItem("Malicious Code Scanner"); + public final JMenuItem mntmNewMenuItem_2 = new JMenuItem("Allatori String Decrypter"); + public final JMenuItem mntmShowAllStrings = new JMenuItem("Show All Strings"); + public final JMenuItem mntmShowMainMethods = new JMenuItem("Show Main Methods"); + public final JMenuItem mntmNewMenuItem_3 = new JMenuItem("Save As Runnable Jar.."); + public final JMenuItem mntmReplaceStrings = new JMenuItem("Replace Strings"); + public final JCheckBoxMenuItem chckbxmntmNewCheckItem_12 = new JCheckBoxMenuItem("Update Check"); + public final JMenuItem mntmNewMenuItem_6 = new JMenuItem("Rename Fields"); + public final JMenuItem mntmNewMenuItem_7 = new JMenuItem("Rename Methods"); + public final JMenuItem mntmNewMenuItem_8 = new JMenuItem("Move All Classes Into Root Package"); + public final JMenuItem mntmNewMenuItem_9 = new JMenuItem("Control Flow"); + public final JMenuItem mntmNewMenuItem_10 = new JMenuItem("Junk Code"); + public final ButtonGroup obfuscatorGroup = new ButtonGroup(); + public final JRadioButtonMenuItem strongObf = new JRadioButtonMenuItem("Strong Obfuscation"); + public final JRadioButtonMenuItem lightObf = new JRadioButtonMenuItem("Light Obfuscation"); + public final JMenuItem mntmNewMenuItem_11 = new JMenuItem("Rename Classes"); + public final JMenuItem mntmNewMenuItem_12 = new JMenuItem("Decompile & Save Opened Class.."); + public WorkPane workPane = new WorkPane(this); + public final JCheckBoxMenuItem refreshOnChange = new JCheckBoxMenuItem("Refresh On View Change"); + public AboutWindow aboutWindow = new AboutWindow(); public final JMenuItem mntmSaveAsApk = new JMenuItem("Save As DEX.."); - public final JMenuItem mntmCodeSequenceDiagram = new JMenuItem("Code Sequence Diagram"); - public final JSeparator separator_7 = new JSeparator(); - public final JSeparator separator_8 = new JSeparator(); - public final JRadioButtonMenuItem panel1Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile On Save"); - public final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile"); - public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile On Refresh"); - public final JMenuItem mntmSetPythonDirectory = new JMenuItem("Set Python 2.7 Executable"); - public final JSeparator separator_13 = new JSeparator(); - public final JRadioButtonMenuItem panel1Krakatau = new JRadioButtonMenuItem("Java"); - public final JRadioButtonMenuItem panel1KrakatauBytecode = new JRadioButtonMenuItem("Bytecode"); - public final JMenuItem mntmSetJreRt = new JMenuItem("Set JRE RT Library"); - public final JMenuItem mntmZstringarrayDecrypter = new JMenuItem("ZStringArray Decrypter"); - public final JSeparator separator_15 = new JSeparator(); - public final JMenuItem mntmRun = new JMenuItem("Run"); - public final JSeparator separator_18 = new JSeparator(); - public final JCheckBoxMenuItem decodeAPKResources = new JCheckBoxMenuItem("Decode APK Resources"); - public final JMenu mnProcyon = new JMenu("Procyon"); - public final JCheckBoxMenuItem panel1Proc_E = new JCheckBoxMenuItem("Editable"); - public final JSeparator separator_14 = new JSeparator(); - public final JMenu mnCfr = new JMenu("CFR"); - public final JSeparator separator_19 = new JSeparator(); - public final JCheckBoxMenuItem panel1CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnFernflower = new JMenu("FernFlower"); - public final JSeparator separator_20 = new JSeparator(); - public final JCheckBoxMenuItem panel1Fern_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnKrakatau = new JMenu("Krakatau"); - public final JSeparator separator_21 = new JSeparator(); - public final JCheckBoxMenuItem panel1Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnSmalidex = new JMenu("Smali/DEX"); - public final JSeparator separator_22 = new JSeparator(); - public final JCheckBoxMenuItem panel1Smali_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnPane = new JMenu("Pane 2"); - public final JRadioButtonMenuItem panel2None = new JRadioButtonMenuItem("None"); - public final JSeparator separator_9 = new JSeparator(); - public final JMenu menu_1 = new JMenu("Procyon"); - public final JRadioButtonMenuItem panel2Proc = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_10 = new JSeparator(); - public final JCheckBoxMenuItem panel2Proc_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_2 = new JMenu("CFR"); - public final JRadioButtonMenuItem panel2CFR = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_11 = new JSeparator(); - public final JCheckBoxMenuItem panel2CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_3 = new JMenu("FernFlower"); - public final JRadioButtonMenuItem panel2Fern = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_12 = new JSeparator(); - public final JCheckBoxMenuItem panel2Fern_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_4 = new JMenu("Krakatau"); - public final JRadioButtonMenuItem panel2Krakatau = new JRadioButtonMenuItem("Java"); - public final JRadioButtonMenuItem panel2KrakatauBytecode = new JRadioButtonMenuItem("Bytecode"); - public final JSeparator separator_16 = new JSeparator(); - public final JCheckBoxMenuItem panel2Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JSeparator separator_17 = new JSeparator(); - public final JMenu menu_5 = new JMenu("Smali/DEX"); - public final JRadioButtonMenuItem panel2Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JSeparator separator_23 = new JSeparator(); - public final JCheckBoxMenuItem panel2Smali_E = new JCheckBoxMenuItem("Editable"); - public final JSeparator separator_24 = new JSeparator(); - public final JRadioButtonMenuItem panel2Bytecode = new JRadioButtonMenuItem("Bytecode"); - public final JRadioButtonMenuItem panel2Hexcode = new JRadioButtonMenuItem("Hexcode"); - public final JMenu mnPane_1 = new JMenu("Pane 3"); - public final JRadioButtonMenuItem panel3None = new JRadioButtonMenuItem("None"); - public final JSeparator separator_25 = new JSeparator(); - public final JMenu menu_7 = new JMenu("Procyon"); - public final JRadioButtonMenuItem panel3Proc = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_26 = new JSeparator(); - public final JCheckBoxMenuItem panel3Proc_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_8 = new JMenu("CFR"); - public final JRadioButtonMenuItem panel3CFR = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_27 = new JSeparator(); - public final JCheckBoxMenuItem panel3CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_9 = new JMenu("FernFlower"); - public final JRadioButtonMenuItem panel3Fern = new JRadioButtonMenuItem("Java"); - public final JSeparator separator_28 = new JSeparator(); - public final JCheckBoxMenuItem panel3Fern_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_10 = new JMenu("Krakatau"); - public final JRadioButtonMenuItem panel3Krakatau = new JRadioButtonMenuItem("Java"); - public final JRadioButtonMenuItem panel3KrakatauBytecode = new JRadioButtonMenuItem("Bytecode"); - public final JSeparator separator_29 = new JSeparator(); - public final JCheckBoxMenuItem panel3Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JSeparator separator_30 = new JSeparator(); - public final JMenu menu_11 = new JMenu("Smali/DEX"); - public final JRadioButtonMenuItem panel3Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JSeparator separator_31 = new JSeparator(); - public final JCheckBoxMenuItem panel3Smali_E = new JCheckBoxMenuItem("Editable"); - public final JSeparator separator_32 = new JSeparator(); - public final JRadioButtonMenuItem panel3Bytecode = new JRadioButtonMenuItem("Bytecode"); - public final JRadioButtonMenuItem panel3Hexcode = new JRadioButtonMenuItem("Hexcode"); - public void setIcon(final boolean busy) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - if (busy) { - try { - mntmNewMenuItem_4.setIcon(Resources.busyIcon); - } catch (NullPointerException e) { - mntmNewMenuItem_4.setIcon(Resources.busyB64Icon); - } - } else - mntmNewMenuItem_4.setIcon(null); - mntmNewMenuItem_4.updateUI(); - } - }); - } - - public final ButtonGroup panelGroup1 = new ButtonGroup(); - public final ButtonGroup panelGroup2 = new ButtonGroup(); - public final ButtonGroup panelGroup3 = new ButtonGroup(); - private final JMenuItem mntmSetOpitonalLibrary = new JMenuItem("Set Optional Library Folder"); - private final JMenuItem mntmPingback = new JMenuItem("Pingback"); - private final JMenu mnJdgui = new JMenu("JD-GUI"); - public final JRadioButtonMenuItem panel3JDGUI = new JRadioButtonMenuItem("Java"); - private final JSeparator separator_33 = new JSeparator(); - public final JCheckBoxMenuItem panel3JDGUI_E = new JCheckBoxMenuItem("Editable"); - private final JMenu menu = new JMenu("JD-GUI"); - public final JRadioButtonMenuItem panel2JDGUI = new JRadioButtonMenuItem("Java"); - private final JSeparator separator_34 = new JSeparator(); - public final JCheckBoxMenuItem panel2JDGUI_E = new JCheckBoxMenuItem("Editable"); - private final JMenu menu_6 = new JMenu("JD-GUI"); - public final JRadioButtonMenuItem panel1JDGUI = new JRadioButtonMenuItem("Java"); - private final JSeparator separator_35 = new JSeparator(); - public final JCheckBoxMenuItem panel1JDGUI_E = new JCheckBoxMenuItem("Editable"); - private final JMenu mnFontSize = new JMenu("Font Size"); - public final JSpinner fontSpinner = new JSpinner(); - private final JSeparator separator_36 = new JSeparator(); - private final JCheckBoxMenuItem chckbxmntmDeleteForiegnoutdatedLibs = new JCheckBoxMenuItem("Delete Foriegn/Outdated Libs"); - private final JSeparator separator_37 = new JSeparator(); - private final JSeparator separator_38 = new JSeparator(); - private final JMenu mnApkConversion = new JMenu("APK Conversion"); - public final ButtonGroup apkConversionGroup = new ButtonGroup(); - public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar"); - public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify"); - private final JMenuItem mntmSetPythonx = new JMenuItem("Set Python 3.X Executable"); - private final JMenuItem mntmReloadResources = new JMenuItem("Reload Resources"); - private final JSeparator separator_39 = new JSeparator(); - private final JSeparator separator_40 = new JSeparator(); - private final JMenuItem mntmSetJavacExecutable = new JMenuItem("Set Javac Executable"); - - public void calledAfterLoad() { - chckbxmntmDeleteForiegnoutdatedLibs.setSelected(BytecodeViewer.deleteForiegnLibraries); - } - - public MainViewerGUI() { - mnNewMenu_5.setVisible(false); - KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new Test()); - this.addWindowStateListener(new WindowAdapter() { - @Override - public void windowStateChanged(WindowEvent evt) { - int oldState = evt.getOldState(); - int newState = evt.getNewState(); - - if ((oldState & Frame.ICONIFIED) == 0 && (newState & Frame.ICONIFIED) != 0) { - //System.out.println("Frame was iconized"); - } else if ((oldState & Frame.ICONIFIED) != 0 && (newState & Frame.ICONIFIED) == 0) { - //System.out.println("Frame was deiconized"); - } - - if ((oldState & Frame.MAXIMIZED_BOTH) == 0 && (newState & Frame.MAXIMIZED_BOTH) != 0) { - isMaximized = true; - } else if ((oldState & Frame.MAXIMIZED_BOTH) != 0 && (newState & Frame.MAXIMIZED_BOTH) == 0) { - isMaximized = false; - } - } - }); - this.setIconImages(Resources.iconList); - ActionListener listener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(refreshOnChange.isSelected()) { - if(workPane.getCurrentViewer() == null) - return; - - workPane.refreshClass.doClick(); - } - } - - }; - - panel1None.addActionListener(listener); - panel1Hexcode.addActionListener(listener); - obfuscatorGroup.add(strongObf); - obfuscatorGroup.add(lightObf); - obfuscatorGroup.setSelected(strongObf.getModel(), true); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - // procyon - /* none */ - - setJMenuBar(menuBar); - - JMenu mnNewMenu = new JMenu("File"); - menuBar.add(mnNewMenu); - - mntmNewWorkspace.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - BytecodeViewer.resetWorkSpace(true); - } - }); - - JMenuItem mntmLoadJar = new JMenuItem("Add.."); - mntmLoadJar.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fc = new JFileChooser(); - try { - File f = new File(BytecodeViewer.lastDirectory); - if(f.exists()) - fc.setSelectedFile(f); - } catch(Exception e2) { - - } - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = MiscUtils.extension(f.getAbsolutePath()); - if (extension != null) - if (extension.equals("jar") || extension.equals("zip") - || extension.equals("class") || extension.equals("apk") - || extension.equals("dex")) - return true; - - return false; - } - - @Override - public String getDescription() { - return "APKs, DEX, Class Files or Zip/Jar Archives"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - BytecodeViewer.lastDirectory = fc.getSelectedFile().getAbsolutePath(); - try { - BytecodeViewer.viewer.setIcon(true); - BytecodeViewer.openFiles(new File[] { fc - .getSelectedFile() }, true); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } - } - }); - mnNewMenu.add(mntmLoadJar); - - mnNewMenu.add(separator_40); - - mnNewMenu.add(mntmNewWorkspace); - - JMenuItem mntmSave = new JMenuItem("Save As Zip.."); - mntmSave.setActionCommand(""); - mntmSave.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - Thread t = new Thread() { - public void run() { - if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); - } - - @Override - public String getDescription() { - return "Zip Archives"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showSaveDialog(MainViewerGUI.this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - if(!file.getAbsolutePath().endsWith(".zip")) - file = new File(file.getAbsolutePath()+".zip"); - - if(file.exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - file.delete(); - } else { - return; - } - } - - final File file2 = file; - - BytecodeViewer.viewer.setIcon(true); - Thread t = new Thread() { - @Override - public void run() { - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), - file2.getAbsolutePath()); - BytecodeViewer.viewer.setIcon(false); - } - }; - t.start(); - } - } - }; - t.start(); - } - }); - - mnNewMenu.add(separator_39); - mntmReloadResources.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - JOptionPane pane = new JOptionPane("Are you sure you wish to reload the resources?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Reload Resources"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - ArrayList reopen = new ArrayList(); - for(FileContainer container : BytecodeViewer.files) - reopen.add(container.file); - - BytecodeViewer.files.clear(); - BytecodeViewer.openFiles(reopen.toArray(new File[reopen.size()]), false); - - //refresh panes - } - } - }); - - mnNewMenu.add(mntmReloadResources); - - mnNewMenu.add(separator_3); - mntmNewMenuItem_3.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - Thread t = new Thread() { - public void run() { - if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); - } - - @Override - public String getDescription() { - return "Zip Archives"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showSaveDialog(MainViewerGUI.this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - String path = file.getAbsolutePath(); - if (!path.endsWith(".jar")) - path = path + ".jar"; - - if(new File(path).exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - file.delete(); - } else { - return; - } - } - - new ExportJar(path).setVisible(true); - } - } - }; - t.start(); - } - }); - mntmNewMenuItem_13.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - Thread t = new Thread() { - public void run() { - BytecodeViewer.compile(true); - } - }; - t.start(); - } - }); - mntmRun.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new RunOptions().setVisible(true); - } - }); - - mnNewMenu.add(mntmRun); - - mnNewMenu.add(mntmNewMenuItem_13); - - mnNewMenu.add(separator_18); - - mnNewMenu.add(mntmNewMenuItem_3); - mntmSaveAsApk.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread() { - public void run() { - if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("dex"); - } - - @Override - public String getDescription() { - return "Android DEX Files"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showSaveDialog(MainViewerGUI.this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - final File file = fc.getSelectedFile(); - String output = file.getAbsolutePath(); - if (!output.endsWith(".dex")) - output = output + ".dex"; - - final File file2 = new File(output); - - if(file2.exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - file.delete(); - } else { - return; - } - } - - Thread t = new Thread() { - @Override - public void run() { - BytecodeViewer.viewer.setIcon(true); - final String input = BytecodeViewer.tempDirectory+BytecodeViewer.fs+BytecodeViewer.getRandomizedName()+".jar"; - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input); - - Thread t = new Thread() { - @Override - public void run() { - Dex2Jar.saveAsDex(new File(input), file2); - - BytecodeViewer.viewer.setIcon(false); - } - }; - t.start(); - } - }; - t.start(); - } - } - }; - t.start(); - } - }); - - mnNewMenu.add(mntmSaveAsApk); - mnNewMenu.add(mntmSave); - mntmNewMenuItem.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.files.isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread() { - public void run() { - if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); - } - - @Override - public String getDescription() { - return "Zip Archives"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showSaveDialog(MainViewerGUI.this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - if(!file.getAbsolutePath().endsWith(".zip")) - file = new File(file.getAbsolutePath()+".zip"); - - if(file.exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - file.delete(); - } else { - return; - } - } - - BytecodeViewer.viewer.setIcon(true); - final String path = MiscUtils.append(file, ".zip"); // cheap hax cause - // string is final - - JOptionPane pane = new JOptionPane( - "What decompiler will you use?"); - Object[] options = new String[] { "Procyon", "CFR", - "Fernflower", "Krakatau", "JD-GUI", "Cancel" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Select Decompiler"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - Thread t = new Thread() { - @Override - public void run() { - try { - Decompiler.procyon.decompileToZip(path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - }; - t.start(); - } - if (result == 1) { - Thread t = new Thread() { - @Override - public void run() { - try { - Decompiler.cfr.decompileToZip(path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - }; - t.start(); - } - if (result == 2) { - Thread t = new Thread() { - @Override - public void run() { - try { - Decompiler.fernflower.decompileToZip(path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - }; - t.start(); - } - - if (result == 3) { - Thread t = new Thread() { - @Override - public void run() { - try { - Decompiler.krakatau.decompileToZip(path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - }; - t.start(); - } else if (result == 4) { - new Thread() { - @Override - public void run() { - try { - Decompiler.jdgui.decompileToZip(path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - }.start(); - } else { - BytecodeViewer.viewer.setIcon(false); - } - } - } - }; - t.start(); - } - }); - mntmNewMenuItem_12.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(workPane.getCurrentViewer() == null) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread() { - public void run() { - if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) - return; - final String s = workPane.getCurrentViewer().name; - - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("java"); - } - - @Override - public String getDescription() { - return "Java Source Files"; - } - }); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showSaveDialog(MainViewerGUI.this); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - - BytecodeViewer.viewer.setIcon(true); - final String path = MiscUtils.append(file, ".java"); // cheap hax cause - // string is final - - if(new File(path).exists()) { - JOptionPane pane = new JOptionPane( - "Are you sure you wish to overwrite this existing file?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Overwrite File"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - file.delete(); - } else { - return; - } - } - - JOptionPane pane = new JOptionPane( - "What decompiler will you use?"); - Object[] options = new String[] { "Procyon", "CFR", - "Fernflower", "Krakatau", "Cancel" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Select Decompiler"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - Thread t = new Thread() { - @Override - public void run() { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch(Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { } - } - String contents = Decompiler.procyon.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI( - e); - } - } - }; - t.start(); - } - if (result == 1) { - Thread t = new Thread() { - @Override - public void run() { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch(Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { } - } - String contents = Decompiler.cfr.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI( - e); - } - } - }; - t.start(); - } - if (result == 2) { - Thread t = new Thread() { - @Override - public void run() { - try { - - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch(Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { } - } - String contents = Decompiler.fernflower.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI( - e); - } - } - }; - t.start(); - } - if (result == 3) { - Thread t = new Thread() { - @Override - public void run() { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - cn.accept(cw); - } catch(Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - cn.accept(cw); - } catch (InterruptedException e1) { } - } - String contents = Decompiler.krakatau.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI( - e); - } - } - }; - t.start(); - } - if(result == 4) { - BytecodeViewer.viewer.setIcon(false); - } - } - } - }; - t.start(); - } - }); - - mnNewMenu.add(mntmNewMenuItem_12); - - mnNewMenu.add(mntmNewMenuItem); - - JSeparator separator = new JSeparator(); - mnNewMenu.add(separator); - - mnNewMenu.add(mnRecentFiles); - - JSeparator separator_1 = new JSeparator(); - mnNewMenu.add(separator_1); - mntmAbout.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - aboutWindow.setVisible(true); - } - }); - - mnNewMenu.add(mntmAbout); - - JMenuItem mntmExit = new JMenuItem("Exit"); - mntmExit.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - JOptionPane pane = new JOptionPane( - "Are you sure you want to exit?"); - Object[] options = new String[] { "Yes", "No" }; - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, - "Bytecode Viewer - Exit"); - dialog.setVisible(true); - Object obj = pane.getValue(); - int result = -1; - for (int k = 0; k < options.length; k++) - if (options[k].equals(obj)) - result = k; - - if (result == 0) { - System.exit(0); - } - } - }); - mntmPingback.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - BytecodeViewer.pingback(); - } - }); - - mnNewMenu.add(mntmPingback); - mnNewMenu.add(mntmExit); - - menuBar.add(mnNewMenu_6); - - mnNewMenu_6.add(mnNewMenu_7); - - mnNewMenu_7.add(panel1None); - - mnNewMenu_7.add(separator_7); - - mnNewMenu_7.add(mnProcyon); - mnProcyon.add(panel1Proc); - - mnProcyon.add(separator_14); - - mnProcyon.add(panel1Proc_E); - panel1Proc.addActionListener(listener); - - mnNewMenu_7.add(mnCfr); - mnCfr.add(panel1CFR); - panel1CFR.addActionListener(listener); - - mnCfr.add(separator_19); - - mnCfr.add(panel1CFR_E); - - mnNewMenu_7.add(menu_6); - - menu_6.add(panel1JDGUI); - - menu_6.add(separator_35); - - menu_6.add(panel1JDGUI_E); - - mnNewMenu_7.add(mnFernflower); - mnFernflower.add(panel1Fern); - panel1Fern.addActionListener(listener); - - mnFernflower.add(separator_20); - - mnFernflower.add(panel1Fern_E); - - mnNewMenu_7.add(mnKrakatau); - mnKrakatau.add(panel1Krakatau); - panel1Krakatau.addActionListener(listener); - mnKrakatau.add(panel1KrakatauBytecode); - panel1KrakatauBytecode.addActionListener(listener); - - mnKrakatau.add(separator_21); - - mnKrakatau.add(panel1Krakatau_E); - - mnNewMenu_7.add(separator_8); - - mnNewMenu_7.add(mnSmalidex); - mnSmalidex.add(panel1Smali); - panel1Smali.addActionListener(listener); - - mnSmalidex.add(separator_22); - - mnSmalidex.add(panel1Smali_E); - panel1Bytecode.addActionListener(listener); - - mnNewMenu_7.add(separator_15); - - mnNewMenu_7.add(panel1Bytecode); - - mnNewMenu_7.add(panel1Hexcode); - - mnNewMenu_6.add(mnPane); - - mnPane.add(panel2None); - - mnPane.add(separator_9); - - mnPane.add(menu_1); - - menu_1.add(panel2Proc); - - menu_1.add(separator_10); - - menu_1.add(panel2Proc_E); - - mnPane.add(menu_2); - - menu_2.add(panel2CFR); - - menu_2.add(separator_11); - - menu_2.add(panel2CFR_E); - - mnPane.add(menu); - - menu.add(panel2JDGUI); - - menu.add(separator_34); - - menu.add(panel2JDGUI_E); - - mnPane.add(menu_3); - - menu_3.add(panel2Fern); - - menu_3.add(separator_12); - - menu_3.add(panel2Fern_E); - - mnPane.add(menu_4); - - menu_4.add(panel2Krakatau); - - menu_4.add(panel2KrakatauBytecode); - - menu_4.add(separator_16); - - menu_4.add(panel2Krakatau_E); - - mnPane.add(separator_17); - - mnPane.add(menu_5); - - menu_5.add(panel2Smali); - - menu_5.add(separator_23); - - menu_5.add(panel2Smali_E); - - mnPane.add(separator_24); - - mnPane.add(panel2Bytecode); - - mnPane.add(panel2Hexcode); - - mnNewMenu_6.add(mnPane_1); - - mnPane_1.add(panel3None); - - mnPane_1.add(separator_25); - - mnPane_1.add(menu_7); - - menu_7.add(panel3Proc); - - menu_7.add(separator_26); - - menu_7.add(panel3Proc_E); - - mnPane_1.add(menu_8); - - menu_8.add(panel3CFR); - - menu_8.add(separator_27); - - menu_8.add(panel3CFR_E); - - mnPane_1.add(mnJdgui); - - mnJdgui.add(panel3JDGUI); - - mnJdgui.add(separator_33); - - mnJdgui.add(panel3JDGUI_E); - - mnPane_1.add(menu_9); - - menu_9.add(panel3Fern); - - menu_9.add(separator_28); - - menu_9.add(panel3Fern_E); - - mnPane_1.add(menu_10); - - menu_10.add(panel3Krakatau); - - menu_10.add(panel3KrakatauBytecode); - - menu_10.add(separator_29); - - menu_10.add(panel3Krakatau_E); - - mnPane_1.add(separator_30); - - mnPane_1.add(menu_11); - - menu_11.add(panel3Smali); - - menu_11.add(separator_31); - - menu_11.add(panel3Smali_E); - - mnPane_1.add(separator_32); - - mnPane_1.add(panel3Bytecode); - - mnPane_1.add(panel3Hexcode); - - menuBar.add(mnSettings); - autoCompileSmali.setSelected(true); - - mnSettings.add(autoCompileSmali); - autoCompileOnRefresh.setSelected(true); - - mnSettings.add(autoCompileOnRefresh); - - mnSettings.add(refreshOnChange); - - mnSettings.add(separator_38); - decodeAPKResources.setSelected(true); - - mnSettings.add(decodeAPKResources); - - mnSettings.add(mnApkConversion); - - mnApkConversion.add(apkConversionDex); - - mnApkConversion.add(apkConversionEnjarify); - - mnSettings.add(separator_37); - chckbxmntmNewCheckItem_12.setSelected(true); - mnSettings.add(chckbxmntmNewCheckItem_12); - chckbxmntmDeleteForiegnoutdatedLibs.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - if(!chckbxmntmDeleteForiegnoutdatedLibs.isSelected()) { - BytecodeViewer.showMessage("WARNING: With this being toggled off outdated libraries will NOT be removed. It's also a security issue. ONLY TURN IT OFF IF YOU KNOW WHAT YOU'RE DOING."); - } - BytecodeViewer.deleteForiegnLibraries = chckbxmntmDeleteForiegnoutdatedLibs.isSelected(); - } - }); - chckbxmntmDeleteForiegnoutdatedLibs.setSelected(true); - - mnSettings.add(chckbxmntmDeleteForiegnoutdatedLibs); - - mnSettings.add(separator_36); - mntmSetPythonDirectory.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - pythonC(); - } - }); - - mnSettings.add(mntmSetPythonDirectory); - mntmSetJreRt.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - rtC(); - } - }); - mntmSetPythonx.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - pythonC3(); - } - }); - - mnSettings.add(mntmSetPythonx); - - mnSettings.add(mntmSetJreRt); - mntmSetOpitonalLibrary.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - library(); - } - }); - - mnSettings.add(mntmSetOpitonalLibrary); - mntmSetJavacExecutable.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent arg0) { - javac(); - } - }); - - mnSettings.add(mntmSetJavacExecutable); - - mnSettings.add(separator_6); - mnSettings.add(mnNewMenu_4); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_6); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_11); - - mnNewMenu_4.add(chckbxmntmShowDebugLine); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_3); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_4); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_7); - - mnNewMenu_4.add(chckbxmntmSimplifyMemberReferences); - - mnNewMenu_4.add(mnMergeVariables); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_8); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_9); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_10); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_2); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_5); - - mnNewMenu_4.add(chckbxmntmNewCheckItem_1); - // cfr - decodeenumswitch.setSelected(true); - sugarenums.setSelected(true); - decodestringswitch.setSelected(true); - arrayiter.setSelected(true); - collectioniter.setSelected(true); - innerclasses.setSelected(true); - removeboilerplate.setSelected(true); - removeinnerclasssynthetics.setSelected(true); - decodelambdas.setSelected(true); - hidebridgemethods.setSelected(true); - liftconstructorinit.setSelected(true); - removedeadmethods.setSelected(true); - removebadgenerics.setSelected(true); - sugarasserts.setSelected(true); - sugarboxing.setSelected(true); - showversion.setSelected(true); - decodefinally.setSelected(true); - tidymonitors.setSelected(true); - lenient.setSelected(false); - dumpclasspath.setSelected(false); - comments.setSelected(true); - forcetopsort.setSelected(true); - forcetopsortaggress.setSelected(true); - forceexceptionprune.setSelected(true); - stringbuffer.setSelected(false); - stringbuilder.setSelected(true); - silent.setSelected(true); - recover.setSelected(true); - eclipse.setSelected(true); - override.setSelected(true); - showinferrable.setSelected(true); - aexagg.setSelected(true); - forcecondpropagate.setSelected(true); - hideutf.setSelected(true); - hidelongstrings.setSelected(false); - commentmonitor.setSelected(false); - allowcorrecting.setSelected(true); - labelledblocks.setSelected(true); - j14classobj.setSelected(false); - hidelangimports.setSelected(true); - recoverytypeclash.setSelected(true); - recoverytypehints.setSelected(true); - forceturningifs.setSelected(true); - forloopaggcapture.setSelected(true); - mnSettings.add(mnNewMenu_3); - - mnNewMenu_3.add(decodeenumswitch); - - mnNewMenu_3.add(sugarenums); - - mnNewMenu_3.add(decodestringswitch); - - mnNewMenu_3.add(arrayiter); - - mnNewMenu_3.add(collectioniter); - - mnNewMenu_3.add(innerclasses); - - mnNewMenu_3.add(removeboilerplate); - - mnNewMenu_3.add(removeinnerclasssynthetics); - - mnNewMenu_3.add(decodelambdas); - - mnNewMenu_3.add(hidebridgemethods); - - mnNewMenu_3.add(liftconstructorinit); - - mnNewMenu_3.add(removedeadmethods); - - mnNewMenu_3.add(removebadgenerics); - - mnNewMenu_3.add(sugarasserts); - - mnNewMenu_3.add(sugarboxing); - - mnNewMenu_3.add(showversion); - - mnNewMenu_3.add(decodefinally); - - mnNewMenu_3.add(tidymonitors); - - mnNewMenu_3.add(lenient); - - mnNewMenu_3.add(dumpclasspath); - - mnNewMenu_3.add(comments); - - mnNewMenu_3.add(forcetopsort); - - mnNewMenu_3.add(forcetopsortaggress); - - mnNewMenu_3.add(forceexceptionprune); - - mnNewMenu_3.add(stringbuffer); - - mnNewMenu_3.add(stringbuilder); - - mnNewMenu_3.add(silent); - - mnNewMenu_3.add(recover); - - mnNewMenu_3.add(eclipse); - - mnNewMenu_3.add(override); - - mnNewMenu_3.add(showinferrable); - - mnNewMenu_3.add(aexagg); - - mnNewMenu_3.add(forcecondpropagate); - - mnNewMenu_3.add(hideutf); - - mnNewMenu_3.add(hidelongstrings); - - mnNewMenu_3.add(commentmonitor); - - mnNewMenu_3.add(allowcorrecting); - - mnNewMenu_3.add(labelledblocks); - - mnNewMenu_3.add(j14classobj); - - mnNewMenu_3.add(hidelangimports); - - mnNewMenu_3.add(recoverytypeclash); - - mnNewMenu_3.add(recoverytypehints); - - mnNewMenu_3.add(forceturningifs); - - mnNewMenu_3.add(forloopaggcapture); - // fernflower - rbr.setSelected(true); - rsy.setSelected(false); - din.setSelected(true); - das.setSelected(true); - dgs.setSelected(false); - den.setSelected(true); - uto.setSelected(true); - udv.setSelected(true); - fdi.setSelected(true); - asc.setSelected(false); - - JMenu mnDecompilerSettings = new JMenu("FernFlower"); - mnSettings.add(mnDecompilerSettings); - dc4.setSelected(true); - mnDecompilerSettings.add(dc4); - nns.setSelected(true); - mnDecompilerSettings.add(nns); - ner.setSelected(true); - mnDecompilerSettings.add(ner); - bto.setSelected(true); - mnDecompilerSettings.add(bto); - rgn.setSelected(true); - mnDecompilerSettings.add(rgn); - rer.setSelected(true); - mnDecompilerSettings.add(rer); - mnDecompilerSettings.add(rbr); - mnDecompilerSettings.add(rsy); - hes.setSelected(true); - mnDecompilerSettings.add(hes); - hdc.setSelected(true); - mnDecompilerSettings.add(hdc); - mnDecompilerSettings.add(din); - mnDecompilerSettings.add(das); - mnDecompilerSettings.add(dgs); - mnDecompilerSettings.add(den); - mnDecompilerSettings.add(uto); - mnDecompilerSettings.add(udv); - mnDecompilerSettings.add(fdi); - mnDecompilerSettings.add(asc); - debugHelpers.setSelected(true); - // other - chckbxmntmAppendBrackets.setSelected(true); - - JMenu mnBytecodeDecompilerSettings = new JMenu("Bytecode Decompiler"); - mnSettings.add(mnBytecodeDecompilerSettings); - - mnBytecodeDecompilerSettings.add(debugHelpers); - - mnBytecodeDecompilerSettings.add(chckbxmntmAppendBrackets); - - menuBar.add(mnNewMenu_5); - mntmNewMenuItem_6.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if (BytecodeViewer.runningObfuscation) { - BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); - return; - } - new RenameFields().start(); - workPane.refreshClass.doClick(); - cn.tree.updateUI(); - } - }); - - mnNewMenu_5.add(strongObf); - - mnNewMenu_5.add(lightObf); - - mnNewMenu_5.add(separator_2); - mntmNewMenuItem_8.setEnabled(false); - - mnNewMenu_5.add(mntmNewMenuItem_8); - - mnNewMenu_5.add(mntmNewMenuItem_6); - mntmNewMenuItem_7.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if (BytecodeViewer.runningObfuscation) { - BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); - return; - } - new RenameMethods().start(); - workPane.refreshClass.doClick(); - cn.tree.updateUI(); - } - }); - - mnNewMenu_5.add(mntmNewMenuItem_7); - mntmNewMenuItem_11.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if (BytecodeViewer.runningObfuscation) { - BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); - return; - } - new RenameClasses().start(); - workPane.refreshClass.doClick(); - cn.tree.updateUI(); - } - }); - - mnNewMenu_5.add(mntmNewMenuItem_11); - mntmNewMenuItem_9.setEnabled(false); - - mnNewMenu_5.add(mntmNewMenuItem_9); - mntmNewMenuItem_10.setEnabled(false); - - mnNewMenu_5.add(mntmNewMenuItem_10); - - menuBar.add(mnNewMenu_1); - mnNewMenu_1.add(mntmStartExternalPlugin); - mnNewMenu_1.add(separator_4); - mnNewMenu_1.add(mnRecentPlugins); - mnNewMenu_1.add(separator_5); - mntmCodeSequenceDiagram.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - PluginManager.runPlugin(new CodeSequenceDiagram()); - } - }); - - mnNewMenu_1.add(mntmCodeSequenceDiagram); - mnNewMenu_1.add(mntmNewMenuItem_1); - mnNewMenu_1.add(mntmShowMainMethods); - mnNewMenu_1.add(mntmShowAllStrings); - mntmReplaceStrings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new ReplaceStringsOptions().setVisible(true); - } - }); - - mnNewMenu_1.add(mntmReplaceStrings); - mnNewMenu_1.add(mntmNewMenuItem_2); - mnNewMenu_1.add(mntmStartZkmString); - mntmZstringarrayDecrypter.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - PluginManager.runPlugin(new ZStringArrayDecrypter()); - } - }); - - mnNewMenu_1.add(mntmZstringarrayDecrypter); - - menuBar.add(mntmNewMenuItem_4); - - mntmStartExternalPlugin.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - JFileChooser fc = new JFileChooser(); - fc.setFileFilter(PluginManager.fileFilter()); - fc.setFileHidingEnabled(false); - fc.setAcceptAllFileFilterUsed(false); - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); - - if (returnVal == JFileChooser.APPROVE_OPTION) - try { - BytecodeViewer.viewer.setIcon(true); - BytecodeViewer.startPlugin(fc.getSelectedFile()); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e1) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); - } - } - }); - mntmStartZkmString.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - PluginManager.runPlugin(new ZKMStringDecrypter()); - } - }); - mntmNewMenuItem_2.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new AllatoriStringDecrypterOptions().setVisible(true); - } - }); - mntmNewMenuItem_1.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if(BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new MaliciousCodeScannerOptions().setVisible(true); - } - }); - mntmShowAllStrings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - PluginManager.runPlugin(new ShowAllStrings()); - } - }); - - mntmShowMainMethods.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - PluginManager.runPlugin(new ShowMainMethods()); - } - }); - - setSize(new Dimension(800, 400)); - if(BytecodeViewer.previewCopy) - setTitle("Bytecode Viewer "+BytecodeViewer.version+" Preview - https://bytecodeviewer.com | https://the.bytecode.club - @Konloch"); - else - setTitle("Bytecode Viewer "+BytecodeViewer.version+" - https://bytecodeviewer.com | https://the.bytecode.club - @Konloch"); - - getContentPane().setLayout( - new BoxLayout(getContentPane(), BoxLayout.X_AXIS)); - - // scrollPane.setViewportView(tree); - cn.setMinimumSize(new Dimension(200, 50)); - // panel.add(cn); - SearchingPane s = new SearchingPane(this); - s.setPreferredSize(new Dimension(200, 50)); - s.setMinimumSize(new Dimension(200, 50)); - s.setMaximumSize(new Dimension(200, 2147483647)); - // panel.add(s); - sp1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, cn, s); - // panel.add(sp1); - cn.setPreferredSize(new Dimension(200, 50)); - cn.setMaximumSize(new Dimension(200, 2147483647)); - sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp1, workPane); - getContentPane().add(sp2); - sp2.setResizeWeight(0.05); - sp1.setResizeWeight(0.5); - rfComps.add(cn); - - rfComps.add(s); - rfComps.add(workPane); - - apkConversionGroup.add(apkConversionDex); - apkConversionGroup.add(apkConversionEnjarify); - apkConversionGroup.setSelected(apkConversionDex.getModel(), true); - - - panelGroup1.add(panel1None); - panelGroup1.add(panel1Proc); - panelGroup1.add(panel1CFR); - panelGroup1.add(panel1JDGUI); - panelGroup1.add(panel1Fern); - panelGroup1.add(panel1Krakatau); - panelGroup1.add(panel1KrakatauBytecode); - panelGroup1.add(panel1Smali); - panelGroup1.add(panel1Bytecode); - panelGroup1.add(panel1Hexcode); - - panelGroup2.add(panel2None); - panelGroup2.add(panel2Proc); - panelGroup2.add(panel2CFR); - panelGroup2.add(panel2JDGUI); - panelGroup2.add(panel2Fern); - panelGroup2.add(panel2Krakatau); - panelGroup2.add(panel2KrakatauBytecode); - panelGroup2.add(panel2Smali); - panelGroup2.add(panel2Bytecode); - panelGroup2.add(panel2Hexcode); - - panelGroup3.add(panel3None); - panelGroup3.add(panel3Proc); - panelGroup3.add(panel3CFR); - panelGroup3.add(panel3JDGUI); - panelGroup3.add(panel3Fern); - panelGroup3.add(panel3Krakatau); - panelGroup3.add(panel3KrakatauBytecode); - panelGroup3.add(panel3Smali); - panelGroup3.add(panel3Bytecode); - panelGroup3.add(panel3Hexcode); - mnNewMenu_6.add(separator_13); - fontSpinner.setPreferredSize(new Dimension(42, 20)); - fontSpinner.setSize(new Dimension(42, 20)); - fontSpinner.setModel(new SpinnerNumberModel(new Integer(12), new Integer(1), null, new Integer(1))); - mnNewMenu_6.add(mnFontSize); - - mnFontSize.add(fontSpinner); - - - panelGroup1.setSelected(panel1JDGUI.getModel(), true); - panelGroup2.setSelected(panel2Bytecode.getModel(), true); - panelGroup3.setSelected(panel3None.getModel(), true); - - this.setLocationRelativeTo(null); - } - - - @Override - public void openClassFile(final String name, final ClassNode cn) { - for (final VisibleComponent vc : rfComps) { - vc.openClassFile(name, cn); - } - } - - @Override - public void openFile(final String name, byte[] content) { - for (final VisibleComponent vc : rfComps) { - vc.openFile(name, content); - } - } - - @SuppressWarnings("unchecked") - public static T getComponent(final Class clazz) { - for (final VisibleComponent vc : rfComps) { - if (vc.getClass() == clazz) - return (T) vc; - } - return null; - } + public final JMenuItem mntmCodeSequenceDiagram = new JMenuItem("Code Sequence Diagram"); + public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile On Save"); + public final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile"); + public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile On Refresh"); + public final JMenuItem mntmSetPythonDirectory = new JMenuItem("Set Python 2.7 Executable"); + public final JMenuItem mntmSetJreRt = new JMenuItem("Set JRE RT Library"); + public final JMenuItem mntmZstringarrayDecrypter = new JMenuItem("ZStringArray Decrypter"); + public final JMenuItem mntmRun = new JMenuItem("Run"); + public final JCheckBoxMenuItem decodeAPKResources = new JCheckBoxMenuItem("Decode APK Resources"); + public final ButtonGroup panelGroup1 = new ButtonGroup(); + public final ButtonGroup panelGroup2 = new ButtonGroup(); + public final ButtonGroup panelGroup3 = new ButtonGroup(); + private final JMenuItem mntmSetOpitonalLibrary = new JMenuItem("Set Optional Library Folder"); + private final JMenuItem mntmPingback = new JMenuItem("Pingback"); + private final JMenu mnFontSize = new JMenu("Font Size"); + private final JCheckBoxMenuItem chckbxmntmDeleteForiegnoutdatedLibs = new JCheckBoxMenuItem("Delete Foriegn/Outdated Libs"); + private final JMenu mnApkConversion = new JMenu("APK Conversion"); + public final ButtonGroup apkConversionGroup = new ButtonGroup(); + public final JRadioButtonMenuItem apkConversionDex = new JRadioButtonMenuItem("Dex2Jar"); + public final JRadioButtonMenuItem apkConversionEnjarify = new JRadioButtonMenuItem("Enjarify"); + private final JMenuItem mntmSetPythonx = new JMenuItem("Set Python 3.X Executable"); + private final JMenuItem mntmReloadResources = new JMenuItem("Reload Resources"); + private final JMenuItem mntmSetJavacExecutable = new JMenuItem("Set Javac Executable"); + public List allPanes = Collections.unmodifiableList(Arrays.asList(panelGroup1, panelGroup2, panelGroup3)); + public Map> allDecompilers = new HashMap<>(); + public Map> allDecompilersRev = new HashMap<>(); + public Map> editButtons = new HashMap<>(); + + public MainViewerGUI() { + Decompiler.ensureInitted(); + allDecompilers.put(panelGroup1, new HashMap()); + allDecompilers.put(panelGroup2, new HashMap()); + allDecompilers.put(panelGroup3, new HashMap()); + allDecompilersRev.put(panelGroup1, new HashMap()); + allDecompilersRev.put(panelGroup2, new HashMap()); + allDecompilersRev.put(panelGroup3, new HashMap()); + editButtons.put(panelGroup1, new HashMap()); + editButtons.put(panelGroup2, new HashMap()); + editButtons.put(panelGroup3, new HashMap()); + KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new Test()); + this.addWindowStateListener(new WindowAdapter() { + @Override + public void windowStateChanged(WindowEvent evt) { + int oldState = evt.getOldState(); + int newState = evt.getNewState(); + + if ((oldState & Frame.ICONIFIED) == 0 && (newState & Frame.ICONIFIED) != 0) { + //System.out.println("Frame was iconized"); + } else if ((oldState & Frame.ICONIFIED) != 0 && (newState & Frame.ICONIFIED) == 0) { + //System.out.println("Frame was deiconized"); + } + + if ((oldState & Frame.MAXIMIZED_BOTH) == 0 && (newState & Frame.MAXIMIZED_BOTH) != 0) { + isMaximized = true; + } else if ((oldState & Frame.MAXIMIZED_BOTH) != 0 && (newState & Frame.MAXIMIZED_BOTH) == 0) { + isMaximized = false; + } + } + }); + this.setIconImages(Resources.iconList); + + JMenuBar menuBar = new JMenuBar(); + JMenu fileMenu = new JMenu("File"); + JMenu viewMenu = new JMenu("View"); + JMenu settingsMenu = new JMenu("Settings"); + JMenu obfuscateMenu = new JMenu("Obfuscate"); + JMenu pluginsMenu = new JMenu("Plugins"); + obfuscateMenu.setVisible(false); + setJMenuBar(menuBar); + + obfuscatorGroup.add(strongObf); + obfuscatorGroup.add(lightObf); + obfuscatorGroup.setSelected(strongObf.getModel(), true); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + + menuBar.add(fileMenu); + + mntmNewWorkspace.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + BytecodeViewer.resetWorkSpace(true); + } + }); + + JMenuItem mntmLoadJar = new JMenuItem("Add.."); + mntmLoadJar.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fc = new JFileChooser(); + try { + File f = new File(BytecodeViewer.lastDirectory); + if (f.exists()) fc.setSelectedFile(f); + } catch (Exception e2) { + + } + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + if (f.isDirectory()) return true; + + String extension = MiscUtils.extension(f.getAbsolutePath()); + if (extension != null) + if (extension.equals("jar") || extension.equals("zip") || extension.equals("class") || extension.equals("apk") || extension.equals("dex")) + return true; + + return false; + } + + @Override + public String getDescription() { + return "APKs, DEX, Class Files or Zip/Jar Archives"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + BytecodeViewer.lastDirectory = fc.getSelectedFile().getAbsolutePath(); + try { + BytecodeViewer.viewer.setIcon(true); + BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()}, true); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e1) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); + } + } + } + }); + fileMenu.add(mntmLoadJar); + + fileMenu.add(new JSeparator()); + + fileMenu.add(mntmNewWorkspace); + + JMenuItem mntmSave = new JMenuItem("Save As Zip.."); + mntmSave.setActionCommand(""); + mntmSave.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.getLoadedBytes().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + Thread t = new Thread() { + public void run() { + if (autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); + } + + @Override + public String getDescription() { + return "Zip Archives"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(MainViewerGUI.this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + if (!file.getAbsolutePath().endsWith(".zip")) + file = new File(file.getAbsolutePath() + ".zip"); + + if (file.exists()) { + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + file.delete(); + } else { + return; + } + } + + final File file2 = file; + + BytecodeViewer.viewer.setIcon(true); + Thread t = new Thread() { + @Override + public void run() { + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), file2.getAbsolutePath()); + BytecodeViewer.viewer.setIcon(false); + } + }; + t.start(); + } + } + }; + t.start(); + } + }); + + fileMenu.add(new JSeparator()); + mntmReloadResources.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + JOptionPane pane = new JOptionPane("Are you sure you wish to reload the resources?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Reload Resources"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + ArrayList reopen = new ArrayList(); + for (FileContainer container : BytecodeViewer.files) + reopen.add(container.file); + + BytecodeViewer.files.clear(); + BytecodeViewer.openFiles(reopen.toArray(new File[reopen.size()]), false); + + //refresh panes + } + } + }); + + fileMenu.add(mntmReloadResources); + + fileMenu.add(new JSeparator()); + mntmNewMenuItem_3.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (BytecodeViewer.getLoadedBytes().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + Thread t = new Thread() { + public void run() { + if (autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); + } + + @Override + public String getDescription() { + return "Zip Archives"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(MainViewerGUI.this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + String path = file.getAbsolutePath(); + if (!path.endsWith(".jar")) path = path + ".jar"; + + if (new File(path).exists()) { + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + file.delete(); + } else { + return; + } + } + + new ExportJar(path).setVisible(true); + } + } + }; + t.start(); + } + }); + mntmNewMenuItem_13.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + Thread t = new Thread() { + public void run() { + BytecodeViewer.compile(true); + } + }; + t.start(); + } + }); + mntmRun.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (BytecodeViewer.getLoadedBytes().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new RunOptions().setVisible(true); + } + }); + + fileMenu.add(mntmRun); + + fileMenu.add(mntmNewMenuItem_13); + + fileMenu.add(new JSeparator()); + + fileMenu.add(mntmNewMenuItem_3); + mntmSaveAsApk.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.getLoadedBytes().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread() { + public void run() { + if (autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("dex"); + } + + @Override + public String getDescription() { + return "Android DEX Files"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(MainViewerGUI.this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + final File file = fc.getSelectedFile(); + String output = file.getAbsolutePath(); + if (!output.endsWith(".dex")) output = output + ".dex"; + + final File file2 = new File(output); + + if (file2.exists()) { + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + file.delete(); + } else { + return; + } + } + + Thread t = new Thread() { + @Override + public void run() { + BytecodeViewer.viewer.setIcon(true); + final String input = BytecodeViewer.tempDir.getAbsolutePath() + BytecodeViewer.fs + BytecodeViewer.getRandomizedName() + ".jar"; + JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), input); + + Thread t = new Thread() { + @Override + public void run() { + Dex2Jar.saveAsDex(new File(input), file2); + + BytecodeViewer.viewer.setIcon(false); + } + }; + t.start(); + } + }; + t.start(); + } + } + }; + t.start(); + } + }); + + fileMenu.add(mntmSaveAsApk); + fileMenu.add(mntmSave); + mntmNewMenuItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.files.isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread() { + public void run() { + if (autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); + } + + @Override + public String getDescription() { + return "Zip Archives"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(MainViewerGUI.this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + if (!file.getAbsolutePath().endsWith(".zip")) + file = new File(file.getAbsolutePath() + ".zip"); + + if (file.exists()) { + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + file.delete(); + } else { + return; + } + } + + BytecodeViewer.viewer.setIcon(true); + final String path = MiscUtils.append(file, ".zip"); // cheap hax cause + // string is final + + JOptionPane pane = new JOptionPane("What decompiler will you use?"); + Object[] options = new String[]{"Procyon", "CFR", "Fernflower", "Krakatau", "JD-GUI", "Cancel"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Select Decompiler"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + Thread t = new Thread() { + @Override + public void run() { + try { + Decompiler.PROCYON.decompileToZip(path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 1) { + Thread t = new Thread() { + @Override + public void run() { + try { + Decompiler.CFR.decompileToZip(path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 2) { + Thread t = new Thread() { + @Override + public void run() { + try { + Decompiler.FERNFLOWER.decompileToZip(path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + + if (result == 3) { + Thread t = new Thread() { + @Override + public void run() { + try { + Decompiler.KRAKATAU.decompileToZip(path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } else if (result == 4) { + new Thread() { + @Override + public void run() { + try { + Decompiler.JDGUI.decompileToZip(path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }.start(); + } else { + BytecodeViewer.viewer.setIcon(false); + } + } + } + }; + t.start(); + } + }); + mntmNewMenuItem_12.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (workPane.getCurrentViewer() == null) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread() { + public void run() { + if (autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return; + final String s = workPane.getCurrentViewer().name; + + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("java"); + } + + @Override + public String getDescription() { + return "Java Source Files"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(MainViewerGUI.this); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + + BytecodeViewer.viewer.setIcon(true); + final String path = MiscUtils.append(file, ".java"); // cheap hax cause + // string is final + + if (new File(path).exists()) { + JOptionPane pane = new JOptionPane("Are you sure you wish to overwrite this existing file?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Overwrite File"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + file.delete(); + } else { + return; + } + } + + JOptionPane pane = new JOptionPane("What decompiler will you use?"); + Object[] options = new String[]{"Procyon", "CFR", "Fernflower", "Krakatau", "Cancel"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Select Decompiler"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + Thread t = new Thread() { + @Override + public void run() { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + byte[] bytes = BytecodeViewer.getClassBytes(s); + String contents = Decompiler.PROCYON.decompileClassNode(cn, bytes); + FileUtils.write(new File(path), contents, "UTF-8", false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 1) { + Thread t = new Thread() { + @Override + public void run() { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + byte[] bytes = BytecodeViewer.getClassBytes(s); + String contents = Decompiler.CFR.decompileClassNode(cn, bytes); + FileUtils.write(new File(path), contents, "UTF-8", false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 2) { + Thread t = new Thread() { + @Override + public void run() { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + byte[] bytes = BytecodeViewer.getClassBytes(s); + String contents = Decompiler.FERNFLOWER.decompileClassNode(cn, bytes); + FileUtils.write(new File(path), contents, "UTF-8", false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 3) { + Thread t = new Thread() { + @Override + public void run() { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + byte[] bytes = BytecodeViewer.getClassBytes(s); + String contents = Decompiler.KRAKATAU.decompileClassNode(cn, bytes); + FileUtils.write(new File(path), contents, "UTF-8", false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + }; + t.start(); + } + if (result == 4) { + BytecodeViewer.viewer.setIcon(false); + } + } + } + }; + t.start(); + } + }); + + fileMenu.add(mntmNewMenuItem_12); + fileMenu.add(mntmNewMenuItem); + fileMenu.add(new JSeparator()); + fileMenu.add(mnRecentFiles); + fileMenu.add(new JSeparator()); + mntmAbout.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + aboutWindow.setVisible(true); + } + }); + + fileMenu.add(mntmAbout); + + JMenuItem mntmExit = new JMenuItem("Exit"); + mntmExit.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + JOptionPane pane = new JOptionPane("Are you sure you want to exit?"); + Object[] options = new String[]{"Yes", "No"}; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Exit"); + dialog.setVisible(true); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) result = k; + + if (result == 0) { + System.exit(0); + } + } + }); + mntmPingback.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + BytecodeViewer.pingback(); + } + }); + + fileMenu.add(mntmPingback); + fileMenu.add(mntmExit); + + menuBar.add(viewMenu); + viewMenu.add(generatePane(0)); + viewMenu.add(generatePane(1)); + viewMenu.add(generatePane(2)); + + + autoCompileSmali.setSelected(true); + + settingsMenu.add(autoCompileSmali); + autoCompileOnRefresh.setSelected(true); + + settingsMenu.add(autoCompileOnRefresh); + + settingsMenu.add(refreshOnChange); + + settingsMenu.add(new JSeparator()); + decodeAPKResources.setSelected(true); + + settingsMenu.add(decodeAPKResources); + + settingsMenu.add(mnApkConversion); + + mnApkConversion.add(apkConversionDex); + + mnApkConversion.add(apkConversionEnjarify); + + settingsMenu.add(new JSeparator()); + chckbxmntmNewCheckItem_12.setSelected(true); + settingsMenu.add(chckbxmntmNewCheckItem_12); + chckbxmntmDeleteForiegnoutdatedLibs.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + if (!chckbxmntmDeleteForiegnoutdatedLibs.isSelected()) { + BytecodeViewer.showMessage("WARNING: With this being toggled off outdated libraries will NOT be removed. It's also a security issue. ONLY TURN IT OFF IF YOU KNOW WHAT YOU'RE DOING."); + } + BytecodeViewer.deleteForiegnLibraries = chckbxmntmDeleteForiegnoutdatedLibs.isSelected(); + } + }); + chckbxmntmDeleteForiegnoutdatedLibs.setSelected(true); + + settingsMenu.add(chckbxmntmDeleteForiegnoutdatedLibs); + + settingsMenu.add(new JSeparator()); + mntmSetPythonDirectory.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + pythonC(); + } + }); + + settingsMenu.add(mntmSetPythonDirectory); + mntmSetJreRt.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + rtC(); + } + }); + mntmSetPythonx.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + pythonC3(); + } + }); + + settingsMenu.add(mntmSetPythonx); + + settingsMenu.add(mntmSetJreRt); + mntmSetOpitonalLibrary.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + library(); + } + }); + + settingsMenu.add(mntmSetOpitonalLibrary); + mntmSetJavacExecutable.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + javac(); + } + }); + + settingsMenu.add(mntmSetJavacExecutable); + + settingsMenu.add(new JSeparator()); + + JMenu cfrSettingsMenu = new JMenu("CFR"); + DecompilerSettings cfrSettings = Decompiler.CFR.getSettings(); + for (CFRDecompiler.Settings setting : CFRDecompiler.Settings.values()) { + cfrSettingsMenu.add(cfrSettings.getMenuItem(setting)); + } + settingsMenu.add(cfrSettingsMenu); + + JMenu fernflowerSettingMenu = new JMenu("FernFlower"); + DecompilerSettings fernflowerSettings = Decompiler.FERNFLOWER.getSettings(); + for (FernFlowerDecompiler.Settings setting : FernFlowerDecompiler.Settings.values()) { + fernflowerSettingMenu.add(fernflowerSettings.getMenuItem(setting)); + } + settingsMenu.add(fernflowerSettingMenu); + + JMenu procyonSettingsMenu = new JMenu("Procyon"); + DecompilerSettings procyonSettings = Decompiler.PROCYON.getSettings(); + for (ProcyonDecompiler.Settings setting : ProcyonDecompiler.Settings.values()) { + procyonSettingsMenu.add(procyonSettings.getMenuItem(setting)); + } + settingsMenu.add(procyonSettingsMenu); + + JMenu bytecodeSettingsMenu = new JMenu("Bytecode Decompiler"); + DecompilerSettings bytecodeSettings = Decompiler.BYTECODE.getSettings(); + for (ClassNodeDecompiler.Settings setting : ClassNodeDecompiler.Settings.values()) { + bytecodeSettingsMenu.add(bytecodeSettings.getMenuItem(setting)); + } + settingsMenu.add(bytecodeSettingsMenu); + + menuBar.add(settingsMenu); + menuBar.add(obfuscateMenu); + mntmNewMenuItem_6.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.runningObfuscation) { + BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); + return; + } + new RenameFields().start(); + workPane.refreshClass.doClick(); + cn.tree.updateUI(); + } + }); + + obfuscateMenu.add(strongObf); + + obfuscateMenu.add(lightObf); + + obfuscateMenu.add(new JSeparator()); + mntmNewMenuItem_8.setEnabled(false); + + obfuscateMenu.add(mntmNewMenuItem_8); + + obfuscateMenu.add(mntmNewMenuItem_6); + mntmNewMenuItem_7.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.runningObfuscation) { + BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); + return; + } + new RenameMethods().start(); + workPane.refreshClass.doClick(); + cn.tree.updateUI(); + } + }); + + obfuscateMenu.add(mntmNewMenuItem_7); + mntmNewMenuItem_11.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.runningObfuscation) { + BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); + return; + } + new RenameClasses().start(); + workPane.refreshClass.doClick(); + cn.tree.updateUI(); + } + }); + + obfuscateMenu.add(mntmNewMenuItem_11); + mntmNewMenuItem_9.setEnabled(false); + + obfuscateMenu.add(mntmNewMenuItem_9); + mntmNewMenuItem_10.setEnabled(false); + + obfuscateMenu.add(mntmNewMenuItem_10); + + menuBar.add(pluginsMenu); + pluginsMenu.add(mntmStartExternalPlugin); + pluginsMenu.add(new JSeparator()); + pluginsMenu.add(mnRecentPlugins); + pluginsMenu.add(new JSeparator()); + mntmCodeSequenceDiagram.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + PluginManager.runPlugin(new CodeSequenceDiagram()); + } + }); + + pluginsMenu.add(mntmCodeSequenceDiagram); + pluginsMenu.add(mntmNewMenuItem_1); + pluginsMenu.add(mntmShowMainMethods); + pluginsMenu.add(mntmShowAllStrings); + mntmReplaceStrings.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new ReplaceStringsOptions().setVisible(true); + } + }); + + pluginsMenu.add(mntmReplaceStrings); + pluginsMenu.add(mntmNewMenuItem_2); + pluginsMenu.add(mntmStartZkmString); + mntmZstringarrayDecrypter.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + PluginManager.runPlugin(new ZStringArrayDecrypter()); + } + }); + + pluginsMenu.add(mntmZstringarrayDecrypter); + + menuBar.add(spinnerMenu); + + mntmStartExternalPlugin.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + JFileChooser fc = new JFileChooser(); + fc.setFileFilter(PluginManager.fileFilter()); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + + if (returnVal == JFileChooser.APPROVE_OPTION) try { + BytecodeViewer.viewer.setIcon(true); + BytecodeViewer.startPlugin(fc.getSelectedFile()); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e1) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); + } + } + }); + mntmStartZkmString.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PluginManager.runPlugin(new ZKMStringDecrypter()); + } + }); + mntmNewMenuItem_2.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new AllatoriStringDecrypterOptions().setVisible(true); + } + }); + mntmNewMenuItem_1.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new MaliciousCodeScannerOptions().setVisible(true); + } + }); + mntmShowAllStrings.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PluginManager.runPlugin(new ShowAllStrings()); + } + }); + + mntmShowMainMethods.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + PluginManager.runPlugin(new ShowMainMethods()); + } + }); + + setSize(new Dimension(800, 400)); + if (BytecodeViewer.previewCopy) + setTitle("Bytecode Viewer " + BytecodeViewer.version + " Preview - https://bytecodeviewer.com | https://the.bytecode.club - @Konloch"); + else + setTitle("Bytecode Viewer " + BytecodeViewer.version + " - https://bytecodeviewer.com | https://the.bytecode.club - @Konloch"); + + getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS)); + + // scrollPane.setViewportView(tree); + cn.setMinimumSize(new Dimension(200, 50)); + // panel.add(cn); + SearchingPane s = new SearchingPane(this); + s.setPreferredSize(new Dimension(200, 50)); + s.setMinimumSize(new Dimension(200, 50)); + s.setMaximumSize(new Dimension(200, 2147483647)); + // panel.add(s); + sp1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, cn, s); + // panel.add(sp1); + cn.setPreferredSize(new Dimension(200, 50)); + cn.setMaximumSize(new Dimension(200, 2147483647)); + sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp1, workPane); + getContentPane().add(sp2); + sp2.setResizeWeight(0.05); + sp1.setResizeWeight(0.5); + rfComps.add(cn); + + rfComps.add(s); + rfComps.add(workPane); + + apkConversionGroup.add(apkConversionDex); + apkConversionGroup.add(apkConversionEnjarify); + apkConversionGroup.setSelected(apkConversionDex.getModel(), true); + + fontSpinner.setPreferredSize(new Dimension(42, 20)); + fontSpinner.setSize(new Dimension(42, 20)); + fontSpinner.setModel(new SpinnerNumberModel(12, 1, null, 1)); + viewMenu.add(mnFontSize); + + mnFontSize.add(fontSpinner); + + + panelGroup1.setSelected(allDecompilersRev.get(panelGroup1).get(Decompiler.JDGUI).getModel(), true); + panelGroup2.setSelected(allDecompilersRev.get(panelGroup2).get(Decompiler.BYTECODE).getModel(), true); + panelGroup3.setSelected(allDecompilersRev.get(panelGroup3).get(null).getModel(), true); + this.setLocationRelativeTo(null); + } + + public JSpinner fontSpinner = new JSpinner(); + private JMenuItem spinnerMenu = new JMenuItem(""); + + public void setIcon(final boolean busy) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (busy) { + try { + spinnerMenu.setIcon(Resources.busyIcon); + } catch (NullPointerException e) { + spinnerMenu.setIcon(Resources.busyB64Icon); + } + } else spinnerMenu.setIcon(null); + spinnerMenu.updateUI(); + } + }); + } + + public void calledAfterLoad() { + chckbxmntmDeleteForiegnoutdatedLibs.setSelected(BytecodeViewer.deleteForiegnLibraries); + } + + @Override + public void openClassFile(final String name, final ClassNode cn) { + for (final VisibleComponent vc : rfComps) { + vc.openClassFile(name, cn); + } + } + + @Override + public void openFile(final String name, byte[] content) { + for (final VisibleComponent vc : rfComps) { + vc.openFile(name, content); + } + } + + public static T getComponent(final Class clazz) { + for (final VisibleComponent vc : rfComps) { + if (vc.getClass() == clazz) return clazz.cast(vc); + } + return null; + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java index 3d4f0cfa..9ac5c439 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java @@ -1,18 +1,15 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.JFrame; - -import java.awt.Dimension; - -import javax.swing.JCheckBox; -import javax.swing.JButton; - import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.plugin.PluginManager; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.MaliciousCodeScanner; -import java.awt.event.ActionListener; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import java.awt.Dimension; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/PaneUpdaterThread.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/PaneUpdaterThread.java index 599b5437..81f7dead 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/PaneUpdaterThread.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/PaneUpdaterThread.java @@ -18,20 +18,98 @@ package the.bytecode.club.bytecodeviewer.gui; * along with this program. If not, see . * ***************************************************************************/ +import com.jhe.hexed.JHexEditor; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rtextarea.RTextScrollPane; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; +import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.awt.Font; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + /** - * Allows us to run a background thread + * Updates a pane * * @author Konloch - * */ +public class PaneUpdaterThread extends Thread { -public abstract class PaneUpdaterThread extends Thread { + private Decompiler decompiler; + private int paneId; + private JPanel target; + private ClassViewer viewer; + private JButton button; - public abstract void doShit(); - - @Override - public void run() { - doShit(); + public PaneUpdaterThread(ClassViewer viewer, Decompiler decompiler, int paneId, JPanel target, JButton button) { + this.decompiler = decompiler; + this.paneId = paneId; + this.target = target; + this.viewer = viewer; + this.button = button; } + public void run() { + try { + final byte[] b = BytecodeViewer.getClassBytes(viewer.cn.name + ".class"); + if (decompiler != Decompiler.HEXCODE) { + RSyntaxTextArea panelArea = new RSyntaxTextArea(); + panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); + panelArea.setCodeFoldingEnabled(true); + panelArea.setAntiAliasingEnabled(true); + final RTextScrollPane scrollPane = new RTextScrollPane(panelArea); + panelArea.setText(decompiler.decompileClassNode(viewer.cn, b)); + panelArea.setCaretPosition(0); + panelArea.setEditable(viewer.isPaneEditable(paneId)); + panelArea.addKeyListener(new KeyListener() { + @Override + public void keyPressed(KeyEvent e) { + if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) { + viewer.requestFocus(paneId); + } + + BytecodeViewer.checkHotKey(e); + } + + @Override + public void keyReleased(KeyEvent arg0) { + } + + @Override + public void keyTyped(KeyEvent arg0) { + } + }); + scrollPane.setColumnHeaderView(new JLabel(decompiler.getName() + " Decompiler - Editable: " + panelArea.isEditable())); + panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue())); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + target.add(scrollPane); + } + }); + viewer.updatePane(paneId, panelArea, decompiler); + } else { + final JHexEditor hex = new JHexEditor(b); + hex.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue())); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + target.add(hex); + } + }); + } + } catch(Exception e) { + new ExceptionUI(e); + } finally { + viewer.resetDivider(); + BytecodeViewer.viewer.setIcon(false); + if(button != null) + button.setEnabled(true); + } + } } \ No newline at end of file diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java index 7ff27eab..c806bf5f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java @@ -1,20 +1,17 @@ package the.bytecode.club.bytecodeviewer.gui; -import java.awt.Dimension; - -import javax.swing.JFrame; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JTextField; - import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.plugin.PluginManager; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ReplaceStrings; -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; - +import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTextField; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/RunOptions.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/RunOptions.java index 39f41a26..4b03f617 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/RunOptions.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/RunOptions.java @@ -1,26 +1,20 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.JFrame; - -import java.awt.Dimension; - -import javax.swing.JCheckBox; -import javax.swing.JButton; - +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.plugin.PluginManager; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; - -import javax.swing.JTextField; - -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; - +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JTextField; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/SearchingPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/SearchingPane.java index a90cbce7..f37e0a8a 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/SearchingPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/SearchingPane.java @@ -3,14 +3,29 @@ package the.bytecode.club.bytecodeviewer.gui; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.FileChangeNotifier; -import the.bytecode.club.bytecodeviewer.searching.*; +import the.bytecode.club.bytecodeviewer.searching.BackgroundSearchThread; +import the.bytecode.club.bytecodeviewer.searching.FieldCallSearch; +import the.bytecode.club.bytecodeviewer.searching.LDCSearch; +import the.bytecode.club.bytecodeviewer.searching.MethodCallSearch; +import the.bytecode.club.bytecodeviewer.searching.RegexInsnFinder; +import the.bytecode.club.bytecodeviewer.searching.RegexSearch; +import the.bytecode.club.bytecodeviewer.searching.SearchResultNotifier; +import the.bytecode.club.bytecodeviewer.searching.SearchTypeDetails; -import javax.swing.*; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTree; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; @@ -59,7 +74,7 @@ public class SearchingPane extends VisibleComponent { JComboBox searchRadiusBox; public JButton search = new JButton("Search"); - BackgroundSearchThread t = new BackgroundSearchThread(true) { + transient BackgroundSearchThread t = new BackgroundSearchThread(true) { @Override public void doSearch() { // empty diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/SystemErrConsole.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/SystemErrConsole.java index 2f056f73..1f1c5df7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/SystemErrConsole.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/SystemErrConsole.java @@ -1,16 +1,21 @@ package the.bytecode.club.bytecodeviewer.gui; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Resources; + import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.JTextField; - +import javax.swing.text.DefaultHighlighter; +import javax.swing.text.Highlighter; +import javax.swing.text.JTextComponent; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; - -import javax.swing.JScrollPane; - -import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; @@ -19,16 +24,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; -import javax.swing.JTextArea; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.Resources; - -import javax.swing.JPanel; -import javax.swing.text.DefaultHighlighter; -import javax.swing.text.Highlighter; -import javax.swing.text.JTextComponent; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java index acf87130..2e429746 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java @@ -1,5 +1,14 @@ package the.bytecode.club.bytecodeviewer.gui; +import javax.swing.AbstractButton; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTabbedPane; +import javax.swing.plaf.basic.BasicButtonUI; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; @@ -13,16 +22,6 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import javax.swing.AbstractButton; -import javax.swing.BorderFactory; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JMenuItem; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.JTabbedPane; -import javax.swing.plaf.basic.BasicButtonUI; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/Viewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/Viewer.java index f0263065..2d163aec 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/Viewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/Viewer.java @@ -1,8 +1,9 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.JPanel; import org.objectweb.asm.tree.ClassNode; +import javax.swing.JPanel; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/VisibleComponent.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/VisibleComponent.java index 2ec8e322..f680aa36 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/VisibleComponent.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/VisibleComponent.java @@ -1,11 +1,10 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.JInternalFrame; - import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.FileChangeNotifier; +import javax.swing.JInternalFrame; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java index f4ac4880..a6be82e4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java @@ -1,5 +1,14 @@ package the.bytecode.club.bytecodeviewer.gui; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.FileChangeNotifier; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; @@ -9,17 +18,6 @@ import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.util.HashMap; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JTabbedPane; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; - -import org.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.FileChangeNotifier; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -156,7 +154,7 @@ public class WorkPane extends VisibleComponent implements ActionListener { } public java.awt.Component[] getLoadedViewers() { - return (java.awt.Component[])tabs.getComponents(); + return tabs.getComponents(); } @Override @@ -193,6 +191,9 @@ public class WorkPane extends VisibleComponent implements ActionListener { } public void resetWorkspace() { + for (Component component : tabs.getComponents()) { + ((ClassViewer) component).reset(); + } tabs.removeAll(); tabs.updateUI(); } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/JavaObfuscator.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/JavaObfuscator.java index 17c86d66..20ca5642 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/JavaObfuscator.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/JavaObfuscator.java @@ -1,10 +1,10 @@ package the.bytecode.club.bytecodeviewer.obfuscators; -import java.util.ArrayList; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.MiscUtils; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameClasses.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameClasses.java index f2968467..8727fa7b 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameClasses.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameClasses.java @@ -1,7 +1,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators; import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameFields.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameFields.java index 42471d54..12303acb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameFields.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameFields.java @@ -2,7 +2,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameMethods.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameMethods.java index c81a056d..2718de8e 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameMethods.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/RenameMethods.java @@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/HookMap.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/HookMap.java index 91e35b04..f1c347c7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/HookMap.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/HookMap.java @@ -1,12 +1,12 @@ package the.bytecode.club.bytecodeviewer.obfuscators.mapping; -import java.util.ArrayList; -import java.util.List; - import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData; +import java.util.ArrayList; +import java.util.List; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/RefactorMapper.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/RefactorMapper.java index b929185e..deee50f3 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/RefactorMapper.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/RefactorMapper.java @@ -1,16 +1,15 @@ package the.bytecode.club.bytecodeviewer.obfuscators.mapping; +import org.objectweb.asm.commons.Remapper; +import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData; +import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData; +import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.objectweb.asm.commons.Remapper; - -import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData; -import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData; -import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -72,7 +71,7 @@ public class RefactorMapper extends Remapper { @Override public String map(String type) { if (sortedClasses.containsKey(type)) { - String map = new String(type + " --> " + sortedClasses.get(type).getRefactoredName() + "\n"); + String map = type + " --> " + sortedClasses.get(type).getRefactoredName() + "\n"; if (!mappingList.contains(map)) mappingList.add(map); @@ -85,7 +84,7 @@ public class RefactorMapper extends Remapper { public String mapFieldName(String owner, String name, String desc) { String obfKey = owner + "$$$$" + name + "$$$$" + desc; if (sortedFields.containsKey(obfKey)) { - String map = new String(owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n"); + String map = owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n"; if (!mappingList.contains(map)) mappingList.add(map); name = sortedFields.get(obfKey).getName().getRefactoredName(); @@ -97,7 +96,7 @@ public class RefactorMapper extends Remapper { public String mapMethodName(String owner, String name, String desc) { String obfKey = owner + "$$$$" + name + "$$$$" + desc; if (sortedMethods.containsKey(obfKey)) { - String map = new String(owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n"); + String map = owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n"; if (!mappingList.contains(map)) mappingList.add(map); name = sortedMethods.get(obfKey).getMethodName().getRefactoredName(); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/Refactorer.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/Refactorer.java index 19659659..3dce375e 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/Refactorer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/mapping/Refactorer.java @@ -1,15 +1,14 @@ package the.bytecode.club.bytecodeviewer.obfuscators.mapping; -import java.util.HashMap; -import java.util.Map; - import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.commons.RemappingClassAdapter; import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import java.util.HashMap; +import java.util.Map; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameClasses.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameClasses.java index 97cc20f4..3c3e0b73 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameClasses.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameClasses.java @@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameFields.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameFields.java index e3de6858..d79c286d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameFields.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameFields.java @@ -2,7 +2,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameMethods.java b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameMethods.java index c2655360..6e8d6869 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameMethods.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/obfuscators/rename/RenameMethods.java @@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java index 277e44a3..e607fa9d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java @@ -1,9 +1,9 @@ package the.bytecode.club.bytecodeviewer.plugin; -import java.io.File; - import the.bytecode.club.bytecodeviewer.api.Plugin; +import java.io.File; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java index 2e9bfd81..465214ca 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java @@ -1,12 +1,5 @@ package the.bytecode.club.bytecodeviewer.plugin; -import java.io.File; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.swing.filechooser.FileFilter; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.MiscUtils; import the.bytecode.club.bytecodeviewer.api.Plugin; @@ -16,6 +9,12 @@ import the.bytecode.club.bytecodeviewer.plugin.strategies.JavaPluginLaunchStrate import the.bytecode.club.bytecodeviewer.plugin.strategies.PythonPluginLaunchStrategy; import the.bytecode.club.bytecodeviewer.plugin.strategies.RubyPluginLaunchStrategy; +import javax.swing.filechooser.FileFilter; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java index 88bacdd2..760e4612 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java @@ -1,14 +1,5 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.swing.JDialog; -import javax.swing.JOptionPane; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.InsnList; @@ -16,13 +7,20 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java index 442219eb..ebb95414 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java @@ -1,26 +1,23 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.awt.Font; -import java.awt.font.FontRenderContext; -import java.awt.geom.AffineTransform; -import java.util.ArrayList; - -import javax.swing.JFrame; -import javax.swing.UIManager; - +import com.mxgraph.swing.mxGraphComponent; +import com.mxgraph.view.mxGraph; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; - -import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.view.mxGraph; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.gui.ClassViewer; +import javax.swing.JFrame; +import javax.swing.UIManager; +import java.awt.Font; +import java.awt.font.FontRenderContext; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java index 3262fbc8..458c1181 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java @@ -1,23 +1,22 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.util.ArrayList; - import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.BytecodeHook; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; import the.bytecode.club.bytecodeviewer.gui.GraphicialReflectionKit; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java index 18e94a9f..9169c065 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java @@ -1,7 +1,5 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.util.ArrayList; - import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -11,11 +9,12 @@ import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java index de016c56..ce0286c4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java @@ -1,17 +1,16 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.util.ArrayList; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java index 098aba90..b5cb7df4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java @@ -1,111 +1,125 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.util.ArrayList; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodNode; - -import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.util.ArrayList; +import java.util.concurrent.atomic.AtomicBoolean; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * Simply shows all the non-empty strings in every single class - * + * * @author Konloch - * */ - public class ShowAllStrings extends Plugin { + @Override + public void execute(final ArrayList classNodeList) { + final PluginConsole frame = new PluginConsole("Show All Strings"); + final AtomicBoolean complete = new AtomicBoolean(false); + final Thread backgroundThread = new Thread() { + public void run() { + try { + for (ClassNode classNode : classNodeList) { + for (Object o : classNode.fields.toArray()) { + FieldNode f = (FieldNode) o; + Object v = f.value; + if (v instanceof String) { + String s = (String) v; + if (!s.isEmpty()) { + frame.appendText(String.format("%s.%s%s -> \"%s\"", classNode.name, f.name, f.desc, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r"))); + } + } + if (v instanceof String[]) { + for (int i = 0; i < ((String[]) v).length; i++) { + String s = ((String[]) v)[i]; + if (!s.isEmpty()) { + frame.appendText(String.format("%s.%s%s[%s] -> \"%s\"", classNode.name, f.name, f.desc, i, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r"))); + } + } + } + } + for (Object o : classNode.methods.toArray()) { + MethodNode m = (MethodNode) o; + InsnList iList = m.instructions; + for (AbstractInsnNode a : iList.toArray()) { + if (a instanceof LdcInsnNode) { + if (((LdcInsnNode) a).cst instanceof String) { + final String s = (String) ((LdcInsnNode) a).cst; + if (!s.isEmpty()) { + frame.appendText(String.format("%s.%s%s -> \"%s\"", classNode.name, m.name, m.desc, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r"))); + } + } + } + } + } + } + } catch (Exception e) { + new ExceptionUI(e, "konloch@gmail.com"); + } finally { + complete.set(true); + } + } + }; + frame.setVisible(true); + frame.addWindowListener(new WindowListener() { + @Override + public void windowClosing(WindowEvent e) { + backgroundThread.stop(); + complete.set(true); + } - @Override - public void execute(ArrayList classNodeList) { - PluginConsole frame = new PluginConsole("Show All Strings"); - StringBuilder sb = new StringBuilder(); - for (ClassNode classNode : classNodeList) { - for (Object o : classNode.fields.toArray()) { - FieldNode f = (FieldNode) o; - Object v = f.value; - if (v instanceof String) { - String s = (String) v; - if (!s.isEmpty()) - sb.append(classNode.name - + "." - + f.name - + "" - + f.desc - + " -> \"" - + s.replaceAll("\\n", "\\\\n").replaceAll( - "\\r", "\\\\r") + "\"" - + BytecodeViewer.nl); - } - if (v instanceof String[]) { - for (int i = 0; i < ((String[]) v).length; i++) { - String s = ((String[]) v)[i]; - if (!s.isEmpty()) - sb.append(classNode.name - + "." - + f.name - + "" - + f.desc - + "[" - + i - + "] -> \"" - + s.replaceAll("\\n", "\\\\n").replaceAll( - "\\r", "\\\\r") + "\"" - + BytecodeViewer.nl); - } - } - } + @Override + public void windowOpened(WindowEvent e) { + } - for (Object o : classNode.methods.toArray()) { - MethodNode m = (MethodNode) o; + @Override + public void windowClosed(WindowEvent e) { + } - InsnList iList = m.instructions; - for (AbstractInsnNode a : iList.toArray()) { - if (a instanceof LdcInsnNode) { - if (((LdcInsnNode) a).cst instanceof String) { - final String s = (String) ((LdcInsnNode) a).cst; - if (!s.isEmpty()) - sb.append(classNode.name - + "." - + m.name - + "" - + m.desc - + " -> \"" - + s.replaceAll("\\n", "\\\\n") - .replaceAll("\\r", "\\\\r") - + "\"" + BytecodeViewer.nl); - } - } - } - } - } + @Override + public void windowIconified(WindowEvent e) { + } - frame.appendText(sb.toString()); - frame.setVisible(true); - } + @Override + public void windowDeiconified(WindowEvent e) { + } + @Override + public void windowActivated(WindowEvent e) { + } + + @Override + public void windowDeactivated(WindowEvent e) { + } + }); + backgroundThread.start(); + while (!complete.get()) ; + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java index 744358bf..b3d03d1f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java @@ -1,13 +1,12 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; -import java.util.ArrayList; - import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import java.util.ArrayList; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java index 10c2baca..86b74343 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java @@ -1,7 +1,6 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.Plugin; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java index a986f4ff..f982fae2 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java @@ -1,19 +1,17 @@ package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import org.objectweb.asm.tree.ClassNode; - import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.PluginConsole; +import javax.swing.JDialog; +import javax.swing.JOptionPane; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; -import javax.swing.JDialog; -import javax.swing.JOptionPane; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java index f1588a73..7b7cfd58 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java @@ -1,5 +1,11 @@ package the.bytecode.club.bytecodeviewer.plugin.strategies; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + import java.io.File; import java.io.FileInputStream; import java.util.HashMap; @@ -9,13 +15,6 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.tree.ClassNode; - -import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.api.Plugin; -import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; - /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java index 908306f6..c763c300 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java @@ -1,15 +1,14 @@ package the.bytecode.club.bytecodeviewer.plugin.strategies; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java index c82f7846..40642b7c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java @@ -1,14 +1,12 @@ package the.bytecode.club.bytecodeviewer.plugin.strategies; -import java.io.File; - -import me.konloch.kontainer.io.DiskReader; - +import org.apache.commons.io.FileUtils; import org.codehaus.janino.SimpleCompiler; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; +import java.io.File; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * @@ -38,7 +36,7 @@ public class JavaPluginLaunchStrategy implements PluginLaunchStrategy { @Override public Plugin run(File file) throws Throwable { - compiler.cook(DiskReader.loadAsString(file.getAbsolutePath())); + compiler.cook(FileUtils.readFileToString(file, "UTF-8")); System.out.println(file.getName().substring(0,(int)(file.getName().length()-(".java".length())))); Class clazz = (Class) Class.forName( diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java index faf70d96..6e07e1c4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java @@ -1,15 +1,14 @@ package the.bytecode.club.bytecodeviewer.plugin.strategies; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java index 274076e6..125a7135 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java @@ -1,15 +1,14 @@ package the.bytecode.club.bytecodeviewer.plugin.strategies; -import java.io.File; -import java.io.FileReader; -import java.io.Reader; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; - import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/FieldCallSearch.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/FieldCallSearch.java index 12068ab9..85ca95fc 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/FieldCallSearch.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/FieldCallSearch.java @@ -1,13 +1,6 @@ package the.bytecode.club.bytecodeviewer.searching; -import java.awt.GridLayout; -import java.util.Iterator; -import java.util.ListIterator; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - +import eu.bibl.banalysis.asm.desc.OpcodeInfo; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -15,7 +8,12 @@ import org.objectweb.asm.tree.FieldInsnNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.MethodNode; -import eu.bibl.banalysis.asm.desc.OpcodeInfo; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.GridLayout; +import java.util.Iterator; +import java.util.ListIterator; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/LDCSearch.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/LDCSearch.java index 9d0c6123..ca30598d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/LDCSearch.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/LDCSearch.java @@ -1,13 +1,5 @@ package the.bytecode.club.bytecodeviewer.searching; -import java.awt.GridLayout; -import java.util.Iterator; -import java.util.ListIterator; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -16,6 +8,13 @@ import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodNode; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.GridLayout; +import java.util.Iterator; +import java.util.ListIterator; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/MethodCallSearch.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/MethodCallSearch.java index 9e8ac555..fa7b9ce0 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/MethodCallSearch.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/MethodCallSearch.java @@ -1,13 +1,6 @@ package the.bytecode.club.bytecodeviewer.searching; -import java.awt.GridLayout; -import java.util.Iterator; -import java.util.ListIterator; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - +import eu.bibl.banalysis.asm.desc.OpcodeInfo; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -15,7 +8,12 @@ import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; -import eu.bibl.banalysis.asm.desc.OpcodeInfo; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.GridLayout; +import java.util.Iterator; +import java.util.ListIterator; /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java index 114fb752..0ee50067 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java @@ -1,13 +1,5 @@ package the.bytecode.club.bytecodeviewer.searching; -import java.rmi.UnexpectedException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldInsnNode; @@ -21,403 +13,413 @@ import org.objectweb.asm.tree.MultiANewArrayInsnNode; import org.objectweb.asm.tree.TypeInsnNode; import org.objectweb.asm.tree.VarInsnNode; +import java.rmi.UnexpectedException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * - * * + * * * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * ***************************************************************************/ /** * An instruction finder that finds regex patterns in a method's instruction * list and returns an array with the found instructions. - * + * * @author Frédéric Hannes - * + * */ public class RegexInsnFinder { - private static String[] opcodes = new String[] { "NOP", "ACONST_NULL", - "ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3", - "ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0", - "FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH", - "LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD", - "ALOAD", "ILOAD_0", "ILOAD_1", "ILOAD_2", "ILOAD_3", "LLOAD_0", - "LLOAD_1", "LLOAD_2", "LLOAD_3", "FLOAD_0", "FLOAD_1", "FLOAD_2", - "FLOAD_3", "DLOAD_0", "DLOAD_1", "DLOAD_2", "DLOAD_3", "ALOAD_0", - "ALOAD_1", "ALOAD_2", "ALOAD_3", "IALOAD", "LALOAD", "FALOAD", - "DALOAD", "AALOAD", "BALOAD", "CALOAD", "SALOAD", "ISTORE", - "LSTORE", "FSTORE", "DSTORE", "ASTORE", "ISTORE_0", "ISTORE_1", - "ISTORE_2", "ISTORE_3", "LSTORE_0", "LSTORE_1", "LSTORE_2", - "LSTORE_3", "FSTORE_0", "FSTORE_1", "FSTORE_2", "FSTORE_3", - "DSTORE_0", "DSTORE_1", "DSTORE_2", "DSTORE_3", "ASTORE_0", - "ASTORE_1", "ASTORE_2", "ASTORE_3", "IASTORE", "LASTORE", - "FASTORE", "DASTORE", "AASTORE", "BASTORE", "CASTORE", "SASTORE", - "POP", "POP2", "DUP", "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", - "DUP2_X2", "SWAP", "IADD", "LADD", "FADD", "DADD", "ISUB", "LSUB", - "FSUB", "DSUB", "IMUL", "LMUL", "FMUL", "DMUL", "IDIV", "LDIV", - "FDIV", "DDIV", "IREM", "LREM", "FREM", "DREM", "INEG", "LNEG", - "FNEG", "DNEG", "ISHL", "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", - "IAND", "LAND", "IOR", "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", - "I2D", "L2I", "L2F", "L2D", "F2I", "F2L", "F2D", "D2I", "D2L", - "D2F", "I2B", "I2C", "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", - "DCMPG", "IFEQ", "IFNE", "IFLT", "IFGE", "IFGT", "IFLE", - "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", - "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE", "GOTO", "JSR", "RET", - "TABLESWITCH", "LOOKUPSWITCH", "IRETURN", "LRETURN", "FRETURN", - "DRETURN", "ARETURN", "RETURN", "GETSTATIC", "PUTSTATIC", - "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", "INVOKESPECIAL", - "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC", "NEW", - "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", "ATHROW", "CHECKCAST", - "INSTANCEOF", "MONITORENTER", "MONITOREXIT", "WIDE", - "MULTIANEWARRAY", "IFNULL", "IFNONNULL", "GOTO_W", "JSR_W" }; + private static String[] opcodes = new String[]{"NOP", "ACONST_NULL", + "ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3", + "ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0", + "FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH", + "LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD", + "ALOAD", "ILOAD_0", "ILOAD_1", "ILOAD_2", "ILOAD_3", "LLOAD_0", + "LLOAD_1", "LLOAD_2", "LLOAD_3", "FLOAD_0", "FLOAD_1", "FLOAD_2", + "FLOAD_3", "DLOAD_0", "DLOAD_1", "DLOAD_2", "DLOAD_3", "ALOAD_0", + "ALOAD_1", "ALOAD_2", "ALOAD_3", "IALOAD", "LALOAD", "FALOAD", + "DALOAD", "AALOAD", "BALOAD", "CALOAD", "SALOAD", "ISTORE", + "LSTORE", "FSTORE", "DSTORE", "ASTORE", "ISTORE_0", "ISTORE_1", + "ISTORE_2", "ISTORE_3", "LSTORE_0", "LSTORE_1", "LSTORE_2", + "LSTORE_3", "FSTORE_0", "FSTORE_1", "FSTORE_2", "FSTORE_3", + "DSTORE_0", "DSTORE_1", "DSTORE_2", "DSTORE_3", "ASTORE_0", + "ASTORE_1", "ASTORE_2", "ASTORE_3", "IASTORE", "LASTORE", + "FASTORE", "DASTORE", "AASTORE", "BASTORE", "CASTORE", "SASTORE", + "POP", "POP2", "DUP", "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", + "DUP2_X2", "SWAP", "IADD", "LADD", "FADD", "DADD", "ISUB", "LSUB", + "FSUB", "DSUB", "IMUL", "LMUL", "FMUL", "DMUL", "IDIV", "LDIV", + "FDIV", "DDIV", "IREM", "LREM", "FREM", "DREM", "INEG", "LNEG", + "FNEG", "DNEG", "ISHL", "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", + "IAND", "LAND", "IOR", "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", + "I2D", "L2I", "L2F", "L2D", "F2I", "F2L", "F2D", "D2I", "D2L", + "D2F", "I2B", "I2C", "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", + "DCMPG", "IFEQ", "IFNE", "IFLT", "IFGE", "IFGT", "IFLE", + "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", + "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE", "GOTO", "JSR", "RET", + "TABLESWITCH", "LOOKUPSWITCH", "IRETURN", "LRETURN", "FRETURN", + "DRETURN", "ARETURN", "RETURN", "GETSTATIC", "PUTSTATIC", + "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", "INVOKESPECIAL", + "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC", "NEW", + "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", "ATHROW", "CHECKCAST", + "INSTANCEOF", "MONITORENTER", "MONITOREXIT", "WIDE", + "MULTIANEWARRAY", "IFNULL", "IFNONNULL", "GOTO_W", "JSR_W"}; - private static String[] opcodesVar = new String[] { "ILOAD", "LLOAD", - "FLOAD", "DLOAD", "ALOAD", "ISTORE", "LSTORE", "FSTORE", "DSTORE", - "ASTORE", "RET" }; - private static String opcodeVars = buildRegexItems(opcodesVar); + private static String[] opcodesVar = new String[]{"ILOAD", "LLOAD", + "FLOAD", "DLOAD", "ALOAD", "ISTORE", "LSTORE", "FSTORE", "DSTORE", + "ASTORE", "RET"}; + private static String opcodeVars = buildRegexItems(opcodesVar); - private static String[] opcodesInt = new String[] { "BIPUSH", "SIPUSH", - "NEWARRAY" }; - private static String opcodesInts = buildRegexItems(opcodesInt); + private static String[] opcodesInt = new String[]{"BIPUSH", "SIPUSH", + "NEWARRAY"}; + private static String opcodesInts = buildRegexItems(opcodesInt); - private static String[] opcodesField = new String[] { "GETSTATIC", - "PUTSTATIC", "GETFIELD", "PUTFIELD" }; - private static String opcodesFields = buildRegexItems(opcodesField); + private static String[] opcodesField = new String[]{"GETSTATIC", + "PUTSTATIC", "GETFIELD", "PUTFIELD"}; + private static String opcodesFields = buildRegexItems(opcodesField); - private static String[] opcodesMethod = new String[] { "INVOKEVIRTUAL", - "INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC" }; - private static String opcodesMethods = buildRegexItems(opcodesMethod); + private static String[] opcodesMethod = new String[]{"INVOKEVIRTUAL", + "INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC"}; + private static String opcodesMethods = buildRegexItems(opcodesMethod); - private static String[] opcodesType = new String[] { "NEW", "ANEWARRAY", - "ARRAYLENGTH", "CHECKCAST", "INSTANCEOF" }; - private static String opcodesTypes = buildRegexItems(opcodesType); + private static String[] opcodesType = new String[]{"NEW", "ANEWARRAY", + "ARRAYLENGTH", "CHECKCAST", "INSTANCEOF"}; + private static String opcodesTypes = buildRegexItems(opcodesType); - private static String[] opcodesIf = new String[] { "IFEQ", "IFNE", "IFLT", - "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", - "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE" }; - private static String opcodesIfs = buildRegexItems(opcodesIf, false, false); + private static String[] opcodesIf = new String[]{"IFEQ", "IFNE", "IFLT", + "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", + "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE"}; + private static String opcodesIfs = buildRegexItems(opcodesIf, false, false); - private static String[] opcodesAny = new String[] { "NOP", "ACONST_NULL", - "ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3", - "ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0", - "FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH", - "LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD", - "ALOAD", "IALOAD", "LALOAD", "FALOAD", "DALOAD", "AALOAD", - "BALOAD", "CALOAD", "SALOAD", "ISTORE", "LSTORE", "FSTORE", - "DSTORE", "ASTORE", "IASTORE", "LASTORE", "FASTORE", "DASTORE", - "AASTORE", "BASTORE", "CASTORE", "SASTORE", "POP", "POP2", "DUP", - "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", "DUP2_X2", "SWAP", "IADD", - "LADD", "FADD", "DADD", "ISUB", "LSUB", "FSUB", "DSUB", "IMUL", - "LMUL", "FMUL", "DMUL", "IDIV", "LDIV", "FDIV", "DDIV", "IREM", - "LREM", "FREM", "DREM", "INEG", "LNEG", "FNEG", "DNEG", "ISHL", - "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", "IAND", "LAND", "IOR", - "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", "I2D", "L2I", "L2F", - "L2D", "F2I", "F2L", "F2D", "D2I", "D2L", "D2F", "I2B", "I2C", - "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", "DCMPG", "IFEQ", "IFNE", - "IFLT", "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", - "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", - "IF_ACMPNE", "GOTO", "JSR", "RET", "TABLESWITCH", "LOOKUPSWITCH", - "IRETURN", "LRETURN", "FRETURN", "DRETURN", "ARETURN", "RETURN", - "GETSTATIC", "PUTSTATIC", "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", - "INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", - "INVOKEDYNAMIC", "NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", - "ATHROW", "CHECKCAST", "INSTANCEOF", "MONITORENTER", "MONITOREXIT", - "MULTIANEWARRAY", "IFNULL", "IFNONNULL" }; - private static String opcodesAnys = buildRegexItems(opcodesAny, false, - false); + private static String[] opcodesAny = new String[]{"NOP", "ACONST_NULL", + "ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3", + "ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0", + "FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH", + "LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD", + "ALOAD", "IALOAD", "LALOAD", "FALOAD", "DALOAD", "AALOAD", + "BALOAD", "CALOAD", "SALOAD", "ISTORE", "LSTORE", "FSTORE", + "DSTORE", "ASTORE", "IASTORE", "LASTORE", "FASTORE", "DASTORE", + "AASTORE", "BASTORE", "CASTORE", "SASTORE", "POP", "POP2", "DUP", + "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", "DUP2_X2", "SWAP", "IADD", + "LADD", "FADD", "DADD", "ISUB", "LSUB", "FSUB", "DSUB", "IMUL", + "LMUL", "FMUL", "DMUL", "IDIV", "LDIV", "FDIV", "DDIV", "IREM", + "LREM", "FREM", "DREM", "INEG", "LNEG", "FNEG", "DNEG", "ISHL", + "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", "IAND", "LAND", "IOR", + "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", "I2D", "L2I", "L2F", + "L2D", "F2I", "F2L", "F2D", "D2I", "D2L", "D2F", "I2B", "I2C", + "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", "DCMPG", "IFEQ", "IFNE", + "IFLT", "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", + "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", + "IF_ACMPNE", "GOTO", "JSR", "RET", "TABLESWITCH", "LOOKUPSWITCH", + "IRETURN", "LRETURN", "FRETURN", "DRETURN", "ARETURN", "RETURN", + "GETSTATIC", "PUTSTATIC", "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", + "INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", + "INVOKEDYNAMIC", "NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", + "ATHROW", "CHECKCAST", "INSTANCEOF", "MONITORENTER", "MONITOREXIT", + "MULTIANEWARRAY", "IFNULL", "IFNONNULL"}; + private static String opcodesAnys = buildRegexItems(opcodesAny, false, + false); - private static String buildRegexItems(final String[] items, - final boolean capture, final boolean stdRepl) { - if (items.length == 0) - return "()"; - String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:") - + items[0]; - for (int i = 1; i < items.length; i++) { - result += "|" + items[i]; - } - result += ")"; - return result; - } + private static String buildRegexItems(final String[] items, + final boolean capture, final boolean stdRepl) { + if (items.length == 0) + return "()"; + String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:") + + items[0]; + for (int i = 1; i < items.length; i++) { + result += "|" + items[i]; + } + result += ")"; + return result; + } - private static String buildRegexItems(final String[] items) { - return buildRegexItems(items, true, true); - } + private static String buildRegexItems(final String[] items) { + return buildRegexItems(items, true, true); + } - public static String processRegex(final String regex) { - String result = regex.trim(); - result = result.replaceAll("\\bANYINSN *", opcodesAnys); - result = result.replaceAll(opcodesInts - + "\\\\\\{\\s*(\\d+)\\s*\\\\\\} *", "$1\\\\{$2\\\\} "); - result = result.replaceAll(opcodesInts + " *", "$1\\\\{\\\\d+\\\\} "); - result = result.replaceAll( - "\\bLDC\\\\\\{(.*?)\\\\\\}(? il = new ArrayList(); + public RegexInsnFinder(final ClassNode clazz, final MethodNode method) { + setMethod(clazz, method); + } - final Iterator iIt = insnList.iterator(); - while (iIt.hasNext()) { - final AbstractInsnNode node = iIt.next(); - if (node.getOpcode() >= 0) { - il.add(node); - } - } - return il.toArray(new AbstractInsnNode[il.size()]); - } + private AbstractInsnNode[] cleanInsn(final InsnList insnList) { + final List il = new ArrayList(); - /** - * Refreshes the internal instruction list when you have made changes to the - * method. - */ - public void refresh() { - origInstructions = cleanInsn(mn.instructions); - final List il = new ArrayList(); - for (final AbstractInsnNode ain : mn.instructions.toArray()) - if (ain.getOpcode() >= 0) { - il.add(ain); - } - instructions = il.toArray(new AbstractInsnNode[il.size()]); - offsets = new int[instructions.length]; - insnString = ""; - for (int i = 0; i < instructions.length; i++) { - offsets[i] = -1; - final AbstractInsnNode ain = instructions[i]; - if (ain.getOpcode() >= 0) { - if (ain.getOpcode() >= opcodes.length) { - try { - throw new UnexpectedException( - "Unknown opcode encountered: " - + ain.getOpcode()); - } catch (final UnexpectedException e) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); - } - } - offsets[i] = insnString.length(); - insnString += opcodes[ain.getOpcode()]; - switch (ain.getType()) { - case AbstractInsnNode.INT_INSN: - final IntInsnNode iin = (IntInsnNode) ain; - insnString += "{" + iin.operand + "}"; - break; - case AbstractInsnNode.LDC_INSN: - final LdcInsnNode lin = (LdcInsnNode) ain; - insnString += "{" + lin.cst.toString().replace("}", "\\}") - + "}"; - break; - case AbstractInsnNode.VAR_INSN: - final VarInsnNode vin = (VarInsnNode) ain; - insnString += "_" + vin.var; - break; - case AbstractInsnNode.IINC_INSN: - final IincInsnNode iiin = (IincInsnNode) ain; - insnString += "{" + iiin.var + "," + iiin.incr + "}"; - break; - case AbstractInsnNode.FIELD_INSN: - final FieldInsnNode fin = (FieldInsnNode) ain; - insnString += "{" + fin.desc + "," + fin.owner + "," - + fin.name + "}"; - break; - case AbstractInsnNode.METHOD_INSN: - final MethodInsnNode min = (MethodInsnNode) ain; - insnString += "{" + min.desc + "," + min.owner + "," - + min.name + "}"; - break; - case AbstractInsnNode.TYPE_INSN: - final TypeInsnNode tin = (TypeInsnNode) ain; - insnString += "{" + tin.desc + "}"; - break; - case AbstractInsnNode.MULTIANEWARRAY_INSN: - final MultiANewArrayInsnNode manain = (MultiANewArrayInsnNode) ain; - insnString += "{" + manain.dims + "," + manain.desc + "}"; - break; - } - insnString += " "; - } - } - } + final Iterator iIt = insnList.iterator(); + while (iIt.hasNext()) { + final AbstractInsnNode node = iIt.next(); + if (node.getOpcode() >= 0) { + il.add(node); + } + } + return il.toArray(new AbstractInsnNode[il.size()]); + } - public void setMethod(final ClassNode ci, final MethodNode mi) { - this.mn = mi; - refresh(); - } + /** + * Refreshes the internal instruction list when you have made changes to the + * method. + */ + public void refresh() { + origInstructions = cleanInsn(mn.instructions); + final List il = new ArrayList(); + for (final AbstractInsnNode ain : mn.instructions.toArray()) + if (ain.getOpcode() >= 0) { + il.add(ain); + } + instructions = il.toArray(new AbstractInsnNode[il.size()]); + offsets = new int[instructions.length]; + insnString = ""; + for (int i = 0; i < instructions.length; i++) { + offsets[i] = -1; + final AbstractInsnNode ain = instructions[i]; + if (ain.getOpcode() >= 0) { + if (ain.getOpcode() >= opcodes.length) { + try { + throw new UnexpectedException( + "Unknown opcode encountered: " + + ain.getOpcode()); + } catch (final UnexpectedException e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } + } + offsets[i] = insnString.length(); + insnString += opcodes[ain.getOpcode()]; + switch (ain.getType()) { + case AbstractInsnNode.INT_INSN: + final IntInsnNode iin = (IntInsnNode) ain; + insnString += "{" + iin.operand + "}"; + break; + case AbstractInsnNode.LDC_INSN: + final LdcInsnNode lin = (LdcInsnNode) ain; + insnString += "{" + lin.cst.toString().replace("}", "\\}") + + "}"; + break; + case AbstractInsnNode.VAR_INSN: + final VarInsnNode vin = (VarInsnNode) ain; + insnString += "_" + vin.var; + break; + case AbstractInsnNode.IINC_INSN: + final IincInsnNode iiin = (IincInsnNode) ain; + insnString += "{" + iiin.var + "," + iiin.incr + "}"; + break; + case AbstractInsnNode.FIELD_INSN: + final FieldInsnNode fin = (FieldInsnNode) ain; + insnString += "{" + fin.desc + "," + fin.owner + "," + + fin.name + "}"; + break; + case AbstractInsnNode.METHOD_INSN: + final MethodInsnNode min = (MethodInsnNode) ain; + insnString += "{" + min.desc + "," + min.owner + "," + + min.name + "}"; + break; + case AbstractInsnNode.TYPE_INSN: + final TypeInsnNode tin = (TypeInsnNode) ain; + insnString += "{" + tin.desc + "}"; + break; + case AbstractInsnNode.MULTIANEWARRAY_INSN: + final MultiANewArrayInsnNode manain = (MultiANewArrayInsnNode) ain; + insnString += "{" + manain.dims + "," + manain.desc + "}"; + break; + default: + throw new IllegalArgumentException(String.valueOf(ain.getType())); + } + insnString += " "; + } + } + } - private AbstractInsnNode[] makeResult(final int start, final int end) { - int startIndex = 0; - int endIndex = -1; - for (int i = 0; i < offsets.length - 1; i++) { - final int offset = offsets[i]; - if (offset == start) { - startIndex = i; - } - if ((offset < end) && (offsets[i + 1] >= end)) { - endIndex = i; - break; - } - } - if (endIndex == -1) { - endIndex = offsets.length - 1; - } - final int length = endIndex - startIndex + 1; - final AbstractInsnNode[] result = new AbstractInsnNode[length]; - System.arraycopy(origInstructions, startIndex, result, 0, length); - return result; - } + public void setMethod(final ClassNode ci, final MethodNode mi) { + this.mn = mi; + refresh(); + } - /** - * Searches for a regex in the instruction list and returns the first match. - * - * @param regex - * the regular expression - * @return the matching instructions - */ - public AbstractInsnNode[] find(final String regex) { - try { - final Matcher regexMatcher = Pattern.compile(processRegex(regex), - Pattern.MULTILINE).matcher(insnString); - if (regexMatcher.find()) - return makeResult(regexMatcher.start(), regexMatcher.end()); - } catch (final PatternSyntaxException ex) { - //ignore, they fucked up regex - } - return new AbstractInsnNode[0]; - } + private AbstractInsnNode[] makeResult(final int start, final int end) { + int startIndex = 0; + int endIndex = -1; + for (int i = 0; i < offsets.length - 1; i++) { + final int offset = offsets[i]; + if (offset == start) { + startIndex = i; + } + if ((offset < end) && (offsets[i + 1] >= end)) { + endIndex = i; + break; + } + } + if (endIndex == -1) { + endIndex = offsets.length - 1; + } + final int length = endIndex - startIndex + 1; + final AbstractInsnNode[] result = new AbstractInsnNode[length]; + System.arraycopy(origInstructions, startIndex, result, 0, length); + return result; + } - /** - * Searches a regex in an instruction list and returns all matches. - * - * @param regex - * the regular expression - * @return a list with all sets of matching instructions - */ - public List findAll(final String regex) { - final List results = new ArrayList(); - try { - final Matcher regexMatcher = Pattern.compile(processRegex(regex), - Pattern.MULTILINE).matcher(insnString); - while (regexMatcher.find()) { - results.add(makeResult(regexMatcher.start(), regexMatcher.end())); - } - } catch (final PatternSyntaxException ex) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); - } - return results; - } + /** + * Searches for a regex in the instruction list and returns the first match. + * + * @param regex + * the regular expression + * @return the matching instructions + */ + public AbstractInsnNode[] find(final String regex) { + try { + final Matcher regexMatcher = Pattern.compile(processRegex(regex), + Pattern.MULTILINE).matcher(insnString); + if (regexMatcher.find()) + return makeResult(regexMatcher.start(), regexMatcher.end()); + } catch (final PatternSyntaxException ex) { + //ignore, they fucked up regex + } + return new AbstractInsnNode[0]; + } - /** - * Searches for a regex in the instruction list and returns all groups for - * the first match. - * - * @param regex - * the regular expression - * @return the groups with matching instructions - */ - public AbstractInsnNode[][] findGroups(final String regex) { - try { - final Matcher regexMatcher = Pattern.compile(processRegex(regex), - Pattern.MULTILINE).matcher(insnString); - if (regexMatcher.find()) { - final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher - .groupCount() + 1][0]; - for (int i = 0; i <= regexMatcher.groupCount(); i++) { - result[i] = makeResult(regexMatcher.start(i), - regexMatcher.end(i)); - } - return result; - } - } catch (final PatternSyntaxException ex) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); - } - return new AbstractInsnNode[0][0]; - } + /** + * Searches a regex in an instruction list and returns all matches. + * + * @param regex + * the regular expression + * @return a list with all sets of matching instructions + */ + public List findAll(final String regex) { + final List results = new ArrayList(); + try { + final Matcher regexMatcher = Pattern.compile(processRegex(regex), + Pattern.MULTILINE).matcher(insnString); + while (regexMatcher.find()) { + results.add(makeResult(regexMatcher.start(), regexMatcher.end())); + } + } catch (final PatternSyntaxException ex) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); + } + return results; + } - /** - * Searches for a regex in the instruction list and returns all groups for - * all matches. - * - * @param regex - * the regular expression - * @return a list with all sets of groups with matching instructions - */ - public List findAllGroups(final String regex) { - final List results = new ArrayList(); - try { - final Matcher regexMatcher = Pattern.compile(processRegex(regex), - Pattern.MULTILINE).matcher(insnString); - if (regexMatcher.find()) { - final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher - .groupCount() + 1][0]; - for (int i = 0; i <= regexMatcher.groupCount(); i++) { - result[i] = makeResult(regexMatcher.start(i), - regexMatcher.end(i)); - } - results.add(result); - } - } catch (final PatternSyntaxException ex) { - new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); - } - return results; - } + /** + * Searches for a regex in the instruction list and returns all groups for + * the first match. + * + * @param regex + * the regular expression + * @return the groups with matching instructions + */ + public AbstractInsnNode[][] findGroups(final String regex) { + try { + final Matcher regexMatcher = Pattern.compile(processRegex(regex), + Pattern.MULTILINE).matcher(insnString); + if (regexMatcher.find()) { + final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher + .groupCount() + 1][0]; + for (int i = 0; i <= regexMatcher.groupCount(); i++) { + result[i] = makeResult(regexMatcher.start(i), + regexMatcher.end(i)); + } + return result; + } + } catch (final PatternSyntaxException ex) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); + } + return new AbstractInsnNode[0][0]; + } + + /** + * Searches for a regex in the instruction list and returns all groups for + * all matches. + * + * @param regex + * the regular expression + * @return a list with all sets of groups with matching instructions + */ + public List findAllGroups(final String regex) { + final List results = new ArrayList(); + try { + final Matcher regexMatcher = Pattern.compile(processRegex(regex), + Pattern.MULTILINE).matcher(insnString); + if (regexMatcher.find()) { + final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher + .groupCount() + 1][0]; + for (int i = 0; i <= regexMatcher.groupCount(); i++) { + result[i] = makeResult(regexMatcher.start(i), + regexMatcher.end(i)); + } + results.add(result); + } + } catch (final PatternSyntaxException ex) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex); + } + return results; + } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexSearch.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexSearch.java index 366cab77..1bcd1c4c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexSearch.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/RegexSearch.java @@ -1,16 +1,15 @@ package the.bytecode.club.bytecodeviewer.searching; -import java.awt.GridLayout; -import java.util.Iterator; - -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.JTextField; - import org.objectweb.asm.Type; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.GridLayout; +import java.util.Iterator; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com * diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/searching/SearchTypeDetails.java b/src/main/java/the/bytecode/club/bytecodeviewer/searching/SearchTypeDetails.java index b9e95acc..27877d47 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/searching/SearchTypeDetails.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/searching/SearchTypeDetails.java @@ -1,9 +1,9 @@ package the.bytecode.club.bytecodeviewer.searching; -import javax.swing.JPanel; - import org.objectweb.asm.tree.ClassNode; +import javax.swing.JPanel; + /*************************************************************************** * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * * Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *