diff --git a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index 2fd9f02c..66bca8b1 100644 --- a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -39,6 +39,7 @@ import the.bytecode.club.bytecodeviewer.gui.SearchingPane; import the.bytecode.club.bytecodeviewer.gui.SystemErrConsole; import the.bytecode.club.bytecodeviewer.gui.WorkPane; import the.bytecode.club.bytecodeviewer.obfuscators.mapping.Refactorer; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; /** * A lightweight Java Reverse Engineering suite, developed by Konloch - @@ -662,18 +663,18 @@ public class BytecodeViewer { /** * Starts the specified plugin - * @param plugin the file of the plugin + * @param file the file of the plugin */ - public static void startPlugin(File plugin) { - if (!plugin.exists()) + public static void startPlugin(File file) { + if (!file.exists()) return; try { - PluginManager.runPlugin(plugin); - } catch (Exception e) { + PluginManager.runPlugin(file); + } catch (Throwable e) { new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); } - addRecentPlugin(plugin); + addRecentPlugin(file); } /** @@ -786,6 +787,7 @@ public class BytecodeViewer { if (!s.isEmpty()) { JMenuItem m = new JMenuItem(s); m.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { JMenuItem m = (JMenuItem) e.getSource(); openFiles(new File[] { new File(m.getText()) }, true); @@ -798,6 +800,7 @@ public class BytecodeViewer { if (!s.isEmpty()) { JMenuItem m = new JMenuItem(s); m.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { JMenuItem m = (JMenuItem) e.getSource(); startPlugin(new File(m.getText())); diff --git a/src/the/bytecode/club/bytecodeviewer/MiscUtils.java b/src/the/bytecode/club/bytecodeviewer/MiscUtils.java index cb67153e..f7682612 100644 --- a/src/the/bytecode/club/bytecodeviewer/MiscUtils.java +++ b/src/the/bytecode/club/bytecodeviewer/MiscUtils.java @@ -79,4 +79,8 @@ public class MiscUtils { } return i; } + + public static String extension(String name) { + return name.substring(name.lastIndexOf('.') + 1); + } } diff --git a/src/the/bytecode/club/bytecodeviewer/PluginManager.java b/src/the/bytecode/club/bytecodeviewer/PluginManager.java deleted file mode 100644 index c7d6bff1..00000000 --- a/src/the/bytecode/club/bytecodeviewer/PluginManager.java +++ /dev/null @@ -1,155 +0,0 @@ -package the.bytecode.club.bytecodeviewer; - -import java.io.File; -import java.io.FileReader; -import java.io.Reader; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; - -import me.konloch.kontainer.io.DiskReader; - -import org.codehaus.janino.*; - -import the.bytecode.club.bytecodeviewer.api.Plugin; - -/** - * Supports loading of groovy, python or ruby scripts. - * - * Only allows one plugin to be running at once. - * - * @author Konloch - * - */ - -public class PluginManager { - - private static Plugin pluginInstance; - private static SimpleCompiler compiler = new SimpleCompiler(); - - /** - * Runs a new plugin instance - * @param newPluginInstance the new plugin instance - */ - public static void runPlugin(Plugin newPluginInstance) { - if (pluginInstance == null || pluginInstance.isFinished()) { - pluginInstance = newPluginInstance; - pluginInstance.start(); // start the thread - } else if (!pluginInstance.isFinished()) { - BytecodeViewer.showMessage("There is currently another plugin running right now, please wait for that to finish executing."); - } - } - - /** - * Starts and runs a plugin from file - * @param f the file of the plugin - * @throws Exception - */ - public static void runPlugin(File f) throws Exception { - Plugin p = null; - if (f.getName().endsWith(".java")) { - p = loadJavaScript(f); - } - if (f.getName().endsWith(".gy") || f.getName().endsWith(".groovy")) { - p = loadGroovyScript(f); - } - if (f.getName().endsWith(".py") || f.getName().endsWith(".python")) { - p = loadPythonScript(f); - } - if (f.getName().endsWith(".rb") || f.getName().endsWith(".ruby")) { - p = loadRubyScript(f); - } - if (p != null) { - runPlugin(p); - } - } - - /** - * Loads a Java file as a Script - * - * @param file - * @return - * @throws Exception - */ - private static Plugin loadJavaScript(File file) throws Exception { - compiler.cook(DiskReader.loadAsString(file.getAbsolutePath())); - - System.out.println(file.getName().substring(0,(int)(file.getName().length()-(".java".length())))); - Class clazz = (Class) Class.forName( - file.getName().substring(0,(int)file.getName().length()-".java".length()), - true, - compiler.getClassLoader() - ); - - return (Plugin) clazz.newInstance(); - } - - /** - * Loads a groovy file as a Script - * - * @param file - * @return - * @throws Exception - */ - private static Plugin loadGroovyScript(File file) throws Exception { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("groovy"); - - if (engine == null) - throw new Exception( - "Cannot find Groovy script engine! Please contact Konloch."); - - Reader reader = new FileReader(file); - engine.eval(reader); - - return (Plugin) engine.eval("new " - + file.getName().replace(".gy", "").replace(".groovy", "") - + "();"); - } - - /** - * Loads a python file as a Script - * - * @param file - * @return - * @throws Exception - */ - private static Plugin loadPythonScript(File file) throws Exception { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("python"); - - if (engine == null) - throw new Exception( - "Cannot find Jython script engine! Please contact Konloch."); - - Reader reader = new FileReader(file); - engine.eval(reader); - - return (Plugin) engine.eval(file.getName().replace(".py", "") - .replace(".python", "") - + "()"); - } - - /** - * Loads a ruby file as a Script - * - * @param file - * @return - * @throws Exception - */ - private static Plugin loadRubyScript(File file) throws Exception { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine engine = manager.getEngineByName("jruby"); - - if (engine == null) - throw new Exception( - "Cannot find jRuby script engine! Please contact Konloch."); - - Reader reader = new FileReader(file); - engine.eval(reader); - - return (Plugin) engine.eval(file.getName().replace(".rb", "") - .replace(".ruby", "") - + ".new"); - } -} diff --git a/src/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java b/src/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java index a00c07f1..7aad1371 100644 --- a/src/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/api/BytecodeViewer.java @@ -13,7 +13,7 @@ import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; -import the.bytecode.club.bytecodeviewer.plugins.EZInjection; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; /** * The official API for BCV, this was designed for plugin authors and diff --git a/src/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java b/src/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java index e9a70da5..c7f5ce59 100644 --- a/src/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java +++ b/src/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java @@ -1,20 +1,18 @@ package the.bytecode.club.bytecodeviewer.api; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.io.PrintWriter; +import java.io.StringWriter; + import javax.swing.JFrame; import javax.swing.JScrollPane; - -import java.awt.Dimension; -import java.awt.CardLayout; - import javax.swing.JTextArea; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Resources; -import java.awt.Color; -import java.io.PrintWriter; -import java.io.StringWriter; - /** * A simple class designed to show exceptions in the UI. * @@ -30,7 +28,7 @@ public class ExceptionUI extends JFrame { * @param e * The exception to be shown */ - public ExceptionUI(Exception e) { + public ExceptionUI(Throwable e) { setup(e, "@Konloch - konloch@gmail.com"); } @@ -48,7 +46,7 @@ public class ExceptionUI extends JFrame { * @param author * the author of the plugin throwing this exception. */ - public ExceptionUI(Exception e, String author) { + public ExceptionUI(Throwable e, String author) { setup(e, author); } @@ -62,7 +60,7 @@ public class ExceptionUI extends JFrame { setup(e, author); } - private void setup(Exception e, String author) { + private void setup(Throwable e, String author) { this.setIconImages(Resources.iconList); setSize(new Dimension(600, 400)); diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java index a097560c..cbab4412 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -1,30 +1,34 @@ package the.bytecode.club.bytecodeviewer.gui; -import javax.swing.ButtonGroup; -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; - import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Frame; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.File; +import java.util.ArrayList; -import javax.swing.filechooser.FileFilter; -import javax.swing.JMenu; -import javax.swing.JMenuItem; -import javax.swing.JSeparator; +import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSeparator; +import javax.swing.JSplitPane; +import javax.swing.SwingUtilities; +import javax.swing.filechooser.FileFilter; import org.objectweb.asm.tree.ClassNode; @@ -32,24 +36,23 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Dex2Jar; import the.bytecode.club.bytecodeviewer.FileChangeNotifier; import the.bytecode.club.bytecodeviewer.JarUtils; -import the.bytecode.club.bytecodeviewer.PluginManager; +import the.bytecode.club.bytecodeviewer.MiscUtils; import the.bytecode.club.bytecodeviewer.Resources; import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler; -import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.Decompiler; +import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.KrakatauDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameClasses; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameFields; import the.bytecode.club.bytecodeviewer.obfuscators.rename.RenameMethods; -import the.bytecode.club.bytecodeviewer.plugins.*; - -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; -import java.io.File; -import java.util.ArrayList; - -import javax.swing.JRadioButtonMenuItem; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; +import the.bytecode.club.bytecodeviewer.plugins.AllatoriStringDecrypter; +import the.bytecode.club.bytecodeviewer.plugins.CodeSequenceDiagram; +import the.bytecode.club.bytecodeviewer.plugins.ShowAllStrings; +import the.bytecode.club.bytecodeviewer.plugins.ShowMainMethods; +import the.bytecode.club.bytecodeviewer.plugins.ZKMStringDecrypter; +import the.bytecode.club.bytecodeviewer.plugins.ZStringArrayDecrypter; /** * The main file for the GUI.n @@ -57,7 +60,6 @@ import javax.swing.JRadioButtonMenuItem; * @author Konloch * */ - public class MainViewerGUI extends JFrame implements FileChangeNotifier { public void pythonC() { @@ -468,6 +470,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public final JRadioButtonMenuItem panel3Hexcode = new JRadioButtonMenuItem("Hexcode"); public void setIcon(final boolean busy) { SwingUtilities.invokeLater(new Runnable() { + @Override public void run() { if (busy) { try { @@ -491,7 +494,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_5.setVisible(false); KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new Test()); this.addWindowStateListener(new WindowAdapter() { - public void windowStateChanged(WindowEvent evt) { + @Override + public void windowStateChanged(WindowEvent evt) { int oldState = evt.getOldState(); int newState = evt.getNewState(); @@ -537,6 +541,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { menuBar.add(mnNewMenu); mntmNewWorkspace.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { BytecodeViewer.resetWorkSpace(true); } @@ -544,6 +549,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { JMenuItem mntmLoadJar = new JMenuItem("Add.."); mntmLoadJar.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); try { @@ -577,6 +583,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { JMenuItem mntmSave = new JMenuItem("Save Files As.."); mntmSave.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -633,6 +640,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu.add(separator_3); mntmNewMenuItem_3.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -677,11 +685,13 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); mntmNewMenuItem_13.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { BytecodeViewer.compile(true); } }); mntmRun.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -699,6 +709,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu.add(mntmNewMenuItem_3); mntmSaveAsApk.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -765,6 +776,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu.add(mntmSaveAsApk); mnNewMenu.add(mntmSave); mntmNewMenuItem.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -886,6 +898,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); mntmNewMenuItem_12.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(workPane.getCurrentViewer() == null) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -1022,6 +1035,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { JSeparator separator_1 = new JSeparator(); mnNewMenu.add(separator_1); mntmAbout.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { aboutWindow.setVisible(true); } @@ -1031,6 +1045,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { JMenuItem mntmExit = new JMenuItem("Exit"); mntmExit.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { JOptionPane pane = new JOptionPane( "Are you sure you want to exit?"); @@ -1051,6 +1066,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); mntmPingback.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { BytecodeViewer.pingback(); } @@ -1244,6 +1260,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnSettings.add(separator_13); mntmSetPythonDirectory.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { pythonC(); } @@ -1251,6 +1268,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnSettings.add(mntmSetPythonDirectory); mntmSetJreRt.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { rtC(); } @@ -1258,6 +1276,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnSettings.add(mntmSetJreRt); mntmSetOpitonalLibrary.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { library(); } @@ -1482,6 +1501,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { menuBar.add(mnNewMenu_5); mntmNewMenuItem_6.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if (BytecodeViewer.runningObfuscation) { BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); @@ -1504,6 +1524,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_5.add(mntmNewMenuItem_6); mntmNewMenuItem_7.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if (BytecodeViewer.runningObfuscation) { BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); @@ -1517,6 +1538,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_5.add(mntmNewMenuItem_7); mntmNewMenuItem_11.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if (BytecodeViewer.runningObfuscation) { BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish."); @@ -1542,6 +1564,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_1.add(mnRecentPlugins); mnNewMenu_1.add(separator_5); mntmCodeSequenceDiagram.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -1556,6 +1579,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_1.add(mntmShowMainMethods); mnNewMenu_1.add(mntmShowAllStrings); mntmReplaceStrings.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -1569,6 +1593,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { mnNewMenu_1.add(mntmNewMenuItem_2); mnNewMenu_1.add(mntmStartZkmString); mntmZstringarrayDecrypter.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { PluginManager.runPlugin(new ZStringArrayDecrypter()); } @@ -1579,9 +1604,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { menuBar.add(mntmNewMenuItem_4); mntmStartExternalPlugin.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent arg0) { JFileChooser fc = new JFileChooser(); - fc.setFileFilter(new JavaPFileFilter()); + /* 01/06/15, 14:32, Changed to plugin file filter rather from the + * only .java filter. */ + fc.setFileFilter(PluginManager.fileFilter()); fc.setFileHidingEnabled(false); fc.setAcceptAllFileFilterUsed(false); int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); @@ -1597,16 +1625,19 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); mntmStartZkmString.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { PluginManager.runPlugin(new ZKMStringDecrypter()); } }); mntmNewMenuItem_2.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { PluginManager.runPlugin(new AllatoriStringDecrypter()); } }); mntmNewMenuItem_1.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { if(BytecodeViewer.getLoadedClasses().isEmpty()) { BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); @@ -1616,12 +1647,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { } }); mntmShowAllStrings.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { PluginManager.runPlugin(new ShowAllStrings()); } }); mntmShowMainMethods.addActionListener(new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { PluginManager.runPlugin(new ShowMainMethods()); } @@ -1738,13 +1771,15 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { return null; } + /* 01/06/15, 14:33 changed by Bibl. */ + public class GroovyPythonRubyFileFilter extends FileFilter { @Override public boolean accept(File f) { if (f.isDirectory()) return true; - String extension = getExtension(f); + String extension = MiscUtils.extension(f.getAbsolutePath()); if (extension != null) return (extension.equals("gy") || extension.equals("groovy") || extension.equals("py") || extension.equals("python") @@ -1757,27 +1792,15 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public String getDescription() { return "Groovy, Python or Ruby plugins."; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } - public class GroovyFileFilter extends FileFilter { @Override public boolean accept(File f) { if (f.isDirectory()) return true; - String extension = getExtension(f); + String extension = MiscUtils.extension(f.getAbsolutePath()); if (extension != null) return (extension.equals("gy") || extension.equals("groovy")); @@ -1788,25 +1811,15 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public String getDescription() { return "Groovy plugins."; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } + public class APKDEXJarZipClassFileFilter extends FileFilter { @Override public boolean accept(File f) { if (f.isDirectory()) return true; - String extension = getExtension(f); + String extension = MiscUtils.extension(f.getAbsolutePath()); if (extension != null) if (extension.equals("jar") || extension.equals("zip") || extension.equals("class") || extension.equals("apk") @@ -1820,167 +1833,54 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { public String getDescription() { return "APKs, DEX, Class Files or Zip/Jar Archives"; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } public class ZipFileFilter extends FileFilter { @Override public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = getExtension(f); - if (extension != null) - return (extension.equals("zip")); - - return false; + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("zip"); } @Override public String getDescription() { return "Zip Archives"; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } public class JarFileFilter extends FileFilter { @Override public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = getExtension(f); - if (extension != null) - return (extension.equals("jar")); - - return false; + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("jar"); } @Override public String getDescription() { return "Jar Archives"; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } public class JavaFileFilter extends FileFilter { @Override public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = getExtension(f); - if (extension != null) - return (extension.equals("java")); - - return false; + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("java"); } @Override public String getDescription() { return "Java Source Files"; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } - } - - public class JavaPFileFilter extends FileFilter { - @Override - public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = getExtension(f); - if (extension != null) - return (extension.equals("java")); - - return false; - } - - @Override - public String getDescription() { - return "Java Plugins"; - } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } public class DexFileFilter extends FileFilter { @Override public boolean accept(File f) { - if (f.isDirectory()) - return true; - - String extension = getExtension(f); - if (extension != null) - return (extension.equals("dex")); - - return false; + return f.isDirectory() || MiscUtils.extension(f.getAbsolutePath()).equals("dex"); } @Override public String getDescription() { return "Android DEX Files"; } - - public String getExtension(File f) { - String ext = null; - String s = f.getName(); - int i = s.lastIndexOf('.'); - - if (i > 0 && i < s.length() - 1) - ext = s.substring(i + 1).toLowerCase(); - - return ext; - } } public class PythonCFileFilter extends FileFilter { diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java b/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java index 2bc49060..ee067f78 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MaliciousCodeScannerOptions.java @@ -7,9 +7,9 @@ import java.awt.Dimension; import javax.swing.JCheckBox; import javax.swing.JButton; -import the.bytecode.club.bytecodeviewer.PluginManager; import the.bytecode.club.bytecodeviewer.Resources; -import the.bytecode.club.bytecodeviewer.plugins.MaliciousCodeScanner; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.MaliciousCodeScanner; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; diff --git a/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java b/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java index cdaef185..cf63fdee 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/ReplaceStringsOptions.java @@ -7,9 +7,9 @@ import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JTextField; -import the.bytecode.club.bytecodeviewer.PluginManager; import the.bytecode.club.bytecodeviewer.Resources; -import the.bytecode.club.bytecodeviewer.plugins.ReplaceStrings; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ReplaceStrings; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; diff --git a/src/the/bytecode/club/bytecodeviewer/gui/RunOptions.java b/src/the/bytecode/club/bytecodeviewer/gui/RunOptions.java index 6e016802..9d3f5a1d 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/RunOptions.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/RunOptions.java @@ -8,9 +8,9 @@ import javax.swing.JCheckBox; import javax.swing.JButton; import the.bytecode.club.bytecodeviewer.BytecodeViewer; -import the.bytecode.club.bytecodeviewer.PluginManager; import the.bytecode.club.bytecodeviewer.Resources; -import the.bytecode.club.bytecodeviewer.plugins.EZInjection; +import the.bytecode.club.bytecodeviewer.plugin.PluginManager; +import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java new file mode 100644 index 00000000..2eb6e650 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/PluginLaunchStrategy.java @@ -0,0 +1,14 @@ +package the.bytecode.club.bytecodeviewer.plugin; + +import java.io.File; + +import the.bytecode.club.bytecodeviewer.api.Plugin; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public abstract interface PluginLaunchStrategy { + + public abstract Plugin run(File file) throws Throwable; +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java b/src/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java new file mode 100644 index 00000000..ad9ced0e --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java @@ -0,0 +1,128 @@ +package the.bytecode.club.bytecodeviewer.plugin; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.swing.filechooser.FileFilter; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.MiscUtils; +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.strategies.CompiledJavaPluginLaunchStrategy; +import the.bytecode.club.bytecodeviewer.plugin.strategies.GroovyPluginLaunchStrategy; +import the.bytecode.club.bytecodeviewer.plugin.strategies.JavaPluginLaunchStrategy; +import the.bytecode.club.bytecodeviewer.plugin.strategies.PythonPluginLaunchStrategy; +import the.bytecode.club.bytecodeviewer.plugin.strategies.RubyPluginLaunchStrategy; + +/** + * Supports loading of groovy, python or ruby scripts. + * + * Only allows one plugin to be running at once. + * + * @author Konloch + * @author Bibl + * + * @since 01/16/16, 14:36, Adaptable PluginLaunchStrategy system. + */ +public final class PluginManager { + + private static final Map launchStrategies = new HashMap(); + private static final PluginFileFilter filter = new PluginFileFilter(); + private static Plugin pluginInstance; + + static { + launchStrategies.put("jar", new CompiledJavaPluginLaunchStrategy()); + launchStrategies.put("java", new JavaPluginLaunchStrategy()); + + GroovyPluginLaunchStrategy groovy = new GroovyPluginLaunchStrategy(); + launchStrategies.put("gy", groovy); + launchStrategies.put("groovy", groovy); + + PythonPluginLaunchStrategy python = new PythonPluginLaunchStrategy(); + launchStrategies.put("py", python); + launchStrategies.put("python", python); + + RubyPluginLaunchStrategy ruby = new RubyPluginLaunchStrategy(); + launchStrategies.put("rb", ruby); + launchStrategies.put("ruby", ruby); + } + + /** + * Runs a new plugin instance + * @param newPluginInstance the new plugin instance + */ + public static void runPlugin(Plugin newPluginInstance) { + if (pluginInstance == null || pluginInstance.isFinished()) { + pluginInstance = newPluginInstance; + pluginInstance.start(); // start the thread + } else if (!pluginInstance.isFinished()) { + BytecodeViewer.showMessage("There is currently another plugin running right now, please wait for that to finish executing."); + } + } + + /** + * Starts and runs a plugin from file + * @param f the file of the plugin + * @throws Exception + */ + public static void runPlugin(File f) throws Throwable { + String ext = f.getName().substring(f.getName().lastIndexOf('.') + 1); + PluginLaunchStrategy strategy = launchStrategies.get(ext); + + if(strategy == null) { + throw new RuntimeException(String.format("No launch strategy for extension %s (%s)", ext, f.getAbsolutePath())); + } + + Plugin p = strategy.run(f); + + if(p != null) { + runPlugin(p); + } + + /*if (f.getName().endsWith(".java")) { + p = loadJavaScript(f); + } + if (f.getName().endsWith(".gy") || f.getName().endsWith(".groovy")) { + p = loadGroovyScript(f); + } + if (f.getName().endsWith(".py") || f.getName().endsWith(".python")) { + p = loadPythonScript(f); + } + if (f.getName().endsWith(".rb") || f.getName().endsWith(".ruby")) { + p = loadRubyScript(f); + } + if (p != null) { + runPlugin(p); + }*/ + } + + public static void register(String name, PluginLaunchStrategy strat) { + launchStrategies.put(name, strat); + } + + public static Set pluginExtensions() { + return launchStrategies.keySet(); + } + + public static FileFilter fileFilter() { + return filter; + } + + public static class PluginFileFilter extends FileFilter { + + @Override + public boolean accept(File f) { + if (f.isDirectory()) + return true; + + return PluginManager.pluginExtensions().contains(MiscUtils.extension(f.getAbsolutePath())); + } + + @Override + public String getDescription() { + return "Plugins"; + } + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java similarity index 87% rename from src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java index 79928874..649601c0 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/AllatoriStringDecrypter.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/AllatoriStringDecrypter.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.util.ArrayList; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/CodeSequenceDiagram.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java similarity index 97% rename from src/the/bytecode/club/bytecodeviewer/plugins/CodeSequenceDiagram.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java index 3654cc65..5424b68b 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/CodeSequenceDiagram.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/CodeSequenceDiagram.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.awt.Font; import java.awt.font.FontRenderContext; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/EZInjection.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java similarity index 99% rename from src/the/bytecode/club/bytecodeviewer/plugins/EZInjection.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java index a480e15e..d67c50fd 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/EZInjection.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/EZInjection.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java similarity index 98% rename from src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java index aeb8d170..92fc7593 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/MaliciousCodeScanner.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/MaliciousCodeScanner.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.util.ArrayList; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ReplaceStrings.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java similarity index 98% rename from src/the/bytecode/club/bytecodeviewer/plugins/ReplaceStrings.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java index 514927ff..5dc159a4 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ReplaceStrings.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ReplaceStrings.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.util.ArrayList; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java similarity index 97% rename from src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java index a10a4357..1889063f 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ShowAllStrings.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowAllStrings.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.util.ArrayList; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ShowMainMethods.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java similarity index 93% rename from src/the/bytecode/club/bytecodeviewer/plugins/ShowMainMethods.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java index c0606a52..21d09a2b 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ShowMainMethods.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ShowMainMethods.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import java.util.ArrayList; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java similarity index 87% rename from src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java index c28235f9..ce67e6d7 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ZKMStringDecrypter.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZKMStringDecrypter.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import org.objectweb.asm.tree.ClassNode; diff --git a/src/the/bytecode/club/bytecodeviewer/plugins/ZStringArrayDecrypter.java b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java similarity index 97% rename from src/the/bytecode/club/bytecodeviewer/plugins/ZStringArrayDecrypter.java rename to src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java index 923f808c..6f59875e 100644 --- a/src/the/bytecode/club/bytecodeviewer/plugins/ZStringArrayDecrypter.java +++ b/src/the/bytecode/club/bytecodeviewer/plugin/preinstalled/ZStringArrayDecrypter.java @@ -1,4 +1,4 @@ -package the.bytecode.club.bytecodeviewer.plugins; +package the.bytecode.club.bytecodeviewer.plugin.preinstalled; import org.objectweb.asm.tree.ClassNode; diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java new file mode 100644 index 00000000..98e769a4 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/CompiledJavaPluginLaunchStrategy.java @@ -0,0 +1,179 @@ +package the.bytecode.club.bytecodeviewer.plugin.strategies; + +import java.io.File; +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.tree.ClassNode; + +import the.bytecode.club.bytecodeviewer.JarUtils; +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public class CompiledJavaPluginLaunchStrategy implements PluginLaunchStrategy { + + private static final String PLUGIN_CLASS_NAME = Plugin.class.getCanonicalName().replace(".", "/"); + + private final Set loaded = new HashSet(); + + @Override + public Plugin run(File file) throws Throwable { + Set set = loadData(file); + + LoadedNodeData pdata = null; + for(LoadedNodeData d : set) { + ClassNode cn = d.node; + if(cn.superName.equals(PLUGIN_CLASS_NAME)) { + if(pdata == null) { + pdata = d; + } else { + throw new RuntimeException("Multiple plugin subclasses."); + } + } + } + + LoadingClassLoader cl = new LoadingClassLoader(pdata, set); + Plugin p = cl.pluginKlass.newInstance(); + LoadedPluginData npdata = new LoadedPluginData(pdata, cl, p); + loaded.add(npdata); + + return p; + } + + public Set getLoaded() { + return loaded; + } + + private static Set loadData(File jarFile) throws Throwable { + ZipInputStream jis = new ZipInputStream(new FileInputStream(jarFile)); + ZipEntry entry; + + Set set = new HashSet(); + + while ((entry = jis.getNextEntry()) != null) { + try { + String name = entry.getName(); + if(!name.endsWith(".class")){ + byte[] bytes = JarUtils.getBytes(jis); + String magic = String.format("%02X", bytes[0]) + String.format("%02X", bytes[1]) + String.format("%02X", bytes[2]) + String.format("%02X", bytes[3]); + if(magic.toLowerCase().equals("cafebabe")) { + try { + ClassReader cr = new ClassReader(bytes); + ClassNode cn = new ClassNode(); + cr.accept(cn, 0); + LoadedNodeData data = new LoadedNodeData(bytes, cn); + set.add(data); + } catch(Exception e) { + e.printStackTrace(); + } + } else { + System.out.println(jarFile + ">" + name + ": Header does not start with CAFEBABE, ignoring."); + } + } + } catch(Exception e) { + new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); + } finally { + jis.closeEntry(); + } + } + jis.close(); + + return set; + } + + public static class LoadedNodeData { + private final byte[] bytes; + private final ClassNode node; + public LoadedNodeData(byte[] bytes, ClassNode node) { + this.bytes = bytes; + this.node = node; + } + } + + public static class LoadedPluginData { + private final LoadedNodeData data; + private final LoadingClassLoader classLoader; + private final Plugin plugin; + + public LoadedPluginData(LoadedNodeData data, LoadingClassLoader classLoader, Plugin plugin) { + this.data = data; + this.classLoader = classLoader; + this.plugin = plugin; + } + + public LoadedNodeData getData() { + return data; + } + public LoadingClassLoader getClassLoader() { + return classLoader; + } + + public Plugin getPlugin() { + return plugin; + } + } + + public static class LoadingClassLoader extends ClassLoader { + private final LoadedNodeData data; + private Map cache; + private Map> ccache; + private final Class pluginKlass; + + public LoadingClassLoader(LoadedNodeData data, Set set) throws Throwable{ + this.data = data; + + cache = new HashMap(); + ccache = new HashMap>(); + + for(LoadedNodeData d: set) { + if(d != data) { + cache.put(d.node.name, d); + } + } + + @SuppressWarnings("unchecked") + Class pluginKlass = (Class) loadClass(data.node.name.replace("/", ".")); + + if(pluginKlass == null) + throw new RuntimeException(); + + this.pluginKlass = pluginKlass; + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + name = name.replace("/", "."); + + if(ccache.containsKey(name)) + return ccache.get(name); + + LoadedNodeData data = cache.get(name); + if(data != null) { + byte[] bytes = data.bytes; + Class klass = defineClass(data.node.name, bytes, 0, bytes.length); + ccache.put(name, klass); + return klass; + } + + return super.findClass(name); + } + + public LoadedNodeData getPluginNode() { + return data; + } + + public Class getPluginKlass() { + return pluginKlass; + } + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java new file mode 100644 index 00000000..debadc07 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/GroovyPluginLaunchStrategy.java @@ -0,0 +1,33 @@ +package the.bytecode.club.bytecodeviewer.plugin.strategies; + +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public class GroovyPluginLaunchStrategy implements PluginLaunchStrategy { + + @Override + public Plugin run(File file) throws Throwable { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("groovy"); + + if (engine == null) + throw new Exception( + "Cannot find Groovy script engine! Please contact Konloch."); + + Reader reader = new FileReader(file); + engine.eval(reader); + + return (Plugin) engine.eval("new " + file.getName().replace(".gy", "").replace(".groovy", "") + "();"); + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java new file mode 100644 index 00000000..262085b5 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/JavaPluginLaunchStrategy.java @@ -0,0 +1,33 @@ +package the.bytecode.club.bytecodeviewer.plugin.strategies; + +import java.io.File; + +import me.konloch.kontainer.io.DiskReader; + +import org.codehaus.janino.SimpleCompiler; + +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public class JavaPluginLaunchStrategy implements PluginLaunchStrategy { + + private static SimpleCompiler compiler = new SimpleCompiler(); + + @Override + public Plugin run(File file) throws Throwable { + compiler.cook(DiskReader.loadAsString(file.getAbsolutePath())); + + System.out.println(file.getName().substring(0,(int)(file.getName().length()-(".java".length())))); + Class clazz = (Class) Class.forName( + file.getName().substring(0,(int)file.getName().length()-".java".length()), + true, + compiler.getClassLoader() + ); + + return (Plugin) clazz.newInstance(); + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java new file mode 100644 index 00000000..df886914 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/PythonPluginLaunchStrategy.java @@ -0,0 +1,33 @@ +package the.bytecode.club.bytecodeviewer.plugin.strategies; + +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public class PythonPluginLaunchStrategy implements PluginLaunchStrategy { + + @Override + public Plugin run(File file) throws Throwable { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("python"); + + if (engine == null) + throw new Exception( + "Cannot find Jython script engine! Please contact Konloch."); + + Reader reader = new FileReader(file); + engine.eval(reader); + + return (Plugin) engine.eval(file.getName().replace(".py", "").replace(".python", "") + "()"); + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java new file mode 100644 index 00000000..536d697a --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/plugin/strategies/RubyPluginLaunchStrategy.java @@ -0,0 +1,33 @@ +package the.bytecode.club.bytecodeviewer.plugin.strategies; + +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + +import the.bytecode.club.bytecodeviewer.api.Plugin; +import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy; + +/** + * @author Bibl (don't ban me pls) + * @created 1 Jun 2015 + */ +public class RubyPluginLaunchStrategy implements PluginLaunchStrategy { + + @Override + public Plugin run(File file) throws Throwable { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine engine = manager.getEngineByName("jruby"); + + if (engine == null) + throw new Exception( + "Cannot find jRuby script engine! Please contact Konloch."); + + Reader reader = new FileReader(file); + engine.eval(reader); + + return (Plugin) engine.eval(file.getName().replace(".rb", "").replace(".ruby", "") + ".new"); + } +} \ No newline at end of file