diff --git a/BytecodeViewer 2.0.jar b/BytecodeViewer 2.0.jar new file mode 100644 index 00000000..b2731f5c Binary files /dev/null and b/BytecodeViewer 2.0.jar differ diff --git a/README.txt b/README.txt index a2968b79..534d1e08 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -Bytecode Viewer is a Java Bytecode Viewer, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more. +Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more. It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch. There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of. @@ -16,6 +16,8 @@ CFR by Lee Benfield Video of Beta 1.5.2: http://the.bytecode.club/pages.php?page=bytecode-viewer +Download the latest version here: https://github.com/Konloch/bytecode-viewer/releases + Features: Java Decompiler - It uses a modified version of FernFlower, Procyon and CFR. Bytecode Decompiler - A modified version of J-RET's. @@ -132,4 +134,17 @@ Changelog: 11/3/2014 - The GUI setttings now save. 11/3/2014 - Removed the option to disable syntax highlighting (since it's lightweight now). 11/3/2014 - About window now contains the version number and the BCV directory. -11/3/2014 - Added an option to toggle to outdated status. \ No newline at end of file +11/3/2014 - Added an option to toggle to outdated status. +--- 2.0 ---: //Out of beta, WOO +11/4/2014 - Officially been 1 month of development. +11/4/2014 - Replaced ""+ with String.valueOf (cheers bibl). +11/4/2014 - Changed how the temp directory was created. +11/4/2014 - Put a file.seperator to the end of tempDirectory. +11/4/2014 - Made the exit button work. +11/4/2014 - Added a GUI for all Exception Stack Trace's. +11/4/2014 - The plugin system now shows a message instead of just printing to the console when it's not going to run a plugin. +11/4/2014 - Updated the search function, it's now perfect. +11/5/2014 - Made the Show All Strings plugin instant. +11/5/2014 - Kinda added middle mouse button closes tab (only if you click the exit button). +11/5/2014 - Improved the Malicious Code Scanner, also made it instant. +11/5/2014 - Added icons to the program (cheers Fluke). \ No newline at end of file diff --git a/VERSION b/VERSION index 2de0fff6..415b19fc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Beta 1.5.3 \ No newline at end of file +2.0 \ No newline at end of file diff --git a/BytecodeViewer Beta 1.0.jar b/archive/BytecodeViewer Beta 1.0.jar similarity index 100% rename from BytecodeViewer Beta 1.0.jar rename to archive/BytecodeViewer Beta 1.0.jar diff --git a/BytecodeViewer Beta 1.1.jar b/archive/BytecodeViewer Beta 1.1.jar similarity index 100% rename from BytecodeViewer Beta 1.1.jar rename to archive/BytecodeViewer Beta 1.1.jar diff --git a/BytecodeViewer Beta 1.2.jar b/archive/BytecodeViewer Beta 1.2.jar similarity index 100% rename from BytecodeViewer Beta 1.2.jar rename to archive/BytecodeViewer Beta 1.2.jar diff --git a/BytecodeViewer Beta 1.3.1.jar b/archive/BytecodeViewer Beta 1.3.1.jar similarity index 100% rename from BytecodeViewer Beta 1.3.1.jar rename to archive/BytecodeViewer Beta 1.3.1.jar diff --git a/BytecodeViewer Beta 1.3.jar b/archive/BytecodeViewer Beta 1.3.jar similarity index 100% rename from BytecodeViewer Beta 1.3.jar rename to archive/BytecodeViewer Beta 1.3.jar diff --git a/BytecodeViewer Beta 1.4.jar b/archive/BytecodeViewer Beta 1.4.jar similarity index 100% rename from BytecodeViewer Beta 1.4.jar rename to archive/BytecodeViewer Beta 1.4.jar diff --git a/BytecodeViewer Beta 1.5.1.jar b/archive/BytecodeViewer Beta 1.5.1.jar similarity index 100% rename from BytecodeViewer Beta 1.5.1.jar rename to archive/BytecodeViewer Beta 1.5.1.jar diff --git a/BytecodeViewer Beta 1.5.2.jar b/archive/BytecodeViewer Beta 1.5.2.jar similarity index 100% rename from BytecodeViewer Beta 1.5.2.jar rename to archive/BytecodeViewer Beta 1.5.2.jar diff --git a/BytecodeViewer Beta 1.5.3.jar b/archive/BytecodeViewer Beta 1.5.3.jar similarity index 100% rename from BytecodeViewer Beta 1.5.3.jar rename to archive/BytecodeViewer Beta 1.5.3.jar diff --git a/BytecodeViewer Beta 1.5.jar b/archive/BytecodeViewer Beta 1.5.jar similarity index 100% rename from BytecodeViewer Beta 1.5.jar rename to archive/BytecodeViewer Beta 1.5.jar diff --git a/libs/imgscalr-lib-4.2.jar b/libs/imgscalr-lib-4.2.jar new file mode 100644 index 00000000..bb7a406b Binary files /dev/null and b/libs/imgscalr-lib-4.2.jar differ diff --git a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index 4bdf035e..df5a7b36 100644 --- a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -2,7 +2,9 @@ package the.bytecode.club.bytecodeviewer; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; @@ -12,6 +14,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; +import javax.imageio.ImageIO; import javax.swing.JDialog; import javax.swing.JMenuItem; import javax.swing.JOptionPane; @@ -20,7 +23,9 @@ import javax.swing.UIManager; import me.konloch.kontainer.io.DiskReader; import me.konloch.kontainer.io.DiskWriter; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; +import org.imgscalr.Scalr; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane; @@ -50,15 +55,13 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager; * File Navigation Pane, Search Pane and Work Pane based off of J-RET by WaterWolf - https://github.com/Waterwolf/Java-ReverseEngineeringTool * HexViewer pane based off of Re-Java's by Sami Koivu - http://rejava.sourceforge.net/ * Java Decompiler is a modified version of FernFlower, Procyon and CFR. - * Bytecode Decompiler base & ByteAnalysis lib by Bibl. - + * Bytecode Decompiler base & ByteAnalysis lib by Bibl. * * TODO: - * Fix the fucking import jar method cause it's a bitch on memory (at the.bytecode.club.bytecodeviewer.JarUtils.getNode(JarUtils.java:83)) + * The import jar method eats up a lot of memory, look into some how reducing this. * Make the search results clickable * Add a tool to build a flowchart of all the classes, and what methods execute what classes, and those method, read chatlog - * Middle mouse click should close tabs * - * * ----Beta 1.0-----: * 10/4/2014 - Designed a POC GUI, still needs a lot of work. * 10/4/2014 - Started importing J-RET's backend. @@ -160,6 +163,19 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager; * 11/3/2014 - Removed the option to disable syntax highlighting (since it's lightweight now). * 11/3/2014 - About window now contains the version number and the BCV directory. * 11/3/2014 - Added an option to toggle to outdated status. + * ----2.0-----: + * 11/4/2014 - Officially been 1 month of development. + * 11/4/2014 - Replaced ""+ with String.valueOf (cheers bibl). + * 11/4/2014 - Changed how the temp directory was created. + * 11/4/2014 - Put a file.seperator to the end of tempDirectory. + * 11/4/2014 - Made the exit button work. + * 11/4/2014 - Added a GUI for all Exception Stack Trace's. + * 11/4/2014 - The plugin system now shows a message instead of just printing to the console when it's not going to run a plugin. + * 11/4/2014 - Updated the search function, it's now perfect. + * 11/5/2014 - Made the Show All Strings plugin instant. + * 11/5/2014 - Kinda added middle mouse button closes tab (only if you click the exit button). + * 11/5/2014 - Improved the Malicious Code Scanner, also made it instant. + * 11/5/2014 - Added icons to the program (cheers Fluke). * * @author Konloch * @@ -176,13 +192,19 @@ public class BytecodeViewer { private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv"; private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv"; private static String settingsName = getBCVDirectory() + fs + "settings.bcv"; - public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp"; + public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs; private static ArrayList recentFiles = DiskReader.loadArrayList(filesName, false); private static ArrayList recentPlugins = DiskReader.loadArrayList(pluginsName, false); - public static String version = "Beta 1.5.3"; + public static String version = "2.0"; public static void main(String[] args) { + iconList = new ArrayList(); + int size = 16; + for(int i = 0; i < 24; i++) { + iconList.add(resize(icon, size, size)); + size += 2; + } cleanup(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override @@ -212,7 +234,7 @@ public class BytecodeViewer { if(!BytecodeViewer.version.equals(version)) showMessage("You're running an outdated version of Bytecode Viewer, current version: " + BytecodeViewer.version + ", latest version: " + version+nl+nl+"https://github.com/Konloch/bytecode-viewer"); } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } } @@ -221,7 +243,7 @@ public class BytecodeViewer { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } viewer = new MainViewerGUI(); loadGUISettings(); @@ -256,7 +278,7 @@ public class BytecodeViewer { try { JarUtils.put(f, BytecodeViewer.loadedClasses); } catch (final Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } @@ -265,7 +287,7 @@ public class BytecodeViewer { final ClassNode cn = JarUtils.getNode(JarUtils.getBytes(new FileInputStream(f))); BytecodeViewer.loadedClasses.put(cn.name, cn); } catch (final Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } } @@ -286,7 +308,7 @@ public class BytecodeViewer { try { PluginManager.runPlugin(plugin); } catch (Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } addRecentPlugin(plugin); } @@ -394,18 +416,15 @@ public class BytecodeViewer { private static File tempF = null; public static void cleanup() { tempF = new File(tempDirectory); - try { - FileUtils.deleteDirectory(tempF); - } catch (Exception e) { - } - - while(!tempF.exists()) { //keep making dirs + while(tempF.exists()) { //delete dirs try { - tempF.mkdir(); - Thread.sleep(1); + FileUtils.deleteDirectory(tempF); } catch (Exception e) { } } + + while(!tempF.exists()) //keep making dirs + tempF.mkdir(); } public static String getBCVDirectory() { @@ -426,97 +445,97 @@ public class BytecodeViewer { public static void saveGUISettings() { try { DiskWriter.replaceFile(settingsName, "", false); - DiskWriter.writeNewLine(settingsName, ""+viewer.rbr.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.rsy.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.din.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.dc4.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.das.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hes.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hdc.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.dgs.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.ner.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.den.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.rgn.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.bto.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.nns.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.uto.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.udv.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.rer.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.fdi.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.asc.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.decodeenumswitch.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.sugarenums.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.decodestringswitch.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.arrayiter.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.collectioniter.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.innerclasses.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.removeboilerplate.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.removeinnerclasssynthetics.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.decodelambdas.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hidebridgemethods.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.liftconstructorinit.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.removedeadmethods.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.removebadgenerics.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.sugarasserts.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.sugarboxing.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.showversion.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.decodefinally.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.tidymonitors.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.lenient.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.dumpclasspath.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.comments.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forcetopsort.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forcetopsortaggress.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.stringbuffer.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.stringbuilder.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.silent.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.recover.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.eclipse.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.override.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.showinferrable.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.aexagg.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forcecondpropagate.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hideutf.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hidelongstrings.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.commentmonitor.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.allowcorrecting.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.labelledblocks.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.j14classobj.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hidelangimports.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.recoverytypeclash.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.recoverytypehints.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forceturningifs.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forloopaggcapture.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.forceexceptionprune.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmShowDebugLine.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmSimplifyMemberReferences.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.mnMergeVariables.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_1.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_2.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_3.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_4.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_5.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_6.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_7.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_8.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_9.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_10.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_11.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmAppendBrackets.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.sourcePane.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.bytecodePane.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.hexPane.isSelected(), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.rbr.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.rsy.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.din.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.dc4.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.das.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hes.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hdc.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.dgs.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.ner.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.den.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.rgn.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.bto.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.nns.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.uto.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.udv.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.rer.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.fdi.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.asc.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.decodeenumswitch.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.sugarenums.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.decodestringswitch.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.arrayiter.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.collectioniter.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.innerclasses.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.removeboilerplate.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.removeinnerclasssynthetics.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.decodelambdas.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hidebridgemethods.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.liftconstructorinit.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.removedeadmethods.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.removebadgenerics.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.sugarasserts.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.sugarboxing.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.showversion.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.decodefinally.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.tidymonitors.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.lenient.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.dumpclasspath.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.comments.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forcetopsort.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forcetopsortaggress.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.stringbuffer.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.stringbuilder.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.silent.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.recover.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.eclipse.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.override.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.showinferrable.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.aexagg.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forcecondpropagate.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hideutf.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hidelongstrings.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.commentmonitor.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.allowcorrecting.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.labelledblocks.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.j14classobj.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hidelangimports.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.recoverytypeclash.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.recoverytypehints.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forceturningifs.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forloopaggcapture.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.forceexceptionprune.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmShowDebugLine.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmSimplifyMemberReferences.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.mnMergeVariables.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_1.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_2.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_3.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_4.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_5.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_6.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_7.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_8.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_9.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_10.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_11.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmAppendBrackets.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.sourcePane.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.bytecodePane.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.hexPane.isSelected()), false); if(viewer.decompilerGroup.isSelected(viewer.procyonDec.getModel())) DiskWriter.writeNewLine(settingsName, "0", false); else if(viewer.decompilerGroup.isSelected(viewer.cfrDec.getModel())) DiskWriter.writeNewLine(settingsName, "1", false); else if(viewer.decompilerGroup.isSelected(viewer.fernflowerDec.getModel())) DiskWriter.writeNewLine(settingsName, "2", false); - DiskWriter.writeNewLine(settingsName, ""+viewer.debugHelpers.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem.isSelected(), false); - DiskWriter.writeNewLine(settingsName, ""+viewer.chckbxmntmNewCheckItem_12.isSelected(), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.debugHelpers.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem.isSelected()), false); + DiskWriter.writeNewLine(settingsName, String.valueOf(viewer.chckbxmntmNewCheckItem_12.isSelected()), false); } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } @@ -613,8 +632,33 @@ public class BytecodeViewer { viewer.chckbxmntmNewCheckItem.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 83, false))); viewer.chckbxmntmNewCheckItem_12.setSelected(Boolean.parseBoolean(DiskReader.loadString(settingsName, 84, false))); } catch(Exception e) { - e.printStackTrace(); + //ignore because errors are expected, first start up and outdated settings. } } + + public static ArrayList iconList; + public static BufferedImage icon = b642IMG("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"); + + public static BufferedImage resize(BufferedImage image, int width, int height) { + return Scalr.resize(image, Scalr.Method.ULTRA_QUALITY, width, height); + } + /** + * Decodes a Base64 String as a BufferedImage + */ + public static BufferedImage b642IMG(String imageString) { + BufferedImage image = null; + byte[] imageByte; + + try { + imageByte = Base64.decodeBase64(imageString); + ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); + image = ImageIO.read(bis); + bis.close(); + } catch (Exception e) { + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); + } + + return image; + } } diff --git a/src/the/bytecode/club/bytecodeviewer/FileDrop.java b/src/the/bytecode/club/bytecodeviewer/FileDrop.java index 15725c08..cc76c8c6 100644 --- a/src/the/bytecode/club/bytecodeviewer/FileDrop.java +++ b/src/the/bytecode/club/bytecodeviewer/FileDrop.java @@ -357,13 +357,13 @@ public class FileDrop { } // end try catch (final java.io.IOException io) { log(out, "FileDrop: IOException - abort:"); - io.printStackTrace(out); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(io); evt.rejectDrop(); } // end catch IOException catch (final java.awt.datatransfer.UnsupportedFlavorException ufe) { log(out, "FileDrop: UnsupportedFlavorException - abort:"); - ufe.printStackTrace(out); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ufe); evt.rejectDrop(); } // end catch: UnsupportedFlavorException finally { @@ -467,7 +467,7 @@ public class FileDrop { dt.addDropTargetListener(dropListener); } // end try catch (final java.util.TooManyListenersException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); log(out, "FileDrop: Drop will not work due to previous error. Do you have another listener attached?"); } // end catch diff --git a/src/the/bytecode/club/bytecodeviewer/JarUtils.java b/src/the/bytecode/club/bytecodeviewer/JarUtils.java index a4aff364..d5a4cfcb 100644 --- a/src/the/bytecode/club/bytecodeviewer/JarUtils.java +++ b/src/the/bytecode/club/bytecodeviewer/JarUtils.java @@ -101,7 +101,7 @@ public class JarUtils { out.close(); } catch (IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } @@ -128,7 +128,7 @@ public class JarUtils { out.close(); } catch (IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java b/src/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java index 06057244..02b5bf08 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/bytecode/InstructionPrinter.java @@ -218,7 +218,7 @@ public class InstructionPrinter { try { return nameOpcode(tin.getOpcode()) + " " + Type.getType(tin.desc).getClassName(); } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } return "//error"; } @@ -295,7 +295,7 @@ public class InstructionPrinter { } bw.close(); } catch (IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } } \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java index 9bd336b4..43c3dbce 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java @@ -46,7 +46,7 @@ public class CFRDecompiler extends JavaDecompiler { fos.close(); } catch (final IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } String fuckery = fuckery(fileStart); @@ -81,7 +81,7 @@ public class CFRDecompiler extends JavaDecompiler { try { s = DiskReader.loadAsString(f.getAbsolutePath()); } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"; } return s; @@ -205,7 +205,7 @@ public class CFRDecompiler extends JavaDecompiler { try { zip(fuck, new File(zipName)); } catch (IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } fuck.delete(); diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java index eb9ebb13..c30cd290 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java @@ -59,7 +59,7 @@ public class FernFlowerDecompiler extends JavaDecompiler { fos.close(); } catch (final IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), ".")); @@ -76,7 +76,7 @@ public class FernFlowerDecompiler extends JavaDecompiler { return s; } catch (Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"; diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java index 3e5660f8..718a1676 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java @@ -84,7 +84,7 @@ public class ProcyonDecompiler extends JavaDecompiler { fos.close(); } catch (final IOException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } @@ -109,7 +109,7 @@ public class ProcyonDecompiler extends JavaDecompiler { return decompiledSource; } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"; } @@ -125,7 +125,7 @@ public class ProcyonDecompiler extends JavaDecompiler { try { doSaveJarDecompiled(tempZip, new File(zipName)); } catch (Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } diff --git a/src/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java b/src/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java index f384975a..4c361bda 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/AboutWindow.java @@ -13,6 +13,7 @@ import java.awt.Color; public class AboutWindow extends JFrame { public AboutWindow() { + this.setIconImages(BytecodeViewer.iconList); setSize(new Dimension(446, 374)); setType(Type.UTILITY); setTitle("Bytecode Viewer - About"); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java index dd584493..8fb5ceba 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import static javax.swing.ScrollPaneConstants.*; +import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JPanel; @@ -113,25 +114,97 @@ public class ClassViewer extends JPanel { public JPanel bytePanel = new JPanel(new BorderLayout()); public JPanel decompPanel = new JPanel(new BorderLayout()); - public void search(int pane, String search) { + /** + * This was really interesting to write. + * + * @author Konloch + * + */ + public void search(int pane, String search, boolean next) { try { - if(pane == 0) { //bytecode - for(Component c : bytePanel.getComponents()) { + Component[] com = null; + if(pane == 0) //bytecode + com = bytePanel.getComponents(); + else if(pane == 1) + com = decompPanel.getComponents(); + + if(com == null) //someone fucked up, lets prevent a nullpointer. + return; + + for(Component c : com) { if(c instanceof RTextScrollPane) { RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0); + + if(search.isEmpty()) { + highlight(pane, area, ""); + return; + } + + int startLine = area.getDocument().getDefaultRootElement().getElementIndex(area.getCaretPosition())+1; + int currentLine = 1; + boolean canSearch = false; + String[] test = null; + if(area.getText().split("\n").length >= 2) + test = area.getText().split("\n"); + else + test = area.getText().split("\r"); + int lastGoodLine = -1; + int firstPos = -1; + boolean found = false; + + if(next) { + for(String s : test) { + if(currentLine == startLine) { + canSearch = true; + } else if(s.contains(search)) { + if(canSearch) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement().getElement(currentLine-1) + .getStartOffset()); + canSearch = false; + found = true; + } + + if(firstPos == -1) + firstPos = currentLine; + } + + currentLine++; + } + + if(!found && firstPos != -1) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement().getElement(firstPos-1) + .getStartOffset()); + } + } else { + canSearch = true; + for(String s : test) { + if(s.contains(search)) { + if(lastGoodLine != -1 && canSearch) + area.setCaretPosition(area.getDocument() + .getDefaultRootElement().getElement(lastGoodLine-1) + .getStartOffset()); + + lastGoodLine = currentLine; + + if(currentLine >= startLine) + canSearch = false; + } + currentLine++; + } + + if(lastGoodLine != -1 && area.getDocument().getDefaultRootElement().getElementIndex(area.getCaretPosition())+1 == startLine) { + area.setCaretPosition(area.getDocument() + .getDefaultRootElement().getElement(lastGoodLine-1) + .getStartOffset()); + } + } highlight(pane, area, search); } } - } else if(pane == 1) { //decomp - for(Component c : decompPanel.getComponents()) { - if(c instanceof RTextScrollPane) { - RSyntaxTextArea area = (RSyntaxTextArea) ((RTextScrollPane)c).getViewport().getComponent(0); - highlight(pane, area, search); - } - } - } } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } @@ -162,32 +235,56 @@ public class ClassViewer extends JPanel { pos += pattern.length(); } } catch (Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } public ClassViewer(final String name, final ClassNode cn) { - JButton byteSearch = new JButton("Search"); - bytePanelSearch.add(byteSearch, BorderLayout.WEST); + JButton byteSearchNext = new JButton(); + JButton byteSearchPrev = new JButton(); + JPanel byteButtonPane = new JPanel(new BorderLayout()); + byteButtonPane.add(byteSearchNext, BorderLayout.WEST); + byteButtonPane.add(byteSearchPrev, BorderLayout.EAST); + byteSearchNext.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg=="))); + byteSearchPrev.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg=="))); + bytePanelSearch.add(byteButtonPane, BorderLayout.WEST); final JTextField byteField = new JTextField(); bytePanelSearch.add(byteField, BorderLayout.CENTER); bytePanelSearch.add(byteCheck, BorderLayout.EAST); - byteSearch.addActionListener(new ActionListener() { + byteSearchNext.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent arg0) { - search(0,byteField.getText()); + search(0,byteField.getText(), true); + } + }); + byteSearchPrev.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + search(0,byteField.getText(), false); } }); - JButton decompSearch = new JButton("Search"); - decompPanelSearch.add(decompSearch, BorderLayout.WEST); + JButton decompSearchNext = new JButton(); + JButton decompSearchPrev = new JButton(); + JPanel decompButtonPane = new JPanel(new BorderLayout()); + decompButtonPane.add(decompSearchNext, BorderLayout.WEST); + decompButtonPane.add(decompSearchPrev, BorderLayout.EAST); + decompSearchNext.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYqPBJSG/ZAAAASUlEQVR42mNgwAbS0oAEE4yHyWBmYAzjYDC694OJ4f9+BoY3H0BSbz6A2MxA6VciFyDqGAWQTWVkYEkCUrcOsDD8OwtkvMViMwAb8xEUHlHcFAAAAABJRU5ErkJggg=="))); + decompSearchPrev.setIcon(new ImageIcon(BytecodeViewer.b642IMG("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEX///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAABnRSTlMANzlYgKhxpRi1AAAATElEQVR42mNgwAZYHIAEExA7qUAYLApMDmCGEwODCojByM/A8FEAyPi/moFh9QewYjCAM1iA+D2KqYwMrIlA6tUGFoa/Z4GMt1hsBgCe1wuKber+SwAAAABJRU5ErkJggg=="))); + decompPanelSearch.add(decompButtonPane, BorderLayout.WEST); final JTextField decompField = new JTextField(); decompPanelSearch.add(decompField, BorderLayout.CENTER); decompPanelSearch.add(decompCheck, BorderLayout.EAST); - decompSearch.addActionListener(new ActionListener() { + decompSearchNext.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent arg0) { - search(1,decompField.getText()); + search(1,decompField.getText(), true); + } + }); + decompSearchPrev.addActionListener(new ActionListener() { + @Override + public void actionPerformed(final ActionEvent arg0) { + search(1,decompField.getText(), false); } }); @@ -363,7 +460,6 @@ public class ClassViewer extends JPanel { return new IconView(elem); } - // default to text display return new LabelView(elem); } } diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java index f33aa7cd..cc4a2756 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -1,12 +1,13 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.imageio.ImageIO; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; +import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.BoxLayout; import javax.swing.JMenuBar; +import javax.swing.JOptionPane; import javax.swing.JSplitPane; import javax.swing.SwingUtilities; @@ -20,7 +21,6 @@ import javax.swing.JMenuItem; import javax.swing.JSeparator; import javax.swing.JCheckBoxMenuItem; -import org.apache.commons.codec.binary.Base64; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; @@ -37,8 +37,6 @@ import the.bytecode.club.bytecodeviewer.plugins.ZKMStringDecrypter; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.File; import java.util.ArrayList; @@ -209,7 +207,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { try { mntmNewMenuItem_4.setIcon(new ImageIcon(getClass().getResource("/resources/1.gif"))); } catch(NullPointerException e) { - mntmNewMenuItem_4.setIcon(new ImageIcon(b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"), "")); + mntmNewMenuItem_4.setIcon(new ImageIcon(BytecodeViewer.b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"), "")); } } else mntmNewMenuItem_4.setIcon(null); @@ -217,27 +215,9 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); } - - /** - * Decodes a Base64 String as a BufferedImage - */ - public BufferedImage b642IMG(String imageString) { - BufferedImage image = null; - byte[] imageByte; - - try { - imageByte = Base64.decodeBase64(imageString); - ByteArrayInputStream bis = new ByteArrayInputStream(imageByte); - image = ImageIO.read(bis); - bis.close(); - } catch (Exception e) { - e.printStackTrace(); - } - - return image; - } public MainViewerGUI() { + this.setIconImages(BytecodeViewer.iconList); decompilerGroup.add(fernflowerDec); decompilerGroup.add(procyonDec); decompilerGroup.add(cfrDec); @@ -335,7 +315,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { BytecodeViewer.openFiles(new File[]{fc.getSelectedFile()}); BytecodeViewer.viewer.setC(false); } catch (Exception e1) { - e1.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e1); } } }); @@ -424,6 +404,26 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu.add(chckbxmntmNewCheckItem_12); JMenuItem mntmExit = new JMenuItem("Exit"); + mntmExit.addActionListener(new ActionListener() { + @SuppressWarnings("deprecation") + public void actionPerformed(ActionEvent arg0) { + JOptionPane pane = new JOptionPane("Are you sure you want to exit?"); + Object[] options = new String[] { "Yes", "No" }; + pane.setOptions(options); + JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Exit"); + dialog.show(); + Object obj = pane.getValue(); + int result = -1; + for (int k = 0; k < options.length; k++) + if (options[k].equals(obj)) + result = k; + + + if(result == 0) { + System.exit(0); + } + } + }); mnNewMenu.add(mntmExit); JMenu mnView = new JMenu("View"); @@ -611,8 +611,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public void actionPerformed(ActionEvent arg0) { if(!BytecodeViewer.loadedClasses.isEmpty()) new ReplaceStringsOptions().setVisible(true); - else + else { System.out.println("Plugin not ran, put some classes in first."); + BytecodeViewer.showMessage("Plugin not ran, put some classes in first."); + } } }); @@ -637,7 +639,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { BytecodeViewer.startPlugin(fc.getSelectedFile()); BytecodeViewer.viewer.setC(false); } catch (Exception e1) { - e1.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e1); } } }); @@ -655,8 +657,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public void actionPerformed(ActionEvent e) { if(!BytecodeViewer.loadedClasses.isEmpty()) new MaliciousCodeScannerOptions().setVisible(true); - else + else { System.out.println("Plugin not ran, put some classes in first."); + BytecodeViewer.showMessage("Plugin not ran, put some classes in first."); + } } }); mntmShowAllStrings.addActionListener(new ActionListener() { diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java b/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java index e3342a9d..7cbbf7e6 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java @@ -7,6 +7,7 @@ import java.awt.Dimension; import javax.swing.JCheckBox; import javax.swing.JButton; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.plugins.MaliciousCodeScanner; import the.bytecode.club.bytecodeviewer.plugins.PluginManager; @@ -15,6 +16,7 @@ import java.awt.event.ActionEvent; public class MaliciousCodeScannerOptions extends JFrame { public MaliciousCodeScannerOptions() { + this.setIconImages(BytecodeViewer.iconList); setSize(new Dimension(250, 277)); setResizable(false); setTitle("Malicious Code Scanner Options"); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java b/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java index 01097727..c0963af1 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java @@ -1,20 +1,24 @@ package the.bytecode.club.bytecodeviewer.gui; import java.awt.Dimension; + import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTextField; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.plugins.PluginManager; import the.bytecode.club.bytecodeviewer.plugins.ReplaceStrings; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; + import javax.swing.JCheckBox; public class ReplaceStringsOptions extends JFrame { public ReplaceStringsOptions() { + this.setIconImages(BytecodeViewer.iconList); setSize(new Dimension(250, 176)); setResizable(false); setTitle("Replace Strings"); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/StackTraceUI.java b/src/the/bytecode/club/bytecodeviewer/gui/StackTraceUI.java new file mode 100644 index 00000000..1f4d2b09 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/gui/StackTraceUI.java @@ -0,0 +1,40 @@ +package the.bytecode.club.bytecodeviewer.gui; + +import javax.swing.JFrame; +import javax.swing.JScrollPane; + +import java.awt.Dimension; +import java.awt.CardLayout; + +import javax.swing.JTextArea; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + +import java.awt.Color; +import java.io.PrintWriter; +import java.io.StringWriter; + +public class StackTraceUI extends JFrame { + + public StackTraceUI(Exception e) { + this.setIconImages(BytecodeViewer.iconList); + setSize(new Dimension(600, 400)); + setTitle("Bytecode Viewer "+BytecodeViewer.version+" - Stack Trace - Send this to @Konloch."); + getContentPane().setLayout(new CardLayout(0, 0)); + + JTextArea txtrBytecodeViewerIs = new JTextArea(); + txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK); + txtrBytecodeViewerIs.setWrapStyleWord(true); + getContentPane().add(new JScrollPane(txtrBytecodeViewerIs), "name_140466576080695"); + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + e.printStackTrace(); + + txtrBytecodeViewerIs.setText(sw.toString()); + this.setLocationRelativeTo(null); + this.setVisible(true); + } + + private static final long serialVersionUID = -5230501978224926296L; + +} diff --git a/src/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java b/src/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java index 0d154cf4..7af9392c 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/TabbedPane.java @@ -34,7 +34,8 @@ public class TabbedPane extends JPanel { private static final long serialVersionUID = -4774885688297538774L; private final JTabbedPane pane; final JButton button = new TabButton(); - + private static long zero = System.currentTimeMillis(); + public TabbedPane(final JTabbedPane pane) { //unset default FlowLayout' gaps super(new FlowLayout(FlowLayout.LEFT, 0, 0)); @@ -63,46 +64,22 @@ public class TabbedPane extends JPanel { add(button); //add more space to the top of the component setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0)); - pane.addMouseListener(new MouseListener() { + button.addMouseListener(new MouseListener() { @Override - public void mouseClicked(MouseEvent arg0) { + public void mouseClicked(MouseEvent e) { + if(e.getModifiers() == 8) { + if(System.currentTimeMillis()-zero >= 500) { + zero = System.currentTimeMillis(); + final int i = pane.indexOfTabComponent(TabbedPane.this); + if (i != -1) + pane.remove(i); + } + } } - @Override - public void mouseEntered(MouseEvent arg0) { - } - @Override - public void mouseExited(MouseEvent arg0) { - } - @Override - public void mousePressed(MouseEvent arg0) { - } - @Override - public void mouseReleased(MouseEvent e) { - //final Component component = e.getComponent(); - // if(component instanceof JTabbedPane) { - if(e.getModifiers() == 8) { - for(Component c : pane.getComponents()) { - if(c.getMousePosition() != null && c instanceof JPanel) { - System.out.println("gotten here..."); - /*BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.remove(component); - final int i = BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.indexOfTabComponent(c); - if (i != -1) - BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.remove(i); - BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.updateUI(); - BytecodeViewer.viewer.getComponent(WorkPane.class).tabs.repaint(); - *////if(c.getComponentAt((int)c.getMousePosition().getX(), (int)c.getMousePosition().getY())button.) - // button.doClick(); - } - - //System.out.println(c.getMousePosition() + ":" + e.getX()); - //System.out.println(c.getWidth() + ":" + e.getX()); - //if( e.getX() >= && - // e.getY()) - // button.doClick(); - } - } - } - //} + @Override public void mouseEntered(MouseEvent arg0) {} + @Override public void mouseExited(MouseEvent arg0) {} + @Override public void mousePressed(MouseEvent arg0) {} + @Override public void mouseReleased(MouseEvent e) {} }); } diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java b/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java index 6a3cd954..e08c5ac4 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java @@ -17,9 +17,6 @@ public class AllatoriStringDecrypter extends Plugin { @Override public void execute(ArrayList classNodeList) { - for(ClassNode classNode : classNodeList) { - - } BytecodeViewer.showMessage("This is a planned feature."); } diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java b/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java index 23b95ab9..fd000367 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java @@ -4,11 +4,14 @@ import java.util.ArrayList; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + /** * The idea/core was based off of J-RET's Malicious Code Searcher * I improved it, and added more stuff to search for. @@ -45,7 +48,35 @@ public class MaliciousCodeScanner extends Plugin { @Override public void execute(ArrayList classNodeList) { PluginConsole frame = new PluginConsole("Malicious Code Scanner"); + StringBuilder sb = new StringBuilder(); for(ClassNode classNode : classNodeList) { + for(Object o : classNode.fields.toArray()) { + FieldNode f = (FieldNode) o; + Object v = f.value; + if(v instanceof String) { + String s = (String)v; + if ((LWW && s.contains("www.")) || + (LHT && s.contains("http://")) || + (LHS && s.contains("https://")) || + (ORE && s.contains("java/lang/Runtime")) || + (ORE && s.contains("java.lang.Runtime")) || + (LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b"))) + sb.append("Found LDC \"" + s + "\" at field " + classNode.name + "." +f.name+"("+f.desc+")"+BytecodeViewer.nl); + } + if(v instanceof String[]) { + for(int i = 0; i < ((String[])v).length; i++) { + String s = ((String[])v)[i]; + if ((LWW && s.contains("www.")) || + (LHT && s.contains("http://")) || + (LHS && s.contains("https://")) || + (ORE && s.contains("java/lang/Runtime")) || + (ORE && s.contains("java.lang.Runtime")) || + (LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b"))) + sb.append("Found LDC \"" + s + "\" at field " + classNode.name + "." +f.name+"("+f.desc+")"+BytecodeViewer.nl); + } + } + } + for(Object o : classNode.methods.toArray()) { MethodNode m = (MethodNode) o; @@ -58,7 +89,7 @@ public class MaliciousCodeScanner extends Plugin { (ORU && min.owner.equals("java/lang/Runtime")) || (OIO && min.owner.startsWith("java/io"))) { - frame.appendText("Found Method call to " + min.owner + "." + min.name + "(" + min.desc + ") at " + classNode.name + "." +m.name+"("+m.desc+")"); + sb.append("Found Method call to " + min.owner + "." + min.name + "(" + min.desc + ") at " + classNode.name + "." +m.name+"("+m.desc+")"+BytecodeViewer.nl); } } if (a instanceof LdcInsnNode) { @@ -71,13 +102,15 @@ public class MaliciousCodeScanner extends Plugin { (ORE && s.contains("java.lang.Runtime")) || (LIP && s.matches("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b"))) { - frame.appendText("Found LDC \"" + s + "\" at " + classNode.name + "." +m.name+"("+m.desc+")"); + sb.append("Found LDC \"" + s + "\" at method " + classNode.name + "." +m.name+"("+m.desc+")"+BytecodeViewer.nl); } } } } } } + + frame.appendText(sb.toString()); frame.setVisible(true); } diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/Plugin.java b/src/the/bytecode/club/bytecodeviewer/plugins/Plugin.java index 6286a3f9..3edbee61 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/Plugin.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/Plugin.java @@ -21,10 +21,12 @@ public abstract class Plugin extends Thread { try { if(!BytecodeViewer.getLoadedClasses().isEmpty()) execute(BytecodeViewer.getLoadedClasses()); - else + else { System.out.println("Plugin not ran, put some classes in first."); + BytecodeViewer.showMessage("Plugin not ran, put some classes in first."); + } } catch(Exception e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } finally { finished = true; BytecodeViewer.viewer.setIcon(false); diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/PluginConsole.java b/src/the/bytecode/club/bytecodeviewer/plugins/PluginConsole.java index d0e6c1e1..f010b9c5 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/PluginConsole.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/PluginConsole.java @@ -1,11 +1,17 @@ package the.bytecode.club.bytecodeviewer.plugins; import javax.swing.JFrame; + import java.awt.Dimension; + import javax.swing.JScrollPane; + import java.awt.BorderLayout; + import javax.swing.JTextArea; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + /** * A simple console GUI. * @@ -16,6 +22,7 @@ import javax.swing.JTextArea; public class PluginConsole extends JFrame { JTextArea textArea = new JTextArea(); public PluginConsole(String pluginName) { + this.setIconImages(BytecodeViewer.iconList); setTitle("Bytecode Viewer - Plugin Console - " + pluginName); setSize(new Dimension(542, 316)); @@ -28,7 +35,7 @@ public class PluginConsole extends JFrame { public void appendText(String t) { textArea.setText((textArea.getText().isEmpty() ? "" : textArea.getText()+"\r\n")+t); - textArea.setCaretPosition(textArea.getLineCount()); + textArea.setCaretPosition(0); } private static final long serialVersionUID = -6556940545421437508L; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java b/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java index 126abb52..e3da8255 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java @@ -9,6 +9,8 @@ import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.LdcInsnNode; import org.objectweb.asm.tree.MethodNode; +import the.bytecode.club.bytecodeviewer.BytecodeViewer; + /** * Simply shows all the non-empty strings in every single class * @@ -21,6 +23,7 @@ public class ShowAllStrings extends Plugin { @Override public void execute(ArrayList classNodeList) { PluginConsole frame = new PluginConsole("Show All Strings"); + StringBuilder sb = new StringBuilder(); for(ClassNode classNode : classNodeList) { for(Object o : classNode.fields.toArray()) { FieldNode f = (FieldNode) o; @@ -28,13 +31,13 @@ public class ShowAllStrings extends Plugin { if(v instanceof String) { String s = (String)v; if(!s.isEmpty()) - frame.appendText(classNode.name + "." +f.name+""+f.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""); + sb.append(classNode.name + "." +f.name+""+f.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl); } if(v instanceof String[]) { for(int i = 0; i < ((String[])v).length; i++) { String s = ((String[])v)[i]; if(!s.isEmpty()) - frame.appendText(classNode.name + "." +f.name+""+f.desc+"["+i+"] -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""); + sb.append(classNode.name + "." +f.name+""+f.desc+"["+i+"] -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl); } } } @@ -48,12 +51,14 @@ public class ShowAllStrings extends Plugin { if(((LdcInsnNode)a).cst instanceof String) { final String s = (String) ((LdcInsnNode)a).cst; if(!s.isEmpty()) - frame.appendText(classNode.name + "." +m.name+""+m.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""); + sb.append(classNode.name + "." +m.name+""+m.desc+" -> \"" + s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r") + "\""+BytecodeViewer.nl); } } } } } + + frame.appendText(sb.toString()); frame.setVisible(true); } diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java b/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java index 5042332a..2b0aa958 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java +++ b/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java @@ -17,9 +17,6 @@ public class ZKMStringDecrypter extends Plugin { @Override public void execute(ArrayList classNodeList) { - for(ClassNode classNode : classNodeList) { - - } BytecodeViewer.showMessage("This is a planned feature."); } diff --git a/src/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java b/src/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java index f80a94ba..6d7d6f3e 100644 --- a/src/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java +++ b/src/the/bytecode/club/bytecodeviewer/searching/RegexInsnFinder.java @@ -223,7 +223,7 @@ public class RegexInsnFinder { "Unknown opcode encountered: " + ain.getOpcode()); } catch (final UnexpectedException e) { - e.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(e); } } offsets[i] = insnString.length(); @@ -309,7 +309,7 @@ public class RegexInsnFinder { if (regexMatcher.find()) return makeResult(regexMatcher.start(), regexMatcher.end()); } catch (final PatternSyntaxException ex) { - ex.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex); } return new AbstractInsnNode[0]; } @@ -328,7 +328,7 @@ public class RegexInsnFinder { results.add(makeResult(regexMatcher.start(), regexMatcher.end())); } } catch (final PatternSyntaxException ex) { - ex.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex); } return results; } @@ -350,7 +350,7 @@ public class RegexInsnFinder { return result; } } catch (final PatternSyntaxException ex) { - ex.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex); } return new AbstractInsnNode[0][0]; } @@ -373,7 +373,7 @@ public class RegexInsnFinder { results.add(result); } } catch (final PatternSyntaxException ex) { - ex.printStackTrace(); + new the.bytecode.club.bytecodeviewer.gui.StackTraceUI(ex); } return results; }