Plugin work. -Bibl

This commit is contained in:
TheBiblMan 2015-06-01 14:45:23 +01:00
parent c60bfd6c6e
commit 0fcddcdacd
25 changed files with 561 additions and 358 deletions

View File

@ -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()));

View File

@ -79,4 +79,8 @@ public class MiscUtils {
}
return i;
}
public static String extension(String name) {
return name.substring(name.lastIndexOf('.') + 1);
}
}

View File

@ -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");
}
}

View File

@ -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

View File

@ -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));

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View 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";
}
}
}

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;

View File

@ -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;

View File

@ -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;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import org.objectweb.asm.tree.ClassNode;

View File

@ -1,4 +1,4 @@
package the.bytecode.club.bytecodeviewer.plugins;
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import org.objectweb.asm.tree.ClassNode;

View File

@ -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;
}
}
}

View File

@ -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", "") + "();");
}
}

View File

@ -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();
}
}

View File

@ -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", "") + "()");
}
}

View File

@ -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");
}
}