diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index cf0f71a7..338b82f6 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -271,7 +271,7 @@ public class BytecodeViewer while (empty) { showMessage("You need to set your Java path, this requires the JRE to be downloaded." + nl + "(C:/Program Files/Java/JDK_xx/bin/java.exe)"); - viewer.java(); + viewer.selectJava(); empty = Configuration.java.isEmpty(); } } @@ -620,7 +620,7 @@ public class BytecodeViewer * resets the recent files menu */ public static void resetRecentFilesMenu() { - viewer.mnRecentFiles.removeAll(); + viewer.recentFilesSecondaryMenu.removeAll(); for (String s : recentFiles) if (!s.isEmpty()) { JMenuItem m = new JMenuItem(s); @@ -628,7 +628,7 @@ public class BytecodeViewer JMenuItem m12 = (JMenuItem) e.getSource(); openFiles(new File[]{new File(m12.getText())}, true); }); - viewer.mnRecentFiles.add(m); + viewer.recentFilesSecondaryMenu.add(m); } viewer.mnRecentPlugins.removeAll(); for (String s : recentPlugins) @@ -805,17 +805,17 @@ public class BytecodeViewer boolean passes = false; - if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel())) + if (BytecodeViewer.viewer.viewPane1.getGroup().isSelected(BytecodeViewer.viewer.viewPane1.getKrakatau().getJava().getModel())) passes = true; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel())) + else if (BytecodeViewer.viewer.viewPane1.getGroup().isSelected(BytecodeViewer.viewer.viewPane1.getKrakatau().getBytecode().getModel())) passes = true; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel())) + else if (BytecodeViewer.viewer.viewPane2.getGroup().isSelected(BytecodeViewer.viewer.viewPane2.getKrakatau().getJava().getModel())) passes = true; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel())) + else if (BytecodeViewer.viewer.viewPane2.getGroup().isSelected(BytecodeViewer.viewer.viewPane2.getKrakatau().getBytecode().getModel())) passes = true; - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel())) + else if (BytecodeViewer.viewer.viewPane3.getGroup().isSelected(BytecodeViewer.viewer.viewPane3.getKrakatau().getJava().getModel())) passes = true; - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel())) + else if (BytecodeViewer.viewer.viewPane3.getGroup().isSelected(BytecodeViewer.viewer.viewPane3.getKrakatau().getBytecode().getModel())) passes = true; if (Configuration.krakatauTempJar != null || !passes) { diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java index 9eb4894f..240ebbcc 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java @@ -196,81 +196,10 @@ public class Settings { "deprecated", false); DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.isSelected()), false); - - if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel())) - DiskWriter.writeNewLine(settingsName, "0", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel())) - DiskWriter.writeNewLine(settingsName, "1", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel())) - DiskWriter.writeNewLine(settingsName, "2", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel())) - DiskWriter.writeNewLine(settingsName, "3", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "4", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel())) - DiskWriter.writeNewLine(settingsName, "5", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel())) - DiskWriter.writeNewLine(settingsName, "6", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel())) - DiskWriter.writeNewLine(settingsName, "7", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "8", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1JDGUI.getModel())) - DiskWriter.writeNewLine(settingsName, "9", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.jadxJ1.getModel())) - DiskWriter.writeNewLine(settingsName, "10", false); - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.asmText1.getModel())) - DiskWriter.writeNewLine(settingsName, "11", false); - - if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel())) - DiskWriter.writeNewLine(settingsName, "0", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel())) - DiskWriter.writeNewLine(settingsName, "1", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel())) - DiskWriter.writeNewLine(settingsName, "2", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel())) - DiskWriter.writeNewLine(settingsName, "3", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "4", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel())) - DiskWriter.writeNewLine(settingsName, "5", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel())) - DiskWriter.writeNewLine(settingsName, "6", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel())) - DiskWriter.writeNewLine(settingsName, "7", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "8", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2JDGUI.getModel())) - DiskWriter.writeNewLine(settingsName, "9", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.jadxJ2.getModel())) - DiskWriter.writeNewLine(settingsName, "10", false); - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.asmText2.getModel())) - DiskWriter.writeNewLine(settingsName, "11", false); - - if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel())) - DiskWriter.writeNewLine(settingsName, "0", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel())) - DiskWriter.writeNewLine(settingsName, "1", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3CFR.getModel())) - DiskWriter.writeNewLine(settingsName, "2", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Fern.getModel())) - DiskWriter.writeNewLine(settingsName, "3", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "4", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel())) - DiskWriter.writeNewLine(settingsName, "5", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel())) - DiskWriter.writeNewLine(settingsName, "6", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel())) - DiskWriter.writeNewLine(settingsName, "7", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel())) - DiskWriter.writeNewLine(settingsName, "8", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3JDGUI.getModel())) - DiskWriter.writeNewLine(settingsName, "9", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.jadxJ3.getModel())) - DiskWriter.writeNewLine(settingsName, "10", false); - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.asmText3.getModel())) - DiskWriter.writeNewLine(settingsName, "11", false); + + DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.viewPane1.getSelectedViewer()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.viewPane2.getSelectedViewer()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.viewPane3.getSelectedViewer()), false); DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false); @@ -287,35 +216,35 @@ public class Settings { DiskWriter.writeNewLine(settingsName, Configuration.rt, false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1Proc_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getProcyon().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1CFR_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getCFR().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1Fern_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getFern().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1Krakatau_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getKrakatau().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1Smali_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getSmali().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2Proc_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getProcyon().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2CFR_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getCFR().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2Fern_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getFern().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2Krakatau_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getKrakatau().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2Smali_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getSmali().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3Proc_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getProcyon().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3CFR_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getCFR().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3Fern_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getFern().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3Krakatau_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getKrakatau().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3Smali_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getSmali().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.decodeAPKResources.isSelected()), false); DiskWriter.writeNewLine(settingsName, @@ -323,11 +252,11 @@ public class Settings { DiskWriter.writeNewLine(settingsName, String.valueOf(Configuration.pingback), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel1JDGUI_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane1.getJD().getEditable().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel2JDGUI_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane2.getJD().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, - String.valueOf(BytecodeViewer.viewer.panel3JDGUI_E.isSelected()), false); + String.valueOf(BytecodeViewer.viewer.viewPane3.getJD().getJava().isSelected()), false); DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.fontSpinner.getValue()), false); DiskWriter.writeNewLine(settingsName, @@ -360,6 +289,8 @@ public class Settings { String.valueOf(BytecodeViewer.viewer.showClassMethods.isSelected()), false); DiskWriter.writeNewLine(settingsName, String.valueOf(BytecodeViewer.viewer.ren.isSelected()), false); + DiskWriter.writeNewLine(settingsName, + String.valueOf(BytecodeViewer.viewer.viewPane1.getJADX().getEditable().isSelected()), false); } catch (Exception e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } @@ -447,83 +378,9 @@ public class Settings { BytecodeViewer.viewer.debugHelpers.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 78, false))); //79 is deprecated BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 80, false))); - int decompiler = Integer.parseInt(DiskReader.loadString(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); - else if (decompiler == 10) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.jadxJ1.getModel(), true); - else if (decompiler == 11) - BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.asmText1.getModel(), true); - - decompiler = Integer.parseInt(DiskReader.loadString(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); - else if (decompiler == 10) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.jadxJ2.getModel(), true); - else if (decompiler == 11) - BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.asmText2.getModel(), true); - - decompiler = Integer.parseInt(DiskReader.loadString(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); - else if (decompiler == 10) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.jadxJ3.getModel(), true); - else if (decompiler == 11) - BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.asmText3.getModel(), true); + BytecodeViewer.viewer.viewPane1.setSelectedViewer(getInt(81)); + BytecodeViewer.viewer.viewPane2.setSelectedViewer(getInt(82)); + BytecodeViewer.viewer.viewPane3.setSelectedViewer(getInt(83)); BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 84, false))); @@ -537,51 +394,62 @@ public class Settings { Configuration.lastDirectory = DiskReader.loadString(settingsName, 88, false); Configuration.python = DiskReader.loadString(settingsName, 89, false); Configuration.rt = DiskReader.loadString(settingsName, 90, false); - BytecodeViewer.viewer.panel1Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 91, false))); - BytecodeViewer.viewer.panel1CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 92, false))); - BytecodeViewer.viewer.panel1Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 93, false))); - BytecodeViewer.viewer.panel1Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 94, false))); - BytecodeViewer.viewer.panel1Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 95, false))); - BytecodeViewer.viewer.panel2Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 96, false))); - BytecodeViewer.viewer.panel2CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 97, false))); - BytecodeViewer.viewer.panel2Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 98, false))); - BytecodeViewer.viewer.panel2Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 99, false))); - BytecodeViewer.viewer.panel2Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 100, false))); - BytecodeViewer.viewer.panel3Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 101, false))); - BytecodeViewer.viewer.panel3CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 101, false))); - BytecodeViewer.viewer.panel3Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 103, false))); - BytecodeViewer.viewer.panel3Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 104, false))); - BytecodeViewer.viewer.panel3Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 105, false))); - BytecodeViewer.viewer.decodeAPKResources.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 106, false))); + BytecodeViewer.viewer.viewPane1.getProcyon().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 91, false))); + BytecodeViewer.viewer.viewPane1.getCFR().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 92, false))); + BytecodeViewer.viewer.viewPane1.getFern().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 93, false))); + BytecodeViewer.viewer.viewPane1.getKrakatau().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 94, false))); + BytecodeViewer.viewer.viewPane1.getSmali().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 95, false))); + BytecodeViewer.viewer.viewPane2.getProcyon().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 96, false))); + BytecodeViewer.viewer.viewPane2.getCFR().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 97, false))); + BytecodeViewer.viewer.viewPane2.getFern().getEditable().setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 98, false))); + BytecodeViewer.viewer.viewPane2.getKrakatau().getEditable().setSelected(asBoolean(99)); + BytecodeViewer.viewer.viewPane2.getSmali().getEditable().setSelected(asBoolean(100)); + BytecodeViewer.viewer.viewPane3.getProcyon().getEditable().setSelected(asBoolean(101)); + BytecodeViewer.viewer.viewPane3.getCFR().getEditable().setSelected(asBoolean(102)); + BytecodeViewer.viewer.viewPane3.getFern().getEditable().setSelected(asBoolean(103)); + BytecodeViewer.viewer.viewPane3.getKrakatau().getEditable().setSelected(asBoolean(104)); + BytecodeViewer.viewer.viewPane3.getSmali().getEditable().setSelected(asBoolean(105)); + BytecodeViewer.viewer.decodeAPKResources.setSelected(asBoolean(106)); Configuration.library = DiskReader.loadString(settingsName, 107, false); - Configuration.pingback = Boolean.parseBoolean(DiskReader.loadString(settingsName, 108, false)); - BytecodeViewer.viewer.panel1JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 109, false))); - BytecodeViewer.viewer.panel2JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 110, false))); - BytecodeViewer.viewer.panel3JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 111, false))); - BytecodeViewer.viewer.fontSpinner.setValue(Integer.parseInt(DiskReader.loadString(settingsName, 112, false))); - Configuration.deleteForeignLibraries = Boolean.parseBoolean(DiskReader.loadString(settingsName, 113, false)); - decompiler = Integer.parseInt(DiskReader.loadString(settingsName, 114, false)); + Configuration.pingback = asBoolean(108); + BytecodeViewer.viewer.viewPane1.getJD().getEditable().setSelected(asBoolean(109)); + BytecodeViewer.viewer.viewPane2.getJD().getEditable().setSelected(asBoolean(110)); + BytecodeViewer.viewer.viewPane3.getJD().getEditable().setSelected(asBoolean(111)); + BytecodeViewer.viewer.fontSpinner.setValue(getInt(112)); + Configuration.deleteForeignLibraries = asBoolean(113); + int apkDecompiler = getInt(114); - if (decompiler == 0) + if (apkDecompiler == 0) BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionDex.getModel(), true); - else if (decompiler == 1) + else if (apkDecompiler == 1) BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel(), true); Configuration.python3 = DiskReader.loadString(settingsName, 115, false); Configuration.javac = DiskReader.loadString(settingsName, 116, false); Configuration.java = DiskReader.loadString(settingsName, 117, false); - BytecodeViewer.viewer.compileOnSave.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 118, false))); - BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 119, false))); + BytecodeViewer.viewer.compileOnSave.setSelected(asBoolean(118)); + BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(asBoolean(119)); Configuration.warnForEditing = Boolean.parseBoolean(DiskReader.loadString(settingsName, 120, false)); - BytecodeViewer.viewer.showFileInTabTitle.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 121, false))); + BytecodeViewer.viewer.showFileInTabTitle.setSelected(asBoolean(121)); Configuration.displayParentInTab = BytecodeViewer.viewer.showFileInTabTitle.isSelected(); - BytecodeViewer.viewer.forcePureAsciiAsText.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 122, false))); - BytecodeViewer.viewer.synchronizedViewing.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 123, false))); - BytecodeViewer.viewer.showClassMethods.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 124, false))); - BytecodeViewer.viewer.ren.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 125, false))); + BytecodeViewer.viewer.forcePureAsciiAsText.setSelected(asBoolean(122)); + BytecodeViewer.viewer.synchronizedViewing.setSelected(asBoolean(123)); + BytecodeViewer.viewer.showClassMethods.setSelected(asBoolean(124)); + BytecodeViewer.viewer.ren.setSelected(asBoolean(125)); + BytecodeViewer.viewer.viewPane1.getJADX().getEditable().setSelected(asBoolean(126)); } catch (Exception e) { //ignore because errors are expected, first start up and outdated settings. //e.printStackTrace(); } } + + public static boolean asBoolean(int lineNumber) throws Exception + { + return Boolean.parseBoolean(DiskReader.loadString(settingsName, lineNumber, false)); + } + + public static int getInt(int lineNumber) throws Exception + { + return Integer.parseInt(DiskReader.loadString(settingsName, lineNumber, false)); + } } \ No newline at end of file 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 d8d54d27..2ac6d649 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java @@ -1763,128 +1763,27 @@ 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; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.jadxJ1.getModel())) - pane1 = 10; - else if (BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.asmText1.getModel())) - pane1 = 11; - - 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; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.jadxJ2.getModel())) - pane2 = 10; - else if (BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.asmText2.getModel())) - pane2 = 11; - - 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; - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.jadxJ3.getModel())) - pane3 = 10; - else if (BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.asmText3.getModel())) - pane3 = 11; + pane1 = BytecodeViewer.viewer.viewPane1.getSelectedViewer(); + pane2 = BytecodeViewer.viewer.viewPane2.getSelectedViewer(); + pane3 = BytecodeViewer.viewer.viewPane3.getSelectedViewer(); } 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; - return (pane1 == 7 || pane1 == 8) && BytecodeViewer.viewer.panel1Krakatau_E.isSelected(); + return BytecodeViewer.viewer.viewPane1.isPaneEditable(); } 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; - return (pane2 == 7 || pane2 == 8) && BytecodeViewer.viewer.panel2Krakatau_E.isSelected(); + + return BytecodeViewer.viewer.viewPane2.isPaneEditable(); } 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; - return (pane3 == 7 || pane3 == 8) && BytecodeViewer.viewer.panel3Krakatau_E.isSelected(); + + return BytecodeViewer.viewer.viewPane3.isPaneEditable(); } /** diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/DecompilerViewComponent.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/DecompilerViewComponent.java new file mode 100644 index 00000000..dd649a0e --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/DecompilerViewComponent.java @@ -0,0 +1,68 @@ +package the.bytecode.club.bytecodeviewer.gui; + +import the.bytecode.club.bytecodeviewer.util.RefreshWorkPane; + +import javax.swing.*; + +/** + * @author Konloch + * @since 6/21/2021 + */ +public class DecompilerViewComponent +{ + private final String name; + private final boolean hasBytecodeOption; + private final JMenu menu; + private final JRadioButtonMenuItem java = new JRadioButtonMenuItem("Java"); + private final JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode"); + private final JCheckBoxMenuItem editable = new JCheckBoxMenuItem("Editable"); + + public DecompilerViewComponent(String name) { + this(name, false); + } + + public DecompilerViewComponent(String name, boolean hasBytecodeOption) { + this.name = name; + this.menu = new JMenu(name); + this.hasBytecodeOption = hasBytecodeOption; + createMenu(); + } + + private void createMenu() + { + menu.add(java); + if(hasBytecodeOption) + menu.add(bytecode); + menu.add(new JSeparator()); + menu.add(editable); + + java.addActionListener(new RefreshWorkPane()); + } + + public void addToGroup(ButtonGroup group) + { + group.add(java); + if(hasBytecodeOption) + group.add(bytecode); + } + + public JMenu getMenu() + { + return menu; + } + + public JRadioButtonMenuItem getJava() + { + return java; + } + + public JRadioButtonMenuItem getBytecode() + { + return bytecode; + } + + public JCheckBoxMenuItem getEditable() + { + return editable; + } +} 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 18936d0d..75f5c4aa 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -12,8 +12,6 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.util.ArrayList; -import java.util.List; -import java.util.Objects; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; @@ -31,15 +29,13 @@ import javax.swing.JSplitPane; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; -import me.konloch.kontainer.io.DiskWriter; -import org.objectweb.asm.ClassWriter; + import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Configuration; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.Settings; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; -import the.bytecode.club.bytecodeviewer.decompilers.Decompilers; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameClasses; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameFields; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameMethods; @@ -51,13 +47,8 @@ import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ShowMainMethods; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.StackFramesRemover; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZKMStringDecrypter; import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ZStringArrayDecrypter; -import the.bytecode.club.bytecodeviewer.util.APKTool; -import the.bytecode.club.bytecodeviewer.util.Dex2Jar; -import the.bytecode.club.bytecodeviewer.util.FileChangeNotifier; -import the.bytecode.club.bytecodeviewer.util.FileContainer; -import the.bytecode.club.bytecodeviewer.util.JarUtils; -import the.bytecode.club.bytecodeviewer.util.LazyNameUtil; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.*; + import static the.bytecode.club.bytecodeviewer.Constants.*; /*************************************************************************** @@ -88,6 +79,32 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public static final long serialVersionUID = 1851409230530948543L; private static ArrayList rfComps = new ArrayList<>(); + //the root menu bar + public final JMenuBar rootMenu = new JMenuBar(); + + //all of the files main menu components + public final JMenu fileMainMenu = new JMenu("File"); + public final JMenuItem newWorkSpace = new JMenuItem("New Workspace"); + public final JMenuItem addResource = new JMenuItem("Add.."); + public final JMenuItem reloadResources = new JMenuItem("Reload Resources"); + public final JMenuItem runButton = new JMenuItem("Run"); + public final JMenuItem compileButton = new JMenuItem("Compile"); + public final JMenuItem saveAsRunnableJar = new JMenuItem("Save As Runnable Jar.."); + public final JMenuItem saveAsDex = new JMenuItem("Save As DEX.."); + public final JMenuItem saveAsAPK = new JMenuItem("Save As APK.."); + public final JMenuItem saveAsZip = new JMenuItem("Save As Zip.."); + public final JMenuItem decompileSaveOpened = new JMenuItem("Decompile & Save Opened Class.."); + public final JMenuItem decompileSaveAll = new JMenuItem("Decompile & Save All Classes.."); + public final JMenu recentFilesSecondaryMenu = new JMenu("Recent Files"); + public final JMenuItem aboutButton = new JMenuItem("About"); + public final JMenuItem exitButton = new JMenuItem("Exit"); + + //all of the view main menu components + public final JMenu viewMainMenu = new JMenu("View"); + public final ViewPane viewPane1 = new ViewPane(1); + public final ViewPane viewPane2 = new ViewPane(2); + public final ViewPane viewPane3 = new ViewPane(3); + public JCheckBoxMenuItem debugHelpers = new JCheckBoxMenuItem("Debug Helpers"); public JSplitPane sp1; public JSplitPane sp2; @@ -110,20 +127,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public JCheckBoxMenuItem fdi = new JCheckBoxMenuItem("Deinline finally structures"); public JCheckBoxMenuItem asc = new JCheckBoxMenuItem("Allow only ASCII characters in strings"); public JCheckBoxMenuItem ren = new JCheckBoxMenuItem("Rename ambiguous classes and class elements"); - 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 JMenu mnNewMenu_1 = new JMenu("Plugins"); public final JMenuItem mntmStartExternalPlugin = new JMenuItem("Open Plugin.."); public JMenu mnRecentPlugins = new JMenu("Recent Plugins"); - public final JMenuBar menuBar = new JMenuBar(); 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 JMenuItem mntmStackFramesRemover = new JMenuItem("StackFrames Remover"); public final JMenuItem[] waitIcons; @@ -174,16 +185,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { 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 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_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"); @@ -201,19 +210,21 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { 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 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 JCheckBoxMenuItem refreshOnChange = new JCheckBoxMenuItem("Refresh On View Change"); public AboutWindow aboutWindow = new AboutWindow(); + + public final JMenuItem mntmCodeSequenceDiagram = new JMenuItem("Code Sequence Diagram"); + public final JCheckBoxMenuItem compileOnSave = new JCheckBoxMenuItem("Compile On Save"); + public final JCheckBoxMenuItem showFileInTabTitle = new JCheckBoxMenuItem("Show File In Tab Title"); + public final JCheckBoxMenuItem forcePureAsciiAsText = new JCheckBoxMenuItem("Force Pure Ascii As Text"); + 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 JCheckBoxMenuItem decodeAPKResources = new JCheckBoxMenuItem("Decode APK Resources"); + public final JCheckBoxMenuItem synchronizedViewing = new JCheckBoxMenuItem("Synchronized Viewing"); + public final JCheckBoxMenuItem showClassMethods = new JCheckBoxMenuItem("Show Class Methods"); + public FileNavigationPane cn = new FileNavigationPane(this); public SearchingPane s; @@ -265,76 +276,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { return false; } } - - public final JMenuItem mntmSaveAsDEX = new JMenuItem("Save As DEX.."); - public final JMenuItem mntmSaveAsAPK = new JMenuItem("Save As APK.."); - public final JMenuItem mntmCodeSequenceDiagram = new JMenuItem("Code Sequence Diagram"); - public final JRadioButtonMenuItem panel1Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JCheckBoxMenuItem compileOnSave = new JCheckBoxMenuItem("Compile On Save"); - public final JCheckBoxMenuItem showFileInTabTitle = new JCheckBoxMenuItem("Show File In Tab Title"); - public final JCheckBoxMenuItem forcePureAsciiAsText = new JCheckBoxMenuItem("Force Pure Ascii As Text"); - public final JMenuItem compileButton = 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 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 JMenuItem mntmRun = new JMenuItem("Run"); - public final JCheckBoxMenuItem decodeAPKResources = new JCheckBoxMenuItem("Decode APK Resources"); - public final JCheckBoxMenuItem synchronizedViewing = new JCheckBoxMenuItem("Synchronized Viewing"); - public final JCheckBoxMenuItem showClassMethods = new JCheckBoxMenuItem("Show Class Methods"); - public final JMenu mnProcyon = new JMenu("Procyon"); - public final JCheckBoxMenuItem panel1Proc_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnCfr = new JMenu("CFR"); - public final JCheckBoxMenuItem panel1CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnFernflower = new JMenu("FernFlower"); - public final JCheckBoxMenuItem panel1Fern_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnKrakatau = new JMenu("Krakatau"); - public final JCheckBoxMenuItem panel1Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JMenu mnSmalidex = new JMenu("Smali/DEX"); - 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 JMenu menu_1 = new JMenu("Procyon"); - public final JRadioButtonMenuItem panel2Proc = new JRadioButtonMenuItem("Java"); - 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 JCheckBoxMenuItem panel2CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_3 = new JMenu("FernFlower"); - public final JRadioButtonMenuItem panel2Fern = new JRadioButtonMenuItem("Java"); - 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 JCheckBoxMenuItem panel2Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_5 = new JMenu("Smali/DEX"); - public final JRadioButtonMenuItem panel2Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JCheckBoxMenuItem panel2Smali_E = new JCheckBoxMenuItem("Editable"); - 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 JMenu menu_7 = new JMenu("Procyon"); - public final JRadioButtonMenuItem panel3Proc = new JRadioButtonMenuItem("Java"); - 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 JCheckBoxMenuItem panel3CFR_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_9 = new JMenu("FernFlower"); - public final JRadioButtonMenuItem panel3Fern = new JRadioButtonMenuItem("Java"); - 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 JCheckBoxMenuItem panel3Krakatau_E = new JCheckBoxMenuItem("Editable"); - public final JMenu menu_11 = new JMenu("Smali/DEX"); - public final JRadioButtonMenuItem panel3Smali = new JRadioButtonMenuItem("Smali/DEX"); - public final JCheckBoxMenuItem panel3Smali_E = new JCheckBoxMenuItem("Editable"); - public final JRadioButtonMenuItem panel3Bytecode = new JRadioButtonMenuItem("Bytecode"); - public final JRadioButtonMenuItem panel3Hexcode = new JRadioButtonMenuItem("Hexcode"); - + public synchronized void setIcon(final boolean busy) { SwingUtilities.invokeLater(() -> { if (busy) { @@ -361,27 +303,6 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { }); } - public final ButtonGroup panelGroup1 = new ButtonGroup(); - public final ButtonGroup panelGroup2 = new ButtonGroup(); - public final ButtonGroup panelGroup3 = new ButtonGroup(); - public final JRadioButtonMenuItem panel3JDGUI = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem panel3JDGUI_E = new JCheckBoxMenuItem("Editable"); - public final JRadioButtonMenuItem panel2JDGUI = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem panel2JDGUI_E = new JCheckBoxMenuItem("Editable"); - public final JRadioButtonMenuItem panel1JDGUI = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem panel1JDGUI_E = new JCheckBoxMenuItem("Editable"); - - public final JRadioButtonMenuItem jadxJ1 = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem jadxE1 = new JCheckBoxMenuItem("Editable"); - public final JRadioButtonMenuItem jadxJ2 = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem jadxE2 = new JCheckBoxMenuItem("Editable"); - public final JRadioButtonMenuItem jadxJ3 = new JRadioButtonMenuItem("Java"); - public final JCheckBoxMenuItem jadxE3 = new JCheckBoxMenuItem("Editable"); - - public final JRadioButtonMenuItem asmText1 = new JRadioButtonMenuItem("ASM Textify"); - public final JRadioButtonMenuItem asmText2 = new JRadioButtonMenuItem("ASM Textify"); - public final JRadioButtonMenuItem asmText3 = new JRadioButtonMenuItem("ASM Textify"); - public final JSpinner fontSpinner = new JSpinner(); private final JCheckBoxMenuItem chckbxmntmDeleteForeignOutdatedLibs = new JCheckBoxMenuItem("Delete Foreign/Outdated Libs"); public final ButtonGroup apkConversionGroup = new ButtonGroup(); @@ -391,8 +312,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public void calledAfterLoad() { chckbxmntmDeleteForeignOutdatedLibs.setSelected(Configuration.deleteForeignLibraries); } + + public final JCheckBoxMenuItem refreshOnChange = new JCheckBoxMenuItem("Refresh On View Change"); + public final WorkPane workPane = new WorkPane(this); - public MainViewerGUI() { + public MainViewerGUI() + { mnNewMenu_5.setVisible(false); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new Test()); this.addWindowStateListener(new WindowAdapter() { @@ -415,17 +340,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); this.setIconImages(Resources.iconList); - ActionListener listener = 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); @@ -437,1091 +352,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { System.exit(0); } }); - // procyon - /* none */ - setJMenuBar(menuBar); - - JMenu mnNewMenu = new JMenu("File"); - menuBar.add(mnNewMenu); - - mntmNewWorkspace.addActionListener(arg0 -> BytecodeViewer.resetWorkSpace(true)); - - JMenuItem mntmLoadJar = new JMenuItem("Add.."); - mntmLoadJar.addActionListener(e -> { - - final JFileChooser fc = new JFileChooser(); - - try { - File f = new File(Configuration.lastDirectory); - if (f.exists()) - fc.setSelectedFile(f); - } catch (Exception ignored) { - - } - - fc.setDialogTitle("Select File or Folder to open in BCV"); - fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); - fc.setAcceptAllFileFilterUsed(true); - fc.setFileFilter(new FileFilter() { - @Override - public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = MiscUtils.extension(f.getAbsolutePath()); - return extension.equals("jar") || extension.equals("zip") - || extension.equals("class") || extension.equals("apk") - || extension.equals("dex") || extension.equals("war") || extension.equals("jsp"); - - } - - @Override - public String getDescription() { - return "APKs, DEX, Class Files or Zip/Jar/War Archives"; - } - }); - - int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); - - if (returnVal == JFileChooser.APPROVE_OPTION) { - Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath(); - try { - BytecodeViewer.viewer.setIcon(true); - BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()}, true); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e1) { - new ExceptionUI(e1); - } - } - }); - - mnNewMenu.add(mntmLoadJar); - - mnNewMenu.add(new JSeparator()); - - mnNewMenu.add(mntmNewWorkspace); - - JMenuItem mntmSave = new JMenuItem("Save As Zip.."); - mntmSave.setActionCommand(""); - mntmSave.addActionListener(arg0 -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - Thread t = new Thread(() -> { - if (compileOnSave.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 t17 = new Thread(() -> { - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), - file2.getAbsolutePath()); - BytecodeViewer.viewer.setIcon(false); - }); - t17.start(); - } - }); - t.start(); - }); - - mnNewMenu.add(new JSeparator()); - JMenuItem mntmReloadResources = new JMenuItem("Reload Resources"); - mntmReloadResources.addActionListener(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) { - LazyNameUtil.reset(); - ArrayList reopen = new ArrayList<>(); - - for (FileContainer container : BytecodeViewer.files) { - File newFile = new File(container.file.getParent() + fs + container.name); - if (!container.file.getAbsolutePath().equals(newFile.getAbsolutePath()) && - (container.file.getAbsolutePath().endsWith(".apk") || container.file.getAbsolutePath().endsWith(".dex"))) //APKs & dex get renamed - { - container.file.renameTo(newFile); - container.file = newFile; - } - reopen.add(container.file); - } - - BytecodeViewer.files.clear(); - - for (File f : reopen) { - BytecodeViewer.openFiles(new File[]{f}, false); - } - - //refresh panes - } - }); - - mnNewMenu.add(mntmReloadResources); - - mnNewMenu.add(new JSeparator()); - mntmNewMenuItem_3.addActionListener(e -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - Thread t = new Thread(() -> { - if (compileOnSave.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(); - }); - compileButton.addActionListener(arg0 -> { - Thread t = new Thread(() -> BytecodeViewer.compile(true)); - t.start(); - }); - mntmRun.addActionListener(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(compileButton); - - mnNewMenu.add(new JSeparator()); - - mnNewMenu.add(mntmNewMenuItem_3); - mntmSaveAsDEX.addActionListener(arg0 -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread(() -> { - if (compileOnSave.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 t16 = new Thread(() -> { - BytecodeViewer.viewer.setIcon(true); - final String input = tempDirectory + fs + MiscUtils.getRandomizedName() + ".jar"; - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input); - - Thread t15 = new Thread(() -> { - Dex2Jar.saveAsDex(new File(input), file2); - - BytecodeViewer.viewer.setIcon(false); - }); - t15.start(); - }); - t16.start(); - } - }); - t.start(); - }); - mntmSaveAsAPK.addActionListener(arg0 -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - //if theres only one file in the container don't bother asking - List containers = BytecodeViewer.getFiles(); - List validContainers = new ArrayList<>(); - List validContainersNames = new ArrayList<>(); - FileContainer container; - - for (FileContainer fileContainer : containers) { - if (fileContainer.APKToolContents != null && fileContainer.APKToolContents.exists()) { - validContainersNames.add(fileContainer.name); - validContainers.add(fileContainer); - } - } - - if (!validContainers.isEmpty()) { - container = validContainers.get(0); - - if (validContainers.size() >= 2) { - JOptionPane pane = new JOptionPane("Which file would you like to export as an APK?"); - Object[] options = validContainersNames.toArray(new String[0]); - - pane.setOptions(options); - JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Select APK"); - 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; - - container = containers.get(result); - } - } else { - BytecodeViewer.showMessage("You can only export as APK from a valid APK file. Make sure " - + "Settings>Decode Resources is ticked on.\n\nTip: Try exporting as DEX, it doesn't rely on " - + "decoded APK resources"); - return; - } - - final FileContainer finalContainer = container; - - Thread t = new Thread(() -> { - if (compileOnSave.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("apk"); - } - - @Override - public String getDescription() { - return "Android APK"; - } - }); - 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(".apk")) - output = output + ".apk"; - - 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 t14 = new Thread(() -> { - BytecodeViewer.viewer.setIcon(true); - final String input = tempDirectory + fs + MiscUtils.getRandomizedName() + ".jar"; - JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input); - - Thread t13 = new Thread(() -> { - APKTool.buildAPK(new File(input), file2, finalContainer); - - BytecodeViewer.viewer.setIcon(false); - }); - t13.start(); - }); - t14.start(); - } - }); - t.start(); - }); - - //mnNewMenu.add(mntmSaveAsAPK); - mnNewMenu.add(mntmSaveAsDEX); - mnNewMenu.add(mntmSave); - mntmNewMenuItem.addActionListener(arg0 -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread(() -> { - if (compileOnSave.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 javaSucks = file; - - 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[]{"All", "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; - - BytecodeViewer.viewer.setIcon(true); - - File tempZip = new File(tempDirectory + fs + "temp_" + MiscUtils.getRandomizedName() + ".jar"); - if (tempZip.exists()) - tempZip.delete(); - - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath()); - - if (result == 0) { - Thread t12 = new Thread(() -> { - try { - Decompilers.procyon.decompileToZip(tempZip.getAbsolutePath(), - MiscUtils.append(javaSucks, "-proycon.zip")); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t12.start(); - Thread t2 = new Thread(() -> { - try { - BytecodeViewer.viewer.setIcon(true); - Decompilers.cfr.decompileToZip(tempZip.getAbsolutePath(), - MiscUtils.append(javaSucks, "-CFR.zip")); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t2.start(); - Thread t3 = new Thread(() -> { - try { - BytecodeViewer.viewer.setIcon(true); - Decompilers.fernflower.decompileToZip(tempZip.getAbsolutePath(), - MiscUtils.append(javaSucks, "-fernflower.zip")); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t3.start(); - Thread t4 = new Thread(() -> { - try { - BytecodeViewer.viewer.setIcon(true); - Decompilers.krakatau.decompileToZip(tempZip.getAbsolutePath(), - MiscUtils.append(javaSucks, "-kraktau.zip")); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t4.start(); - } - if (result == 1) { - Thread t12 = new Thread(() -> { - try { - Decompilers.procyon.decompileToZip(tempZip.getAbsolutePath(), path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t12.start(); - } - if (result == 2) { - Thread t12 = new Thread(() -> { - try { - Decompilers.cfr.decompileToZip(tempZip.getAbsolutePath(), path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t12.start(); - } - if (result == 3) { - Thread t12 = new Thread(() -> { - try { - Decompilers.fernflower.decompileToZip(tempZip.getAbsolutePath(), path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t12.start(); - } - - if (result == 4) { - Thread t12 = new Thread(() -> { - try { - Decompilers.krakatau.decompileToZip(tempZip.getAbsolutePath(), path); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - new ExceptionUI(e); - } - }); - t12.start(); - } - - if (result == 5) { - BytecodeViewer.viewer.setIcon(false); - } - } - }); - t.start(); - }); - mntmNewMenuItem_12.addActionListener(arg0 -> { - if (workPane.getCurrentViewer() == null) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - - Thread t = new Thread(() -> { - if (compileOnSave.isSelected() && !BytecodeViewer.compile(false)) - return; - - final String s = workPane.getCurrentViewer().cn.name; - - if (s == null) - return; - - 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[]{"All", "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 t1 = new Thread(() -> { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - Objects.requireNonNull(cn).accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - Objects.requireNonNull(cn).accept(cw); - } catch (InterruptedException ignored) { - } - } - - try { - DiskWriter.replaceFile(MiscUtils.append(file, "-proycon.java"), - Decompilers.procyon.decompileClassNode(cn, cw.toByteArray()), false); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - DiskWriter.replaceFile(MiscUtils.append(file, "-CFR.java"), - Decompilers.cfr.decompileClassNode(cn, cw.toByteArray()), false); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - DiskWriter.replaceFile(MiscUtils.append(file, "-fernflower.java"), - Decompilers.fernflower.decompileClassNode(cn, cw.toByteArray()), false); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - DiskWriter.replaceFile(MiscUtils.append(file, "-kraktau.java"), - Decompilers.krakatau.decompileClassNode(cn, cw.toByteArray()), false); - } catch (Exception e) { - e.printStackTrace(); - } - - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - BytecodeViewer.viewer.setIcon(false); - new ExceptionUI(e); - } - }); - t1.start(); - } - if (result == 1) { - Thread t1 = new Thread(() -> { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - Objects.requireNonNull(cn).accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - Objects.requireNonNull(cn).accept(cw); - } catch (InterruptedException ignored) { - } - } - String contents = Decompilers.procyon.decompileClassNode(cn, - cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - BytecodeViewer.viewer.setIcon(false); - new ExceptionUI( - e); - } - }); - t1.start(); - } - if (result == 2) { - Thread t1 = new Thread(() -> { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - Objects.requireNonNull(cn).accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - Objects.requireNonNull(cn).accept(cw); - } catch (InterruptedException ignored) { - } - } - String contents = Decompilers.cfr.decompileClassNode(cn, cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - BytecodeViewer.viewer.setIcon(false); - new ExceptionUI( - e); - } - }); - t1.start(); - } - if (result == 3) { - Thread t1 = new Thread(() -> { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - Objects.requireNonNull(cn).accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - if (cn != null) - cn.accept(cw); - } catch (InterruptedException ignored) { - } - } - String contents = Decompilers.fernflower.decompileClassNode(cn, - cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - BytecodeViewer.viewer.setIcon(false); - new ExceptionUI( - e); - } - }); - t1.start(); - } - if (result == 4) { - Thread t1 = new Thread(() -> { - try { - ClassNode cn = BytecodeViewer.getClassNode(s); - final ClassWriter cw = new ClassWriter(0); - try { - Objects.requireNonNull(cn).accept(cw); - } catch (Exception e) { - e.printStackTrace(); - try { - Thread.sleep(200); - Objects.requireNonNull(cn).accept(cw); - } catch (InterruptedException ignored) { - } - } - - String contents = Decompilers.krakatau.decompileClassNode(cn, - cw.toByteArray()); - DiskWriter.replaceFile(path, contents, false); - BytecodeViewer.viewer.setIcon(false); - } catch (Exception e) { - BytecodeViewer.viewer.setIcon(false); - new ExceptionUI( - e); - } - }); - t1.start(); - } - if (result == 5) { - BytecodeViewer.viewer.setIcon(false); - } - } - }); - t.start(); - }); - - mnNewMenu.add(mntmNewMenuItem_12); - - mnNewMenu.add(mntmNewMenuItem); - - mnNewMenu.add(new JSeparator()); - - mnNewMenu.add(mnRecentFiles); - - mnNewMenu.add(new JSeparator()); - mntmAbout.addActionListener(arg0 -> aboutWindow.setVisible(true)); - - mnNewMenu.add(mntmAbout); - - JMenuItem mntmExit = new JMenuItem("Exit"); - mntmExit.addActionListener(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) { - Configuration.canExit = true; - System.exit(0); - } - }); - - mnNewMenu.add(mntmExit); - - menuBar.add(mnNewMenu_6); - - mnNewMenu_6.add(mnNewMenu_7); - - mnNewMenu_7.add(panel1None); - - mnNewMenu_7.add(new JSeparator()); - - mnNewMenu_7.add(mnProcyon); - mnProcyon.add(panel1Proc); - - mnProcyon.add(new JSeparator()); - - mnProcyon.add(panel1Proc_E); - panel1Proc.addActionListener(listener); - - mnNewMenu_7.add(mnCfr); - - JMenu jadx1 = new JMenu("JADX"); - jadx1.add(jadxJ1); - jadx1.add(new JSeparator()); - jadx1.add(jadxE1); - - JMenu jadx2 = new JMenu("JADX"); - jadx2.add(jadxJ2); - jadx2.add(new JSeparator()); - jadx2.add(jadxE2); - - JMenu jadx3 = new JMenu("JADX"); - jadx3.add(jadxJ3); - jadx3.add(new JSeparator()); - jadx3.add(jadxE3); - - mnNewMenu_7.add(jadx1); - - - mnCfr.add(panel1CFR); - panel1CFR.addActionListener(listener); - - mnCfr.add(new JSeparator()); - - mnCfr.add(panel1CFR_E); - - JMenu menu_6 = new JMenu("JD-GUI"); - mnNewMenu_7.add(menu_6); - - menu_6.add(panel1JDGUI); - menu_6.add(new JSeparator()); - menu_6.add(panel1JDGUI_E); - - mnNewMenu_7.add(mnFernflower); - mnFernflower.add(panel1Fern); - panel1Fern.addActionListener(listener); - - mnFernflower.add(new JSeparator()); - mnFernflower.add(panel1Fern_E); - - mnNewMenu_7.add(mnKrakatau); - mnKrakatau.add(panel1Krakatau); - - panel1Krakatau.addActionListener(listener); - mnKrakatau.add(panel1KrakatauBytecode); - panel1KrakatauBytecode.addActionListener(listener); - - mnKrakatau.add(new JSeparator()); - mnKrakatau.add(panel1Krakatau_E); - - mnNewMenu_7.add(new JSeparator()); - mnNewMenu_7.add(mnSmalidex); - - mnSmalidex.add(panel1Smali); - panel1Smali.addActionListener(listener); - - mnSmalidex.add(new JSeparator()); - - mnSmalidex.add(panel1Smali_E); - panel1Bytecode.addActionListener(listener); - - mnNewMenu_7.add(new JSeparator()); - mnNewMenu_7.add(panel1Bytecode); - mnNewMenu_7.add(panel1Hexcode); - mnNewMenu_7.add(asmText1); - - mnNewMenu_6.add(mnPane); - - mnPane.add(panel2None); - mnPane.add(new JSeparator()); - mnPane.add(menu_1); - - menu_1.add(panel2Proc); - menu_1.add(new JSeparator()); - menu_1.add(panel2Proc_E); - - mnPane.add(menu_2); - mnPane.add(jadx2); - - menu_2.add(panel2CFR); - menu_2.add(new JSeparator()); - menu_2.add(panel2CFR_E); - - JMenu menu = new JMenu("JD-GUI"); - mnPane.add(menu); - - menu.add(panel2JDGUI); - - menu.add(new JSeparator()); - menu.add(panel2JDGUI_E); - - mnPane.add(menu_3); - - menu_3.add(panel2Fern); - menu_3.add(new JSeparator()); - menu_3.add(panel2Fern_E); - - mnPane.add(menu_4); - - menu_4.add(panel2Krakatau); - menu_4.add(panel2KrakatauBytecode); - menu_4.add(new JSeparator()); - menu_4.add(panel2Krakatau_E); - - mnPane.add(new JSeparator()); - mnPane.add(menu_5); - - menu_5.add(panel2Smali); - menu_5.add(new JSeparator()); - menu_5.add(panel2Smali_E); - - mnPane.add(new JSeparator()); - mnPane.add(panel2Bytecode); - mnPane.add(panel2Hexcode); - mnPane.add(asmText2); - - mnNewMenu_6.add(mnPane_1); - - mnPane_1.add(panel3None); - - mnPane_1.add(new JSeparator()); - - mnPane_1.add(menu_7); - - menu_7.add(panel3Proc); - - menu_7.add(new JSeparator()); - - menu_7.add(panel3Proc_E); - - mnPane_1.add(menu_8); - mnPane_1.add(jadx3); - - menu_8.add(panel3CFR); - - menu_8.add(new JSeparator()); - - menu_8.add(panel3CFR_E); - - JMenu mnJdgui = new JMenu("JD-GUI"); - mnPane_1.add(mnJdgui); - - mnJdgui.add(panel3JDGUI); - - mnJdgui.add(new JSeparator()); - - mnJdgui.add(panel3JDGUI_E); - - mnPane_1.add(menu_9); - - menu_9.add(panel3Fern); - - menu_9.add(new JSeparator()); - - menu_9.add(panel3Fern_E); - - mnPane_1.add(menu_10); - - menu_10.add(panel3Krakatau); - - menu_10.add(panel3KrakatauBytecode); - - menu_10.add(new JSeparator()); - - menu_10.add(panel3Krakatau_E); - - mnPane_1.add(new JSeparator()); - - mnPane_1.add(menu_11); - - menu_11.add(panel3Smali); - - menu_11.add(new JSeparator()); - - menu_11.add(panel3Smali_E); - - mnPane_1.add(new JSeparator()); - - mnPane_1.add(panel3Bytecode); - - mnPane_1.add(panel3Hexcode); - - mnPane_1.add(asmText3); + buildMenuBar(); + buildFileMenuBar(); + buildViewMenuBar(); compileOnSave.setSelected(false); - menuBar.add(mnSettings); + rootMenu.add(mnSettings); JMenu visualSettings = new JMenu("Visual Settings"); @@ -1806,7 +644,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnBytecodeDecompilerSettings.add(chckbxmntmAppendBrackets); - menuBar.add(mnNewMenu_5); + rootMenu.add(mnNewMenu_5); mntmNewMenuItem_6.addActionListener(arg0 -> { if (Configuration.runningObfuscation) { BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); @@ -1856,7 +694,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mntmNewMenuItem_10.setEnabled(false); mnNewMenu_5.add(mntmNewMenuItem_10); - menuBar.add(mnNewMenu_1); + rootMenu.add(mnNewMenu_1); mnNewMenu_1.add(mntmStartExternalPlugin); mnNewMenu_1.add(new JSeparator()); mnNewMenu_1.add(mnRecentPlugins); @@ -1898,7 +736,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { waitIcons[i] = new JMenuItem(""); waitIcons[i].setMaximumSize(new Dimension(20, 50)); waitIcons[i].setEnabled(false); - menuBar.add(waitIcons[i]); + rootMenu.add(waitIcons[i]); } mntmStartExternalPlugin.addActionListener(arg0 -> { @@ -1917,15 +755,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { new ExceptionUI(e1); } }); + mntmStartZkmString.addActionListener(e -> PluginManager.runPlugin(new ZKMStringDecrypter())); mntmNewMenuItem_2.addActionListener(e -> PluginManager.runPlugin(new AllatoriStringDecrypter())); - mntmNewMenuItem_1.addActionListener(e -> { - if (BytecodeViewer.getLoadedClasses().isEmpty()) { - BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); - return; - } - new MaliciousCodeScannerOptions().setVisible(true); - }); + mntmNewMenuItem_1.addActionListener(e -> MaliciousCodeScannerOptions.showOptionPanel()); mntmShowAllStrings.addActionListener(e -> PluginManager.runPlugin(new ShowAllStrings())); mntmShowMainMethods.addActionListener(e -> PluginManager.runPlugin(new ShowMainMethods())); @@ -1963,44 +796,6 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { apkConversionGroup.setSelected(apkConversionDex.getModel(), true); - panelGroup1.add(panel1None); - panelGroup1.add(panel1Proc); - panelGroup1.add(panel1CFR); - panelGroup1.add(jadxJ1); - panelGroup1.add(panel1JDGUI); - panelGroup1.add(panel1Fern); - panelGroup1.add(panel1Krakatau); - panelGroup1.add(panel1KrakatauBytecode); - panelGroup1.add(panel1Smali); - panelGroup1.add(panel1Bytecode); - panelGroup1.add(panel1Hexcode); - panelGroup1.add(asmText1); - - panelGroup2.add(panel2None); - panelGroup2.add(panel2Proc); - panelGroup2.add(panel2CFR); - panelGroup2.add(jadxJ2); - panelGroup2.add(panel2JDGUI); - panelGroup2.add(panel2Fern); - panelGroup2.add(panel2Krakatau); - panelGroup2.add(panel2KrakatauBytecode); - panelGroup2.add(panel2Smali); - panelGroup2.add(panel2Bytecode); - panelGroup2.add(panel2Hexcode); - panelGroup2.add(asmText2); - - panelGroup3.add(panel3None); - panelGroup3.add(panel3Proc); - panelGroup3.add(panel3CFR); - panelGroup3.add(jadxJ3); - panelGroup3.add(panel3JDGUI); - panelGroup3.add(panel3Fern); - panelGroup3.add(panel3Krakatau); - panelGroup3.add(panel3KrakatauBytecode); - panelGroup3.add(panel3Smali); - panelGroup3.add(panel3Bytecode); - panelGroup3.add(panel3Hexcode); - panelGroup3.add(asmText3); fontSpinner.setPreferredSize(new Dimension(42, 20)); fontSpinner.setSize(new Dimension(42, 20)); @@ -2022,13 +817,67 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { visualSettings.add(showClassMethods); - panelGroup1.setSelected(panel1Fern.getModel(), true); - panelGroup2.setSelected(panel2Bytecode.getModel(), true); - panelGroup3.setSelected(panel3None.getModel(), true); + viewPane1.getGroup().setSelected(viewPane1.getFern().getJava().getModel(), true); + viewPane2.getGroup().setSelected(viewPane1.getBytecode().getModel(), true); + viewPane3.getGroup().setSelected(viewPane1.getNone().getModel(), true); this.setLocationRelativeTo(null); } - + + public void buildMenuBar() + { + setJMenuBar(rootMenu); + + rootMenu.add(fileMainMenu); + rootMenu.add(viewMainMenu); + } + + public void buildFileMenuBar() + { + fileMainMenu.add(addResource); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(newWorkSpace); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(reloadResources); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(runButton); + fileMainMenu.add(compileButton); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(saveAsRunnableJar); + //fileMainMenuBar.add(mntmSaveAsAPK); + fileMainMenu.add(saveAsDex); + fileMainMenu.add(saveAsZip); + fileMainMenu.add(decompileSaveOpened); + fileMainMenu.add(decompileSaveAll); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(recentFilesSecondaryMenu); + fileMainMenu.add(new JSeparator()); + fileMainMenu.add(aboutButton); + fileMainMenu.add(exitButton); + + saveAsZip.setActionCommand(""); + + addResource.addActionListener(e -> selectFile()); + newWorkSpace.addActionListener(e -> BytecodeViewer.resetWorkSpace(true)); + reloadResources.addActionListener(arg0 -> reloadResources()); + runButton.addActionListener(e -> runResources()); + compileButton.addActionListener(arg0 -> compileOnNewThread()); + saveAsRunnableJar.addActionListener(e -> ResourceExporting.saveAsRunnableJar()); + saveAsAPK.addActionListener(arg0 -> ResourceExporting.saveAsAPK()); + saveAsDex.addActionListener(arg0 -> ResourceExporting.saveAsDex()); + saveAsZip.addActionListener(arg0 -> ResourceExporting.saveAsZip()); + decompileSaveAll.addActionListener(arg0 -> ResourceDecompiling.decompileSaveAll()); + decompileSaveOpened.addActionListener(arg0 -> ResourceDecompiling.decompileSaveOpenedOnly()); + aboutButton.addActionListener(arg0 -> aboutWindow.setVisible(true)); + exitButton.addActionListener(arg0 -> askBeforeExiting()); + } + + public void buildViewMenuBar() + { + viewMainMenu.add(viewPane1.menu); + viewMainMenu.add(viewPane2.menu); + viewMainMenu.add(viewPane3.menu); + } @Override public void openClassFile(final FileContainer container, final String name, final ClassNode cn) { @@ -2052,6 +901,108 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } return null; } + + public void selectFile() + { + final JFileChooser fc = new JFileChooser(); + + try { + File f = new File(Configuration.lastDirectory); + if (f.exists()) + fc.setSelectedFile(f); + } catch (Exception ignored) { + + } + + fc.setDialogTitle("Select File or Folder to open in BCV"); + fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + fc.setAcceptAllFileFilterUsed(true); + fc.setFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + + String extension = MiscUtils.extension(f.getAbsolutePath()); + return extension.equals("jar") || extension.equals("zip") + || extension.equals("class") || extension.equals("apk") + || extension.equals("dex") || extension.equals("war") || extension.equals("jsp"); + + } + + @Override + public String getDescription() { + return "APKs, DEX, Class Files or Zip/Jar/War Archives"; + } + }); + + int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + Configuration.lastDirectory = fc.getSelectedFile().getAbsolutePath(); + try { + BytecodeViewer.viewer.setIcon(true); + BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()}, true); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e1) { + new ExceptionUI(e1); + } + } + } + + public void reloadResources() + { + 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) { + LazyNameUtil.reset(); + ArrayList reopen = new ArrayList<>(); + + for (FileContainer container : BytecodeViewer.files) { + File newFile = new File(container.file.getParent() + fs + container.name); + if (!container.file.getAbsolutePath().equals(newFile.getAbsolutePath()) && + (container.file.getAbsolutePath().endsWith(".apk") || container.file.getAbsolutePath().endsWith(".dex"))) //APKs & dex get renamed + { + container.file.renameTo(newFile); + container.file = newFile; + } + reopen.add(container.file); + } + + BytecodeViewer.files.clear(); + + for (File f : reopen) { + BytecodeViewer.openFiles(new File[]{f}, false); + } + + //refresh panes + } + } + + public void compileOnNewThread() + { + Thread t = new Thread(() -> BytecodeViewer.compile(true)); + t.start(); + } + + public void runResources() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + new RunOptions().setVisible(true); + } public void selectPythonC() { JFileChooser fc = new JFileChooser(); @@ -2103,7 +1054,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } } - public void java() { + public void selectJava() { JFileChooser fc = new JFileChooser(); fc.setFileFilter(new FileFilter() { @Override @@ -2178,8 +1129,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); } } - - + public void selectJRERTLibrary() { JFileChooser fc = new JFileChooser(); fc.setFileFilter(new FileFilter() { @@ -2204,4 +1154,25 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1); } } + + public void askBeforeExiting() + { + 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) { + Configuration.canExit = true; + System.exit(0); + } + } } 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 69dbe743..83a0a39b 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java @@ -4,6 +4,8 @@ import java.awt.Dimension; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; + +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.MaliciousCodeScanner; @@ -34,6 +36,14 @@ import the.bytecode.club.bytecodeviewer.plugin.preinstalled.MaliciousCodeScanner */ public class MaliciousCodeScannerOptions extends JFrame { + public static void showOptionPanel() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + new MaliciousCodeScannerOptions().setVisible(true); + } public MaliciousCodeScannerOptions() { this.setIconImages(Resources.iconList); setSize(new Dimension(250, 323)); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/ViewPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ViewPane.java new file mode 100644 index 00000000..76aa94db --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/ViewPane.java @@ -0,0 +1,215 @@ +package the.bytecode.club.bytecodeviewer.gui; + +import javax.swing.*; + +/** + * @author Konloch + * @since 6/21/2021 + */ +public class ViewPane +{ + public final int paneID; + public final JMenu menu; + public final ButtonGroup group = new ButtonGroup(); + public final JRadioButtonMenuItem none = new JRadioButtonMenuItem("None"); + public final DecompilerViewComponent procyon = new DecompilerViewComponent("Procyon"); + public final DecompilerViewComponent CFR = new DecompilerViewComponent("CFR"); + public final DecompilerViewComponent JADX = new DecompilerViewComponent("JADX"); + public final DecompilerViewComponent JD = new DecompilerViewComponent("JD-GUI"); + public final DecompilerViewComponent fern = new DecompilerViewComponent("FernFlower"); + public final DecompilerViewComponent krakatau = new DecompilerViewComponent("Krakatau", true); + public final DecompilerViewComponent smali = new DecompilerViewComponent("Smali/DEX"); + public final JRadioButtonMenuItem hexcode = new JRadioButtonMenuItem("Hexcode"); + public final JRadioButtonMenuItem bytecode = new JRadioButtonMenuItem("Bytecode"); + public final JRadioButtonMenuItem asmTextify = new JRadioButtonMenuItem("ASM Textify"); + + public ViewPane(int paneID) { + this.paneID = paneID; + this.menu = new JMenu("Pane " + paneID); + buildMenu(); + } + + public void buildMenu() + { + group.add(none); + procyon.addToGroup(group); + CFR.addToGroup(group); + JADX.addToGroup(group); + JD.addToGroup(group); + fern.addToGroup(group); + krakatau.addToGroup(group); + smali.addToGroup(group); + group.add(bytecode); + group.add(hexcode); + group.add(asmTextify); + + menu.add(none); + menu.add(new JSeparator()); + menu.add(procyon.getMenu()); + menu.add(CFR.getMenu()); + menu.add(JADX.getMenu()); + menu.add(JD.getMenu()); + menu.add(fern.getMenu()); + menu.add(krakatau.getMenu()); + menu.add(new JSeparator()); + menu.add(smali.getMenu()); + menu.add(new JSeparator()); + menu.add(hexcode); + menu.add(bytecode); + menu.add(asmTextify); + } + + public int getSelectedViewer() + { + if (group.isSelected(none.getModel())) + return 0; + else if (group.isSelected(procyon.getJava().getModel())) + return 1; + else if (group.isSelected(CFR.getJava().getModel())) + return 2; + else if (group.isSelected(fern.getJava().getModel())) + return 3; + else if (group.isSelected(bytecode.getModel())) + return 4; + else if (group.isSelected(hexcode.getModel())) + return 5; + else if (group.isSelected(smali.getJava().getModel())) + return 6; + else if (group.isSelected(krakatau.getJava().getModel())) + return 7; + else if (group.isSelected(krakatau.getBytecode().getModel())) + return 8; + else if (group.isSelected(JD.getBytecode().getModel())) + return 9; + else if (group.isSelected(JADX.getBytecode().getModel())) + return 10; + else if (group.isSelected(asmTextify.getModel())) + return 11; + + //default to none + return 0; + } + + public void setSelectedViewer(int decompiler) + { + switch (decompiler) + { + case 0: + group.setSelected(none.getModel(), true); + break; + case 1: + group.setSelected(procyon.getJava().getModel(), true); + break; + case 2: + group.setSelected(CFR.getJava().getModel(), true); + break; + case 3: + group.setSelected(fern.getJava().getModel(), true); + break; + case 4: + group.setSelected(bytecode.getModel(), true); + break; + case 5: + group.setSelected(hexcode.getModel(), true); + break; + case 6: + group.setSelected(smali.getJava().getModel(), true); + break; + case 7: + group.setSelected(krakatau.getJava().getModel(), true); + break; + case 8: + group.setSelected(krakatau.getBytecode().getModel(), true); + break; + case 9: + group.setSelected(JD.getJava().getModel(), true); + break; + case 10: + group.setSelected(JADX.getJava().getModel(), true); + break; + case 11: + group.setSelected(asmTextify.getModel(), true); + break; + } + } + + public boolean isPaneEditable() + { + if(group.isSelected(procyon.getJava().getModel()) && procyon.getEditable().isSelected()) + return true; + if(group.isSelected(CFR.getJava().getModel()) && CFR.getEditable().isSelected()) + return true; + if(group.isSelected(JADX.getJava().getModel()) && JADX.getEditable().isSelected()) + return true; + if(group.isSelected(JD.getJava().getModel()) && JD.getEditable().isSelected()) + return true; + if(group.isSelected(fern.getJava().getModel()) && fern.getEditable().isSelected()) + return true; + if((group.isSelected(krakatau.getJava().getModel()) || group.isSelected(krakatau.getBytecode().getModel())) && krakatau.getEditable().isSelected()) + return true; + if(group.isSelected(smali.getJava().getModel()) && krakatau.getEditable().isSelected()) + return true; + + return false; + } + + public ButtonGroup getGroup() + { + return group; + } + + public JRadioButtonMenuItem getNone() + { + return none; + } + + public DecompilerViewComponent getProcyon() + { + return procyon; + } + + public DecompilerViewComponent getCFR() + { + return CFR; + } + + public DecompilerViewComponent getJADX() + { + return JADX; + } + + public DecompilerViewComponent getJD() + { + return JD; + } + + public DecompilerViewComponent getFern() + { + return fern; + } + + public DecompilerViewComponent getKrakatau() + { + return krakatau; + } + + public DecompilerViewComponent getSmali() + { + return smali; + } + + public JRadioButtonMenuItem getHexcode() + { + return hexcode; + } + + public JRadioButtonMenuItem getBytecode() + { + return bytecode; + } + + public JRadioButtonMenuItem getAsmTextify() + { + return asmTextify; + } +} 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 6cc727fb..1ccffd5d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/WorkPane.java @@ -58,7 +58,7 @@ public class WorkPane extends VisibleComponent implements ActionListener { public JTabbedPane tabs; JPanel buttonPanel; - JButton refreshClass; + public JButton refreshClass; HashMap workingOn = new HashMap<>(); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/RefreshWorkPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/RefreshWorkPane.java new file mode 100644 index 00000000..68b19a1e --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/RefreshWorkPane.java @@ -0,0 +1,24 @@ +package the.bytecode.club.bytecodeviewer.util; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Konloch + * @since 6/21/2021 + */ +public class RefreshWorkPane implements ActionListener +{ + @Override + public void actionPerformed(ActionEvent e) + { + if (BytecodeViewer.viewer.refreshOnChange.isSelected()) { + if (BytecodeViewer.viewer.workPane.getCurrentViewer() == null) + return; + + BytecodeViewer.viewer.workPane.refreshClass.doClick(); + } + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceDecompiling.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceDecompiling.java new file mode 100644 index 00000000..c70b370f --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceDecompiling.java @@ -0,0 +1,442 @@ +package the.bytecode.club.bytecodeviewer.util; + +import me.konloch.kontainer.io.DiskWriter; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; +import the.bytecode.club.bytecodeviewer.decompilers.Decompilers; +import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import java.io.File; +import java.util.Objects; + +import static the.bytecode.club.bytecodeviewer.Constants.fs; +import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory; + +/** + * @author Konloch + * @since 6/21/2021 + */ +public class ResourceDecompiling +{ + public static void decompileSaveAll() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.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(BytecodeViewer.viewer); + 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 javaSucks = file; + + 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[]{"All", "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; + + BytecodeViewer.viewer.setIcon(true); + + File tempZip = new File(tempDirectory + fs + "temp_" + MiscUtils.getRandomizedName() + ".jar"); + if (tempZip.exists()) + tempZip.delete(); + + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath()); + + if (result == 0) { + Thread t12 = new Thread(() -> { + try { + Decompilers.procyon.decompileToZip(tempZip.getAbsolutePath(), + MiscUtils.append(javaSucks, "-proycon.zip")); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t12.start(); + Thread t2 = new Thread(() -> { + try { + BytecodeViewer.viewer.setIcon(true); + Decompilers.cfr.decompileToZip(tempZip.getAbsolutePath(), + MiscUtils.append(javaSucks, "-CFR.zip")); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t2.start(); + Thread t3 = new Thread(() -> { + try { + BytecodeViewer.viewer.setIcon(true); + Decompilers.fernflower.decompileToZip(tempZip.getAbsolutePath(), + MiscUtils.append(javaSucks, "-fernflower.zip")); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t3.start(); + Thread t4 = new Thread(() -> { + try { + BytecodeViewer.viewer.setIcon(true); + Decompilers.krakatau.decompileToZip(tempZip.getAbsolutePath(), + MiscUtils.append(javaSucks, "-kraktau.zip")); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t4.start(); + } + if (result == 1) { + Thread t12 = new Thread(() -> { + try { + Decompilers.procyon.decompileToZip(tempZip.getAbsolutePath(), path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t12.start(); + } + if (result == 2) { + Thread t12 = new Thread(() -> { + try { + Decompilers.cfr.decompileToZip(tempZip.getAbsolutePath(), path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t12.start(); + } + if (result == 3) { + Thread t12 = new Thread(() -> { + try { + Decompilers.fernflower.decompileToZip(tempZip.getAbsolutePath(), path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t12.start(); + } + + if (result == 4) { + Thread t12 = new Thread(() -> { + try { + Decompilers.krakatau.decompileToZip(tempZip.getAbsolutePath(), path); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + new ExceptionUI(e); + } + }); + t12.start(); + } + + if (result == 5) { + BytecodeViewer.viewer.setIcon(false); + } + } + }); + t.start(); + } + + public static void decompileSaveOpenedOnly() + { + if (BytecodeViewer.viewer.workPane.getCurrentViewer() == null) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.isSelected() && !BytecodeViewer.compile(false)) + return; + + final String s = BytecodeViewer.viewer.workPane.getCurrentViewer().cn.name; + + if (s == null) + return; + + 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(BytecodeViewer.viewer); + 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[]{"All", "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 t1 = new Thread(() -> { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + final ClassWriter cw = new ClassWriter(0); + try { + Objects.requireNonNull(cn).accept(cw); + } catch (Exception e) { + e.printStackTrace(); + try { + Thread.sleep(200); + Objects.requireNonNull(cn).accept(cw); + } catch (InterruptedException ignored) { + } + } + + try { + DiskWriter.replaceFile(MiscUtils.append(file, "-proycon.java"), + Decompilers.procyon.decompileClassNode(cn, cw.toByteArray()), false); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + DiskWriter.replaceFile(MiscUtils.append(file, "-CFR.java"), + Decompilers.cfr.decompileClassNode(cn, cw.toByteArray()), false); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + DiskWriter.replaceFile(MiscUtils.append(file, "-fernflower.java"), + Decompilers.fernflower.decompileClassNode(cn, cw.toByteArray()), false); + } catch (Exception e) { + e.printStackTrace(); + } + + try { + DiskWriter.replaceFile(MiscUtils.append(file, "-kraktau.java"), + Decompilers.krakatau.decompileClassNode(cn, cw.toByteArray()), false); + } catch (Exception e) { + e.printStackTrace(); + } + + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + BytecodeViewer.viewer.setIcon(false); + new ExceptionUI(e); + } + }); + t1.start(); + } + if (result == 1) { + Thread t1 = new Thread(() -> { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + final ClassWriter cw = new ClassWriter(0); + try { + Objects.requireNonNull(cn).accept(cw); + } catch (Exception e) { + e.printStackTrace(); + try { + Thread.sleep(200); + Objects.requireNonNull(cn).accept(cw); + } catch (InterruptedException ignored) { + } + } + String contents = Decompilers.procyon.decompileClassNode(cn, + cw.toByteArray()); + DiskWriter.replaceFile(path, contents, false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + BytecodeViewer.viewer.setIcon(false); + new ExceptionUI( + e); + } + }); + t1.start(); + } + if (result == 2) { + Thread t1 = new Thread(() -> { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + final ClassWriter cw = new ClassWriter(0); + try { + Objects.requireNonNull(cn).accept(cw); + } catch (Exception e) { + e.printStackTrace(); + try { + Thread.sleep(200); + Objects.requireNonNull(cn).accept(cw); + } catch (InterruptedException ignored) { + } + } + String contents = Decompilers.cfr.decompileClassNode(cn, cw.toByteArray()); + DiskWriter.replaceFile(path, contents, false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + BytecodeViewer.viewer.setIcon(false); + new ExceptionUI( + e); + } + }); + t1.start(); + } + if (result == 3) { + Thread t1 = new Thread(() -> { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + final ClassWriter cw = new ClassWriter(0); + try { + Objects.requireNonNull(cn).accept(cw); + } catch (Exception e) { + e.printStackTrace(); + try { + Thread.sleep(200); + if (cn != null) + cn.accept(cw); + } catch (InterruptedException ignored) { + } + } + String contents = Decompilers.fernflower.decompileClassNode(cn, + cw.toByteArray()); + DiskWriter.replaceFile(path, contents, false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + BytecodeViewer.viewer.setIcon(false); + new ExceptionUI( + e); + } + }); + t1.start(); + } + if (result == 4) { + Thread t1 = new Thread(() -> { + try { + ClassNode cn = BytecodeViewer.getClassNode(s); + final ClassWriter cw = new ClassWriter(0); + try { + Objects.requireNonNull(cn).accept(cw); + } catch (Exception e) { + e.printStackTrace(); + try { + Thread.sleep(200); + Objects.requireNonNull(cn).accept(cw); + } catch (InterruptedException ignored) { + } + } + + String contents = Decompilers.krakatau.decompileClassNode(cn, + cw.toByteArray()); + DiskWriter.replaceFile(path, contents, false); + BytecodeViewer.viewer.setIcon(false); + } catch (Exception e) { + BytecodeViewer.viewer.setIcon(false); + new ExceptionUI( + e); + } + }); + t1.start(); + } + if (result == 5) { + BytecodeViewer.viewer.setIcon(false); + } + } + }); + t.start(); + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceExporting.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceExporting.java new file mode 100644 index 00000000..08c74938 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ResourceExporting.java @@ -0,0 +1,326 @@ +package the.bytecode.club.bytecodeviewer.util; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.gui.ExportJar; + +import javax.swing.*; +import javax.swing.filechooser.FileFilter; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import static the.bytecode.club.bytecodeviewer.Constants.fs; +import static the.bytecode.club.bytecodeviewer.Constants.tempDirectory; + +/** + * @author Konloch + * @since 6/21/2021 + */ +public class ResourceExporting +{ + + public static void saveAsRunnableJar() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.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(BytecodeViewer.viewer); + 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(); + } + + public static void saveAsZip() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.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(BytecodeViewer.viewer); + 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 t17 = new Thread(() -> { + JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), + file2.getAbsolutePath()); + BytecodeViewer.viewer.setIcon(false); + }); + t17.start(); + } + }); + t.start(); + } + + public static void saveAsDex() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.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(BytecodeViewer.viewer); + 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 t16 = new Thread(() -> { + BytecodeViewer.viewer.setIcon(true); + final String input = tempDirectory + fs + MiscUtils.getRandomizedName() + ".jar"; + JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input); + + Thread t15 = new Thread(() -> { + Dex2Jar.saveAsDex(new File(input), file2); + + BytecodeViewer.viewer.setIcon(false); + }); + t15.start(); + }); + t16.start(); + } + }); + t.start(); + } + + public static void saveAsAPK() + { + if (BytecodeViewer.getLoadedClasses().isEmpty()) { + BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); + return; + } + + //if theres only one file in the container don't bother asking + List containers = BytecodeViewer.getFiles(); + List validContainers = new ArrayList<>(); + List validContainersNames = new ArrayList<>(); + FileContainer container; + + for (FileContainer fileContainer : containers) { + if (fileContainer.APKToolContents != null && fileContainer.APKToolContents.exists()) { + validContainersNames.add(fileContainer.name); + validContainers.add(fileContainer); + } + } + + if (!validContainers.isEmpty()) { + container = validContainers.get(0); + + if (validContainers.size() >= 2) { + JOptionPane pane = new JOptionPane("Which file would you like to export as an APK?"); + Object[] options = validContainersNames.toArray(new String[0]); + + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Select APK"); + 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; + + container = containers.get(result); + } + } else { + BytecodeViewer.showMessage("You can only export as APK from a valid APK file. Make sure " + + "Settings>Decode Resources is ticked on.\n\nTip: Try exporting as DEX, it doesn't rely on " + + "decoded APK resources"); + return; + } + + final FileContainer finalContainer = container; + + Thread t = new Thread(() -> { + if (BytecodeViewer.viewer.compileOnSave.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("apk"); + } + + @Override + public String getDescription() { + return "Android APK"; + } + }); + fc.setFileHidingEnabled(false); + fc.setAcceptAllFileFilterUsed(false); + int returnVal = fc.showSaveDialog(BytecodeViewer.viewer); + if (returnVal == JFileChooser.APPROVE_OPTION) { + final File file = fc.getSelectedFile(); + String output = file.getAbsolutePath(); + if (!output.endsWith(".apk")) + output = output + ".apk"; + + 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 t14 = new Thread(() -> { + BytecodeViewer.viewer.setIcon(true); + final String input = tempDirectory + fs + MiscUtils.getRandomizedName() + ".jar"; + JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input); + + Thread t13 = new Thread(() -> { + APKTool.buildAPK(new File(input), file2, finalContainer); + + BytecodeViewer.viewer.setIcon(false); + }); + t13.start(); + }); + t14.start(); + } + }); + t.start(); + } +}