Plugin work. -Bibl
This commit is contained in:
parent
c60bfd6c6e
commit
0fcddcdacd
25 changed files with 561 additions and 358 deletions
|
@ -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()));
|
||||
|
|
|
@ -79,4 +79,8 @@ public class MiscUtils {
|
|||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public static String extension(String name) {
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
128
src/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java
Normal file
128
src/the/bytecode/club/bytecodeviewer/plugin/PluginManager.java
Normal file
|
@ -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<String, PluginLaunchStrategy> launchStrategies = new HashMap<String, PluginLaunchStrategy>();
|
||||
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<String> 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";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -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;
|
|
@ -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;
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package the.bytecode.club.bytecodeviewer.plugins;
|
||||
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
|
@ -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<LoadedPluginData> loaded = new HashSet<LoadedPluginData>();
|
||||
|
||||
@Override
|
||||
public Plugin run(File file) throws Throwable {
|
||||
Set<LoadedNodeData> 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<LoadedPluginData> getLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
private static Set<LoadedNodeData> loadData(File jarFile) throws Throwable {
|
||||
ZipInputStream jis = new ZipInputStream(new FileInputStream(jarFile));
|
||||
ZipEntry entry;
|
||||
|
||||
Set<LoadedNodeData> set = new HashSet<LoadedNodeData>();
|
||||
|
||||
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<String, LoadedNodeData> cache;
|
||||
private Map<String, Class<?>> ccache;
|
||||
private final Class<? extends Plugin> pluginKlass;
|
||||
|
||||
public LoadingClassLoader(LoadedNodeData data, Set<LoadedNodeData> set) throws Throwable{
|
||||
this.data = data;
|
||||
|
||||
cache = new HashMap<String, LoadedNodeData>();
|
||||
ccache = new HashMap<String, Class<?>>();
|
||||
|
||||
for(LoadedNodeData d: set) {
|
||||
if(d != data) {
|
||||
cache.put(d.node.name, d);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Class<? extends Plugin> pluginKlass = (Class<? extends Plugin>) 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<? extends Plugin> getPluginKlass() {
|
||||
return pluginKlass;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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", "") + "();");
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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", "") + "()");
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue