02/01/2015 - Updated CFR and Proycon to latest versions.
02/01/2015 - Started working on implementing Krakatau.
02/01/2015 - Sexifixed the security manager a little bit.
02/03/2015 - Fully added Krakatau Java decompiler, just
disassembly/assembly left.
02/03/2015 - Updated the about window.
02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb,
was 45mb).
02/04/2015 - Added Krakatau Disassembly.
02/04/2015 - Added Krakatau Assembly.
This commit is contained in:
Kalen Kinloch 2015-02-04 07:06:04 -08:00
parent 58020b0891
commit 1cd3bfa92f
28 changed files with 1111 additions and 280 deletions

Binary file not shown.

View file

@ -1,8 +1,8 @@
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Smali, GUI Baksmali, GUI APK Editor, GUI Dex Editor, GUI APK Decompiler, GUI DEX Decompiler, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI DEX2Jar, GUI Jar2DEX, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more. Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Smali, GUI Baksmali, GUI APK Editor, GUI Dex Editor, GUI APK Decompiler, GUI DEX Decompiler, GUI Procyon Java Decompiler, GUI Krakatau, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI DEX2Jar, GUI Jar2DEX, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch. It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch.
There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of. There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of.
You can either use one of the pre-written plugins, or write your own. It supports groovy, python and ruby scripting. Once a plugin is activated, it will execute the plugin with a ClassNode ArrayList of every single class loaded in BCV, this allows the user to handle it completely using ASM. You can either use one of the pre-written plugins, or write your own. It supports groovy scripting. Once a plugin is activated, it will execute the plugin with a ClassNode ArrayList of every single class loaded in BCV, this allows the user to handle it completely using ASM.
Code from various projects has been used, including but not limited to: Code from various projects has been used, including but not limited to:
J-RET by WaterWolf J-RET by WaterWolf
@ -16,6 +16,7 @@ Code from various projects has been used, including but not limited to:
CFIDE by Bibl CFIDE by Bibl
Smali by JesusFreke Smali by JesusFreke
Dex2Jar by pxb1..? Dex2Jar by pxb1..?
Krakatau by Storyyeller
Contributors: Contributors:
Konloch Konloch
@ -31,7 +32,7 @@ Contribution Guide Lines:
Packages must start with the.bytecode.club.bytecodeviewer Packages must start with the.bytecode.club.bytecodeviewer
If code you write can throw an exception, handle it using new the.bytecode.club.bytecodeviewer.ExceptionUI(exception) If code you write can throw an exception, handle it using new the.bytecode.club.bytecodeviewer.ExceptionUI(exception)
Video: http://the.bytecode.club/bytecodeviewer-video/ Website: https://bytecodeviewer.com
Source Code: https://github.com/konloch/bytecode-viewer Source Code: https://github.com/konloch/bytecode-viewer
Bin/Archive: https://github.com/konloch/bytecode-viewer/releases Bin/Archive: https://github.com/konloch/bytecode-viewer/releases
Java Docs: https://the.bytecode.club/docs/bytecode-viewer/ Java Docs: https://the.bytecode.club/docs/bytecode-viewer/
@ -40,7 +41,8 @@ Report Bugs (or below): https://github.com/Konloch/bytecode-viewer/issues
Discussion Forum: https://the.bytecode.club/forumdisplay.php?fid=69 Discussion Forum: https://the.bytecode.club/forumdisplay.php?fid=69
Key Features: Key Features:
Smali/BakSmali Intergration - You can now edit class files/dex files via smali! Krakatau Integration for Bytecode assembly/disassembly.
Smali/BakSmali Integration - You can now edit class files/dex files via smali!
APK/DEX Support - Using Dex2Jar and Jar2Dex it's able to load and save APKs with ease! APK/DEX Support - Using Dex2Jar and Jar2Dex it's able to load and save APKs with ease!
Java Decompiler - It utilizes FernFlower, Procyon and CFR for decompilation. Java Decompiler - It utilizes FernFlower, Procyon and CFR for decompilation.
Bytecode Decompiler - A modified version of CFIDE's. Bytecode Decompiler - A modified version of CFIDE's.
@ -48,7 +50,7 @@ Key Features:
Each Decompiler/Viewer is toggleable, you can also select what will display on each pane. Each Decompiler/Viewer is toggleable, you can also select what will display on each pane.
Fully Featured Search System - Search through strings, functions, variables and more! Fully Featured Search System - Search through strings, functions, variables and more!
A Plugin System With Built In Plugins - (Show All Strings, Malicious Code Scanner, String Decrypters, etc) A Plugin System With Built In Plugins - (Show All Strings, Malicious Code Scanner, String Decrypters, etc)
Fully Featured Scripting System That Supports Groovy, Python And Ruby. Fully Featured Scripting System That Supports Groovy.
EZ-Inject - Graphically insert hooks and debugging code, invoke main and start the program. EZ-Inject - Graphically insert hooks and debugging code, invoke main and start the program.
Recent Files & Recent Plugins. Recent Files & Recent Plugins.
And more! Give it a try for yourself! And more! Give it a try for yourself!
@ -277,3 +279,12 @@ Changelog:
01/27/2015 - BCV now blocks exec and won't allow any ports to be bound. 01/27/2015 - BCV now blocks exec and won't allow any ports to be bound.
--- 2.7.1 ---: --- 2.7.1 ---:
01/27/2015 - Fixed hide file. 01/27/2015 - Fixed hide file.
--- 2.8.0 ---:
02/01/2015 - Updated CFR and Proycon to latest versions.
02/01/2015 - Started working on implementing Krakatau.
02/01/2015 - Sexifixed the security manager a little bit.
02/03/2015 - Fully added Krakatau Java decompiler, just disassembly/assembly left.
02/03/2015 - Updated the about window.
02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb, was 45mb).
02/04/2015 - Added Krakatau Disassembly.
02/04/2015 - Added Krakatau Assembly.

Binary file not shown.

BIN
src/krakatau.zip Normal file

Binary file not shown.

View file

@ -7,16 +7,13 @@ import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.InetAddress;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.Permission;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -37,7 +34,7 @@ import org.apache.commons.io.FileUtils;
import org.imgscalr.Scalr; import org.imgscalr.Scalr;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.decompilers.Smali; import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
import the.bytecode.club.bytecodeviewer.gui.ClassViewer; import the.bytecode.club.bytecodeviewer.gui.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane; import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane;
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI; import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
@ -63,7 +60,7 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
* There is also a plugin system that will allow you to interact with the loaded * There is also a plugin system that will allow you to interact with the loaded
* classfiles, for example you can write a String deobfuscator, a malicious code * classfiles, for example you can write a String deobfuscator, a malicious code
* searcher, or something else you can think of. You can either use one of the * searcher, or something else you can think of. You can either use one of the
* pre-written plugins, or write your own. It supports groovy, python and ruby * pre-written plugins, or write your own. It supports groovy
* scripting. Once a plugin is activated, it will send a ClassNode ArrayList of * scripting. Once a plugin is activated, it will send a ClassNode ArrayList of
* every single class loaded in the file system to the execute function, this * every single class loaded in the file system to the execute function, this
* allows the user to handle it completely using ASM. * allows the user to handle it completely using ASM.
@ -303,6 +300,15 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
* 01/27/2015 - Added java.awt.Robot to the malicious code scanner. * 01/27/2015 - Added java.awt.Robot to the malicious code scanner.
* -----2.7.1-----: * -----2.7.1-----:
* 01/27/2015 - Fixed hide file. * 01/27/2015 - Fixed hide file.
* -----2.8.0-----:
* 02/01/2015 - Updated CFR and Proycon to latest versions.
* 02/01/2015 - Started working on implementing Krakatau.
* 02/01/2015 - Sexifixed the security manager a little bit.
* 02/03/2015 - Fully added Krakatau Java decompiler, just disassembly/assembly left.
* 02/03/2015 - Updated the about window.
* 02/03/2015 - Dropped JRuby and Jython support (BCV is now roughly 16mb, was 45mb).
* 02/04/2015 - Added Krakatau Disassembly.
* 02/04/2015 - Added Krakatau Assembly.
* *
* @author Konloch * @author Konloch
* *
@ -310,20 +316,29 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
public class BytecodeViewer { public class BytecodeViewer {
/*per version*/
public static String version = "2.8.0";
public static String krakatauVersion = "2";
/*the rest*/
public static MainViewerGUI viewer = null; public static MainViewerGUI viewer = null;
public static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV, however that's highly unlikely.
public static String python = "";
public static String rt = "";
public static SecurityMan sm = new SecurityMan();
public static HashMap<String, ClassNode> loadedClasses = new HashMap<String, ClassNode>(); public static HashMap<String, ClassNode> loadedClasses = new HashMap<String, ClassNode>();
public static HashMap<String, byte[]> loadedResources = new HashMap<String, byte[]>(); public static HashMap<String, byte[]> loadedResources = new HashMap<String, byte[]>();
private static int maxRecentFiles = 25; private static int maxRecentFiles = 25;
public static String fs = System.getProperty("file.separator"); public static String fs = System.getProperty("file.separator");
public static String nl = System.getProperty("line.separator"); public static String nl = System.getProperty("line.separator");
private static File BCVDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer");
private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv"; private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv";
private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv"; private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv";
public static String settingsName = getBCVDirectory() + fs + "settings.bcv"; public static String settingsName = getBCVDirectory() + fs + "settings.bcv";
public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs; public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs;
public static String krakatauWorkingDirectory = getBCVDirectory() + fs + "krakatau_" + krakatauVersion + fs + "Krakatau-master";
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false); private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false); private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
public static boolean runningObfuscation = false; public static boolean runningObfuscation = false;
public static String version = "2.7.1";
private static long start = System.currentTimeMillis(); private static long start = System.currentTimeMillis();
public static String lastDirectory = ""; public static String lastDirectory = "";
private static Thread versionChecker = new Thread() { private static Thread versionChecker = new Thread() {
@ -502,51 +517,8 @@ public class BytecodeViewer {
} }
public static void main(String[] args) { public static void main(String[] args) {
getBCVDirectory();
SecurityManager sm = new SecurityManager() {
@Override
public void checkExec(String cmd) {
throw new SecurityException("BCV is awesome.");
}
@Override
public void checkListen(int port) {
throw new SecurityException("BCV is awesome.");
}
@Override
public void checkPermission(Permission perm) { //expand eventually
}
@Override
public void checkPermission(Permission perm, Object context) {//expand eventually
}
@Override public void checkAccess(Thread t) {}
@Override public void checkAccept(String host, int port) {}
@Override public void checkAccess(ThreadGroup g) {}
@Override public void checkAwtEventQueueAccess() {}
@Override public void checkConnect(String host, int port) {}
@Override public void checkConnect(String host, int port, Object context) {}
@Override public void checkCreateClassLoader() {}
@Override public void checkDelete(String file) {}
@Override public void checkExit(int status) {}
@Override public void checkLink(String lib) {}
@Override public void checkMemberAccess(Class<?> clazz, int which) {}
@Override public void checkMulticast(InetAddress maddr) {}
@Override public void checkMulticast(InetAddress maddr, byte ttl) {}
@Override public void checkPackageAccess(String pkg) {}
@Override public void checkPackageDefinition(String pkg) {}
@Override public void checkPrintJobAccess() {}
@Override public void checkPropertiesAccess() {}
@Override public void checkPropertyAccess(String key) {}
@Override public void checkRead(FileDescriptor fd) {}
@Override public void checkRead(String file) {}
@Override public void checkRead(String file, Object context) {}
@Override public void checkSecurityAccess(String target) {}
@Override public void checkSetFactory() {}
@Override public void checkSystemClipboardAccess() {}
@Override public void checkWrite(FileDescriptor fd) {}
@Override public void checkWrite(String file) {}
};
System.setSecurityManager(sm); System.setSecurityManager(sm);
checkKrakatau();
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version); System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
iconList = new ArrayList<BufferedImage>(); iconList = new ArrayList<BufferedImage>();
int size = 16; int size = 16;
@ -616,7 +588,7 @@ public class BytecodeViewer {
} }
//called whenever a save function is executed //called whenever a save function is executed
public static boolean compileSmali(boolean message) { public static boolean compile(boolean message) {
if(getLoadedClasses().isEmpty()) if(getLoadedClasses().isEmpty())
return false; return false;
@ -624,10 +596,10 @@ public class BytecodeViewer {
if(c instanceof ClassViewer) { if(c instanceof ClassViewer) {
ClassViewer cv = (ClassViewer) c; ClassViewer cv = (ClassViewer) c;
Object smali[] = cv.getSmali(); Object smali[] = cv.getSmali();
ClassNode origNode = (ClassNode) smali[0];
String smaliText = (String) smali[1];
if(smali != null) { if(smali != null) {
byte[] smaliCompiled = Smali.compile(smaliText); ClassNode origNode = (ClassNode) smali[0];
String smaliText = (String) smali[1];
byte[] smaliCompiled = the.bytecode.club.bytecodeviewer.compilers.SmaliAssembler.compile(smaliText);
if(smaliCompiled != null) { if(smaliCompiled != null) {
ClassNode newNode = JarUtils.getNode(smaliCompiled); ClassNode newNode = JarUtils.getNode(smaliCompiled);
System.out.println(origNode.name+":"+newNode.name); System.out.println(origNode.name+":"+newNode.name);
@ -637,6 +609,22 @@ public class BytecodeViewer {
return false; return false;
} }
} }
Object krakatau[] = cv.getKrakatau();
if(krakatau != null) {
ClassNode origNodeK = (ClassNode) krakatau[0];
String krakatauText = (String) krakatau[1];
byte[] krakatauCompiled = the.bytecode.club.bytecodeviewer.compilers.KrakatauAssembler.compile(krakatauText, origNodeK.name);
if(krakatauCompiled != null) {
ClassNode newNode = JarUtils.getNode(krakatauCompiled);
System.out.println(origNodeK.name+":"+newNode.name);
BytecodeViewer.updateNode(origNodeK, newNode);
} else {
BytecodeViewer.showMessage("There has been an error with assembling your Krakatau Bytecode, please check this. Class: " + origNodeK.name);
return false;
}
}
} }
} }
@ -646,6 +634,30 @@ public class BytecodeViewer {
return true; return true;
} }
public static void checkKrakatau() {
File krakatauDirectory = new File(getBCVDirectory() + fs + "krakatau_" + krakatauVersion);
if(!krakatauDirectory.exists()) {
try {
File temp = new File(getBCVDirectory() + fs + "krakatau_" + krakatauVersion + ".zip");
while(temp.exists())
temp.delete();
InputStream is = BytecodeViewer.class.getClassLoader().getResourceAsStream("krakatau.zip");
FileOutputStream baos = new FileOutputStream(temp);
int r = 0;
byte[] buffer = new byte[8192];
while((r=is.read(buffer))>=0) {
baos.write(buffer, 0, r);
}
baos.close();
ZipUtils.unzipFilesToPath(temp.getAbsolutePath(), krakatauDirectory.getAbsolutePath());
temp.delete();
} catch(Exception e) {
showMessage("ERROR: There was an issue unzipping Krakatau decompiler, please contact @Konloch with your stacktrace.");
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}
private static boolean update = true; private static boolean update = true;
public static void openFiles(final File[] files, boolean recentFiles) { public static void openFiles(final File[] files, boolean recentFiles) {
if(recentFiles) if(recentFiles)
@ -741,7 +753,6 @@ public class BytecodeViewer {
JOptionPane.showMessageDialog(viewer, message); JOptionPane.showMessageDialog(viewer, message);
} }
@SuppressWarnings("deprecation")
public static void resetWorkSpace(boolean ask) { public static void resetWorkSpace(boolean ask) {
if(!ask) { if(!ask) {
loadedResources.clear(); loadedResources.clear();
@ -759,7 +770,7 @@ public class BytecodeViewer {
pane.setOptions(options); pane.setOptions(options);
JDialog dialog = pane.createDialog(viewer, JDialog dialog = pane.createDialog(viewer,
"Bytecode Viewer - Reset Workspace"); "Bytecode Viewer - Reset Workspace");
dialog.show(); dialog.setVisible(true);
Object obj = pane.getValue(); Object obj = pane.getValue();
int result = -1; int result = -1;
for (int k = 0; k < options.length; k++) for (int k = 0; k < options.length; k++)
@ -793,8 +804,7 @@ public class BytecodeViewer {
killList.clear(); killList.clear();
} }
if (recentFiles.contains(f.getAbsolutePath())) // already added on the if (recentFiles.contains(f.getAbsolutePath())) // already added on the list
// list
recentFiles.remove(f.getAbsolutePath()); recentFiles.remove(f.getAbsolutePath());
if (recentFiles.size() >= maxRecentFiles) if (recentFiles.size() >= maxRecentFiles)
recentFiles.remove(maxRecentFiles - 1); // zero indexing recentFiles.remove(maxRecentFiles - 1); // zero indexing
@ -818,8 +828,7 @@ public class BytecodeViewer {
killList2.clear(); killList2.clear();
} }
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the if (recentPlugins.contains(f.getAbsolutePath())) // already added on the list
// list
recentPlugins.remove(f.getAbsolutePath()); recentPlugins.remove(f.getAbsolutePath());
if (recentPlugins.size() >= maxRecentFiles) if (recentPlugins.size() >= maxRecentFiles)
recentPlugins.remove(maxRecentFiles - 1); // zero indexing recentPlugins.remove(maxRecentFiles - 1); // zero indexing
@ -887,15 +896,13 @@ public class BytecodeViewer {
} }
public static String getBCVDirectory() { public static String getBCVDirectory() {
File f = new File(System.getProperty("user.home") + fs while (!BCVDir.exists())
+ ".Bytecode-Viewer"); BCVDir.mkdirs();
while (!f.exists())
f.mkdirs();
if (!f.isHidden() && isWindows()) if (!BCVDir.isHidden() && isWindows())
hideFile(f); hideFile(BCVDir);
return f.getAbsolutePath(); return BCVDir.getAbsolutePath();
} }
private static boolean isWindows() { private static boolean isWindows() {
@ -903,13 +910,14 @@ public class BytecodeViewer {
} }
private static void hideFile(File f) { private static void hideFile(File f) {
System.out.println("hiding file"); sm.blocking = false;
try { try {
// Hide file by running attrib system command (on Windows) // Hide file by running attrib system command (on Windows)
Runtime.getRuntime().exec("attrib +H " + f.getAbsolutePath()); Runtime.getRuntime().exec("attrib +H " + f.getAbsolutePath());
} catch (Exception e) { } catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} }
sm.blocking = true;
} }
private static String quickConvert(ArrayList<String> a) { private static String quickConvert(ArrayList<String> a) {

View file

@ -1,5 +1,6 @@
package the.bytecode.club.bytecodeviewer; package the.bytecode.club.bytecodeviewer;
import java.io.File;
import java.util.Random; import java.util.Random;
public class MiscUtils { public class MiscUtils {
@ -20,4 +21,35 @@ public class MiscUtils {
sb.append(AN.charAt(rnd.nextInt(AN.length()))); sb.append(AN.charAt(rnd.nextInt(AN.length())));
return sb.toString(); return sb.toString();
} }
public static String getUniqueName(String start, String ext) {
String s = null;
boolean b = true;
File f = null;
String m = null;
while (b) {
m = MiscUtils.randomString(32);
f = new File(start + m + ext);
if (!f.exists()) {
s = start + m;
b = false;
}
}
return s;
}
public static int getClassNumber(String start, String ext) {
boolean b = true;
int i = 0;
while (b) {
File tempF = new File(start + i + ext);
if (!tempF.exists())
b = false;
else
i++;
}
return i;
}
} }

View file

@ -0,0 +1,53 @@
package the.bytecode.club.bytecodeviewer;
import java.io.FileDescriptor;
import java.net.InetAddress;
import java.security.Permission;
public class SecurityMan extends SecurityManager {
public boolean blocking = true;
@Override
public void checkExec(String cmd) {
if(blocking)
throw new SecurityException("BCV is awesome.");
}
@Override
public void checkListen(int port) {
if(blocking)
throw new SecurityException("BCV is awesome.");
}
@Override
public void checkPermission(Permission perm) { //expand eventually
}
@Override
public void checkPermission(Permission perm, Object context) {//expand eventually
}
@Override public void checkAccess(Thread t) {}
@Override public void checkAccept(String host, int port) {}
@Override public void checkAccess(ThreadGroup g) {}
@Override public void checkAwtEventQueueAccess() {}
@Override public void checkConnect(String host, int port) {}
@Override public void checkConnect(String host, int port, Object context) {}
@Override public void checkCreateClassLoader() {}
@Override public void checkDelete(String file) {}
@Override public void checkExit(int status) {}
@Override public void checkLink(String lib) {}
@Override public void checkMemberAccess(Class<?> clazz, int which) {}
@Override public void checkMulticast(InetAddress maddr) {}
@Override public void checkMulticast(InetAddress maddr, byte ttl) {}
@Override public void checkPackageAccess(String pkg) {}
@Override public void checkPackageDefinition(String pkg) {}
@Override public void checkPrintJobAccess() {}
@Override public void checkPropertiesAccess() {}
@Override public void checkPropertyAccess(String key) {}
@Override public void checkRead(FileDescriptor fd) {}
@Override public void checkRead(String file) {}
@Override public void checkRead(String file, Object context) {}
@Override public void checkSecurityAccess(String target) {}
@Override public void checkSetFactory() {}
@Override public void checkSystemClipboardAccess() {}
@Override public void checkWrite(FileDescriptor fd) {}
@Override public void checkWrite(String file) {}
}

View file

@ -111,6 +111,10 @@ public class Settings {
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel())) else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauEditable.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel())) if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
@ -126,6 +130,10 @@ public class Settings {
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel())) else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauEditable.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel())) if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
@ -141,12 +149,18 @@ public class Settings {
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel())) else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3KrakatauEditable.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.isMaximized), false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.isMaximized), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.lastDirectory, false); DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.lastDirectory, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.rt, false);
} catch(Exception e) { } catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e); new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} }
@ -249,6 +263,10 @@ public class Settings {
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true); BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true);
else if(decompiler == 6) else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Smali.getModel(), true); BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1KrakatauEditable.getModel(), true);
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false)); decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false));
if(decompiler == 0) if(decompiler == 0)
@ -265,6 +283,10 @@ public class Settings {
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true); BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true);
else if(decompiler == 6) else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Smali.getModel(), true); BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2KrakatauEditable.getModel(), true);
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false)); decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false));
if(decompiler == 0) if(decompiler == 0)
@ -281,6 +303,10 @@ public class Settings {
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true); BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true);
else if(decompiler == 6) else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Smali.getModel(), true); BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3KrakatauEditable.getModel(), true);
BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 84, false))); BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 84, false)));
@ -292,6 +318,8 @@ public class Settings {
BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 86, false))); BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 86, false)));
BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 87, false))); BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 87, false)));
BytecodeViewer.lastDirectory = DiskReader.loadString(BytecodeViewer.settingsName, 88, false); BytecodeViewer.lastDirectory = DiskReader.loadString(BytecodeViewer.settingsName, 88, false);
BytecodeViewer.python = DiskReader.loadString(BytecodeViewer.settingsName, 89, false);
BytecodeViewer.rt = DiskReader.loadString(BytecodeViewer.settingsName, 90, false);
} catch(Exception e) { } catch(Exception e) {
//ignore because errors are expected, first start up and outdated settings. //ignore because errors are expected, first start up and outdated settings.
} }

View file

@ -279,4 +279,47 @@ public final class ZipUtils {
e.printStackTrace(); e.printStackTrace();
} }
} }
public static void zipFolder(String srcFolder, String destZipFile, String ignore) throws Exception {
ZipOutputStream zip = null;
FileOutputStream fileWriter = null;
fileWriter = new FileOutputStream(destZipFile);
zip = new ZipOutputStream(fileWriter);
addFolderToZip("", srcFolder, zip, ignore);
zip.flush();
zip.close();
}
public static void addFileToZip(String path, String srcFile, ZipOutputStream zip, String ignore)
throws Exception {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(path, srcFile, zip, ignore);
} else {
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
zip.putNextEntry(new ZipEntry(path.replace(ignore, "BCV_Krakatau") + "/" + folder.getName()));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
in.close();
}
}
public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip, String ignore)
throws Exception {
File folder = new File(srcFolder);
for (String fileName : folder.list()) {
if (path.equals("")) {
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, ignore);
} else {
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, ignore);
}
}
}
} }

View file

@ -17,26 +17,21 @@ import the.bytecode.club.bytecodeviewer.plugins.EZInjection;
public class BytecodeViewer { public class BytecodeViewer {
/**
* This is used to define a global loader.
*/
private static ClassNodeLoader loader = new ClassNodeLoader();
/** /**
* Grab the loader instance * Grab the loader instance
* *
* @return * @return
*/ */
public static ClassNodeLoader getClassNodeLoader() { public static ClassNodeLoader getClassNodeLoader() {
return loader; return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader;
} }
/** /**
* Creates a new instance of the ClassNode loader. * Creates a new instance of the ClassNode loader.
*/ */
public static void createNewClassNodeLoaderInstance() { public static void createNewClassNodeLoaderInstance() {
loader.clear(); the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear();
loader = new ClassNodeLoader(); the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader();
} }
/** /**

View file

@ -31,6 +31,14 @@ public class ExceptionUI extends JFrame {
setup(e, "@Konloch - konloch@gmail.com"); setup(e, "@Konloch - konloch@gmail.com");
} }
/**
* @param e
* The exception to be shown
*/
public ExceptionUI(String e) {
setup(e, "@Konloch - konloch@gmail.com");
}
/** /**
* @param e * @param e
* The exception to be shown * The exception to be shown
@ -41,6 +49,16 @@ public class ExceptionUI extends JFrame {
setup(e, author); setup(e, author);
} }
/**
* @param e
* The exception to be shown
* @param author
* the author of the plugin throwing this exception.
*/
public ExceptionUI(String e, String author) {
setup(e, author);
}
private void setup(Exception e, String author) { private void setup(Exception e, String author) {
this.setIconImages(BytecodeViewer.iconList); this.setIconImages(BytecodeViewer.iconList);
@ -63,6 +81,23 @@ public class ExceptionUI extends JFrame {
this.setVisible(true); this.setVisible(true);
} }
private void setup(String e, String author) {
this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(600, 400));
setTitle("Bytecode Viewer " + BytecodeViewer.version
+ " - Stack Trace - Send this to " + author);
getContentPane().setLayout(new CardLayout(0, 0));
JTextArea txtrBytecodeViewerIs = new JTextArea();
txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK);
txtrBytecodeViewerIs.setWrapStyleWord(true);
getContentPane().add(new JScrollPane(txtrBytecodeViewerIs),
"name_140466576080695");
txtrBytecodeViewerIs.setText(e);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private static final long serialVersionUID = -5230501978224926296L; private static final long serialVersionUID = -5230501978224926296L;
} }

View file

@ -0,0 +1,91 @@
package the.bytecode.club.bytecodeviewer.compilers;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/**
* Krakatau Java assembler, requires Python 2.7
*
* @author Konloch
*
*/
public class KrakatauAssembler {
public static byte[] compile(String contents, String name) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
String origName = name;
name = MiscUtils.randomString(20);
System.out.println("run");
File tempD = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempD.mkdir();
File tempJ = new File(tempD.getAbsolutePath() + BytecodeViewer.fs+name+".j");
DiskWriter.replaceFile(tempJ.getAbsolutePath(), contents, true);
System.out.println("ran");
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.blocking = false;
String log = "";
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "assemble.py",
"-out",
tempDirectory.getAbsolutePath(),
tempJ.getAbsolutePath()
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
System.out.println(log);
byte[] b = org.apache.commons.io.FileUtils.readFileToByteArray(new File(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + origName + ".class"));
tempDirectory.delete();
tempJar.delete();
return b;
} catch(Exception e) {
e.printStackTrace();
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(log);
}
BytecodeViewer.sm.blocking = true;
return null;
}
}

View file

@ -1,80 +1,19 @@
package the.bytecode.club.bytecodeviewer.decompilers; package the.bytecode.club.bytecodeviewer.compilers;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import me.konloch.kontainer.io.DiskReader;
import me.konloch.kontainer.io.DiskWriter; import me.konloch.kontainer.io.DiskWriter;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Dex2Jar; import the.bytecode.club.bytecodeviewer.Dex2Jar;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils; import the.bytecode.club.bytecodeviewer.ZipUtils;
public class Smali { public class SmaliAssembler {
public static String decompileClassNode(ClassNode cn) {
final ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp";
String start = JavaDecompiler.getUniqueName(fileStart, ".class");
final File tempClass = new File(start + ".class");
final File tempZip = new File(start + ".jar");
final File tempDex = new File(start + ".dex");
final File tempSmali = new File(start + "-smali"); //output directory
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
fos.write(cw.toByteArray());
fos.close();
} catch (final IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
ZipUtils.zipFile(tempClass, tempZip);
Dex2Jar.saveAsDex(tempZip, tempDex);
try {
org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()});
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
File outputSmali = null;
boolean found = false;
File current = tempSmali;
while(!found) {
File f = current.listFiles()[0];
if(f.isDirectory())
current = f;
else {
outputSmali = f;
found = true;
}
}
try {
return DiskReader.loadAsString(outputSmali.getAbsolutePath());
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;
}
public static byte[] compile(String contents) { public static byte[] compile(String contents) {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp"; + "temp";
int fileNumber = JavaDecompiler.getClassNumber(fileStart, ".dex"); int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex");
final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder"+BytecodeViewer.fs); final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder"+BytecodeViewer.fs);
tempSmaliFolder.mkdir(); tempSmaliFolder.mkdir();

View file

@ -23,6 +23,7 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/** /**
* *
@ -43,10 +44,9 @@ public class CFRDecompiler extends JavaDecompiler {
final ClassWriter cw = new ClassWriter(0); final ClassWriter cw = new ClassWriter(0);
cn.accept(cw); cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs;
+ "temp";
final File tempClass = new File(getUniqueName(fileStart, ".class") + ".class"); final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try { try {
final FileOutputStream fos = new FileOutputStream(tempClass); final FileOutputStream fos = new FileOutputStream(tempClass);
@ -96,12 +96,12 @@ public class CFRDecompiler extends JavaDecompiler {
e.printStackTrace(); e.printStackTrace();
String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggestest Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception; return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggested Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception;
} }
return s; return s;
} }
} }
return "CFR error!"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggestest Fix: Click refresh class, if it fails again try another decompiler."; return "CFR error!"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggested Fix: Click refresh class, if it fails again try another decompiler.";
} }
public String[] generateMainMethod(String filePath, String outputPath) { public String[] generateMainMethod(String filePath, String outputPath) {
@ -230,8 +230,7 @@ public class CFRDecompiler extends JavaDecompiler {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
tempZip.getAbsolutePath()); tempZip.getAbsolutePath());
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs;
+ "temp";
String fuckery = fuckery(fileStart); String fuckery = fuckery(fileStart);

View file

@ -14,6 +14,7 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/** /**
* A complete FernFlower launcher with all the options (except 2) * A complete FernFlower launcher with all the options (except 2)
@ -63,7 +64,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
final ClassWriter cw = new ClassWriter(0); final ClassWriter cw = new ClassWriter(0);
cn.accept(cw); cn.accept(cw);
String start = getUniqueName("", ".class"); String start = MiscUtils.getUniqueName("", ".class");
final File tempClass = new File(start + ".class"); final File tempClass = new File(start + ".class");
@ -104,7 +105,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
exception += BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); exception += BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
} }
} }
return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggestest Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception; return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggested Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception;
} }
private String[] generateMainMethod(String className, String folder) { private String[] generateMainMethod(String className, String folder) {

View file

@ -1,11 +1,7 @@
package the.bytecode.club.bytecodeviewer.decompilers; package the.bytecode.club.bytecodeviewer.decompilers;
import java.io.File;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/** /**
* *
* @author Konloch * @author Konloch
@ -19,33 +15,4 @@ public abstract class JavaDecompiler {
public abstract void decompileToZip(String zipName); public abstract void decompileToZip(String zipName);
public abstract void decompileToClass(String className, String classNameSaved); public abstract void decompileToClass(String className, String classNameSaved);
public static String getUniqueName(String start, String ext) {
String s = null;
boolean b = true;
File f = null;
String m = null;
while (b) {
m = MiscUtils.randomString(32);
f = new File(start + m + ext);
if (!f.exists()) {
s = start + m;
b = false;
}
}
return s;
}
public static int getClassNumber(String start, String ext) {
boolean b = true;
int i = 0;
while (b) {
File tempF = new File(start + i + ext);
if (!tempF.exists())
b = false;
else
i++;
}
return i;
}
} }

View file

@ -0,0 +1,219 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
/**
* Krakatau Java Decompiler, requires Python 2.7
*
* @author Konloch
*
*/
public class KrakatauDecompiler extends JavaDecompiler {
public String decompileClassNode(ClassNode cn) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
while(tempJar.exists())
tempJar.delete();
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.blocking = false;
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
cn.name+".class"
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String log = "Process:"+BytecodeViewer.nl+BytecodeViewer.nl;
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
s = log;
//if the motherfucker failed this'll fail, aka wont set.
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".java");
tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
s += BytecodeViewer.nl+"Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
}
BytecodeViewer.sm.blocking = true;
return s;
}
public void decompileToZip(String zipName) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
String ran = MiscUtils.randomString(32);
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.blocking = false;
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
tempJar.getAbsolutePath()
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
int exitValue = process.waitFor();
System.out.println("Exit Value is " + exitValue);
// ZipUtils.zipDirectory(tempDirectory, new File(zipName));
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
//tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
BytecodeViewer.sm.blocking = true;
}
public void decompileToClass(String className, String classNameSaved) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.blocking = false;
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
className+".class"
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
System.out.println(line);
}
int exitValue = process.waitFor();
System.out.println("Exit Value is " + exitValue);
File f = new File(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + className + ".java");
f.renameTo(new File(classNameSaved));
tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}

View file

@ -0,0 +1,91 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/**
* Krakatau Java Disassembler, requires Python 2.7
*
* @author Konloch
*
*/
public class KrakatauDisassembler {
public static String decompileClassNode(ClassNode cn) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.blocking = false;
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "disassemble.py",
"-path",
tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
cn.name+".class"
);
Process process = pb.start();
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String log = "Process:"+BytecodeViewer.nl+BytecodeViewer.nl;
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
s = log;
//if the motherfucker failed this'll fail, aka wont set.
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".j");
tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
s += BytecodeViewer.nl+"Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
}
BytecodeViewer.sm.blocking = true;
return s;
}
}

View file

@ -39,6 +39,7 @@ import com.strobel.assembler.metadata.TypeReference;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/** /**
* *
@ -99,7 +100,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp"; + "temp";
final File tempClass = new File(getUniqueName(fileStart, ".class") + ".class"); final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try { try {
final FileOutputStream fos = new FileOutputStream(tempClass); final FileOutputStream fos = new FileOutputStream(tempClass);
@ -139,7 +140,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString(); exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
} }
return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggestest Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception; return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"+BytecodeViewer.nl+BytecodeViewer.nl+"Suggested Fix: Click refresh class, if it fails again try another decompiler."+BytecodeViewer.nl+BytecodeViewer.nl+exception;
} }
@Override @Override

View file

@ -0,0 +1,74 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Dex2Jar;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
public class SmaliDisassembler {
public static String decompileClassNode(ClassNode cn) {
final ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp";
String start = MiscUtils.getUniqueName(fileStart, ".class");
final File tempClass = new File(start + ".class");
final File tempZip = new File(start + ".jar");
final File tempDex = new File(start + ".dex");
final File tempSmali = new File(start + "-smali"); //output directory
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
fos.write(cw.toByteArray());
fos.close();
} catch (final IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
ZipUtils.zipFile(tempClass, tempZip);
Dex2Jar.saveAsDex(tempZip, tempDex);
try {
org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()});
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
File outputSmali = null;
boolean found = false;
File current = tempSmali;
while(!found) {
File f = current.listFiles()[0];
if(f.isDirectory())
current = f;
else {
outputSmali = f;
found = true;
}
}
try {
return DiskReader.loadAsString(outputSmali.getAbsolutePath());
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;
}
}

View file

@ -14,7 +14,7 @@ import java.awt.Color;
public class AboutWindow extends JFrame { public class AboutWindow extends JFrame {
public AboutWindow() { public AboutWindow() {
this.setIconImages(BytecodeViewer.iconList); this.setIconImages(BytecodeViewer.iconList);
setSize(new Dimension(446, 374)); setSize(new Dimension(446, 434));
setType(Type.UTILITY); setType(Type.UTILITY);
setTitle("Bytecode Viewer - About"); setTitle("Bytecode Viewer - About");
getContentPane().setLayout(new CardLayout(0, 0)); getContentPane().setLayout(new CardLayout(0, 0));
@ -24,9 +24,7 @@ public class AboutWindow extends JFrame {
txtrBytecodeViewerIs.setWrapStyleWord(true); txtrBytecodeViewerIs.setWrapStyleWord(true);
getContentPane().add(txtrBytecodeViewerIs, "name_140466526081695"); getContentPane().add(txtrBytecodeViewerIs, "name_140466526081695");
txtrBytecodeViewerIs txtrBytecodeViewerIs
.setText("Bytecode Viewer "+BytecodeViewer.version+" is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\nDir: " .setText("Bytecode Viewer "+BytecodeViewer.version+" is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\nDir: C:\\Users\\null\\.Bytecode-Viewer\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSynaxPane by Robert Futrell\r\n Commons IO by Apache\r\n ASM by OW2\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n CFIDE by Bibl\r\n Smali by JesusFreke\r\n Dex2Jar by pxb1..?\r\n Krakatau by Storyyeller\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttps://the.bytecode.club");
+ BytecodeViewer.getBCVDirectory()
+ "\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSyntaxTextArea by Bobbylight\r\n Commons IO by Apache\r\n ASM by OW2\r\n CFIDE by Bibl\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttps://the.bytecode.club");
txtrBytecodeViewerIs.setEnabled(false); txtrBytecodeViewerIs.setEnabled(false);
this.setResizable(false); this.setResizable(false);
this.setLocationRelativeTo(null); this.setLocationRelativeTo(null);

View file

@ -47,8 +47,11 @@ import com.jhe.hexed.JHexEditor;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.JavaDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.KrakatauDisassembler;
import the.bytecode.club.bytecodeviewer.decompilers.KrakatauDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.Smali; import the.bytecode.club.bytecodeviewer.decompilers.SmaliDisassembler;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler;
/** /**
@ -118,6 +121,9 @@ public class ClassViewer extends JPanel {
public RSyntaxTextArea smali1 = null; public RSyntaxTextArea smali1 = null;
public RSyntaxTextArea smali2 = null; public RSyntaxTextArea smali2 = null;
public RSyntaxTextArea smali3 = null; public RSyntaxTextArea smali3 = null;
public RSyntaxTextArea krakatau1 = null;
public RSyntaxTextArea krakatau2 = null;
public RSyntaxTextArea krakatau3 = null;
/** /**
* This was really interesting to write. * This was really interesting to write.
@ -453,9 +459,10 @@ public class ClassViewer extends JPanel {
} }
} }
static FernFlowerDecompiler ff_dc = new FernFlowerDecompiler(); static JavaDecompiler ff_dc = new FernFlowerDecompiler();
static ProcyonDecompiler proc_dc = new ProcyonDecompiler(); static JavaDecompiler proc_dc = new ProcyonDecompiler();
static CFRDecompiler cfr_dc = new CFRDecompiler(); static JavaDecompiler cfr_dc = new CFRDecompiler();
static JavaDecompiler krak_dc = new KrakatauDecompiler();
PaneUpdaterThread t; PaneUpdaterThread t;
public void startPaneUpdater(final JButton button) { public void startPaneUpdater(final JButton button) {
@ -481,6 +488,12 @@ public class ClassViewer extends JPanel {
else if (BytecodeViewer.viewer.panelGroup1 else if (BytecodeViewer.viewer.panelGroup1
.isSelected(BytecodeViewer.viewer.panel1Smali.getModel())) .isSelected(BytecodeViewer.viewer.panel1Smali.getModel()))
pane1 = 6; pane1 = 6;
else if (BytecodeViewer.viewer.panelGroup1
.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel()))
pane1 = 7;
else if (BytecodeViewer.viewer.panelGroup1
.isSelected(BytecodeViewer.viewer.panel1KrakatauEditable.getModel()))
pane1 = 8;
if (BytecodeViewer.viewer.panelGroup2 if (BytecodeViewer.viewer.panelGroup2
.isSelected(BytecodeViewer.viewer.panel2None.getModel())) .isSelected(BytecodeViewer.viewer.panel2None.getModel()))
@ -503,6 +516,12 @@ public class ClassViewer extends JPanel {
else if (BytecodeViewer.viewer.panelGroup2 else if (BytecodeViewer.viewer.panelGroup2
.isSelected(BytecodeViewer.viewer.panel2Smali.getModel())) .isSelected(BytecodeViewer.viewer.panel2Smali.getModel()))
pane2 = 6; pane2 = 6;
else if (BytecodeViewer.viewer.panelGroup2
.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel()))
pane2 = 7;
else if (BytecodeViewer.viewer.panelGroup2
.isSelected(BytecodeViewer.viewer.panel2KrakatauEditable.getModel()))
pane2 = 8;
if (BytecodeViewer.viewer.panelGroup3 if (BytecodeViewer.viewer.panelGroup3
.isSelected(BytecodeViewer.viewer.panel3None.getModel())) .isSelected(BytecodeViewer.viewer.panel3None.getModel()))
@ -525,6 +544,12 @@ public class ClassViewer extends JPanel {
else if (BytecodeViewer.viewer.panelGroup3 else if (BytecodeViewer.viewer.panelGroup3
.isSelected(BytecodeViewer.viewer.panel3Smali.getModel())) .isSelected(BytecodeViewer.viewer.panel3Smali.getModel()))
pane3 = 6; pane3 = 6;
else if (BytecodeViewer.viewer.panelGroup3
.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel()))
pane3 = 7;
else if (BytecodeViewer.viewer.panelGroup3
.isSelected(BytecodeViewer.viewer.panel3KrakatauEditable.getModel()))
pane3 = 8;
t = new PaneUpdaterThread() { t = new PaneUpdaterThread() {
@Override @Override
@ -612,12 +637,41 @@ public class ClassViewer extends JPanel {
bytecodeArea.setAntiAliasingEnabled(true); bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane( RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea); bytecodeArea);
bytecodeArea.setText(Smali.decompileClassNode(cn)); bytecodeArea.setText(SmaliDisassembler.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0); bytecodeArea.setCaretPosition(0);
smali1 = bytecodeArea; smali1 = bytecodeArea;
panel1.add(bytecodeSPane); panel1.add(bytecodeSPane);
} }
if (pane1 == 7) {// krakatau
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(krak_dc.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
panel1.add(bytecodeSPane);
}
if (pane1 == 8) {// kraktau editable
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(KrakatauDisassembler.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
krakatau1 = bytecodeArea;
panel1.add(bytecodeSPane);
}
if (pane2 == 1) { if (pane2 == 1) {
RSyntaxTextArea panelArea = new RSyntaxTextArea(); RSyntaxTextArea panelArea = new RSyntaxTextArea();
panelArea panelArea
@ -682,12 +736,41 @@ public class ClassViewer extends JPanel {
paneArea.setCodeFoldingEnabled(true); paneArea.setCodeFoldingEnabled(true);
paneArea.setAntiAliasingEnabled(true); paneArea.setAntiAliasingEnabled(true);
RTextScrollPane scrollPane = new RTextScrollPane(paneArea); RTextScrollPane scrollPane = new RTextScrollPane(paneArea);
paneArea.setText(Smali.decompileClassNode(cn)); paneArea.setText(SmaliDisassembler.decompileClassNode(cn));
paneArea.setCaretPosition(0); paneArea.setCaretPosition(0);
smali2 = paneArea; smali2 = paneArea;
panel2.add(scrollPane); panel2.add(scrollPane);
} }
if (pane2 == 7) {// krakatau
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(krak_dc.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
panel2.add(bytecodeSPane);
}
if (pane2 == 8) {// kraktau editable
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(KrakatauDisassembler.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
krakatau2 = bytecodeArea;
panel2.add(bytecodeSPane);
}
if (pane3 == 1) { if (pane3 == 1) {
RSyntaxTextArea panelArea = new RSyntaxTextArea(); RSyntaxTextArea panelArea = new RSyntaxTextArea();
panelArea panelArea
@ -752,12 +835,41 @@ public class ClassViewer extends JPanel {
paneArea.setCodeFoldingEnabled(true); paneArea.setCodeFoldingEnabled(true);
paneArea.setAntiAliasingEnabled(true); paneArea.setAntiAliasingEnabled(true);
RTextScrollPane scrollPane = new RTextScrollPane(paneArea); RTextScrollPane scrollPane = new RTextScrollPane(paneArea);
paneArea.setText(Smali.decompileClassNode(cn)); paneArea.setText(SmaliDisassembler.decompileClassNode(cn));
paneArea.setCaretPosition(0); paneArea.setCaretPosition(0);
smali3 = paneArea; smali3 = paneArea;
panel3.add(scrollPane); panel3.add(scrollPane);
} }
if (pane3 == 7) {// krakatau
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(krak_dc.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
panel3.add(bytecodeSPane);
}
if (pane3 == 8) {// kraktau editable
RSyntaxTextArea bytecodeArea = new RSyntaxTextArea();
bytecodeArea
.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
bytecodeArea.setCodeFoldingEnabled(true);
bytecodeArea.setAntiAliasingEnabled(true);
RTextScrollPane bytecodeSPane = new RTextScrollPane(
bytecodeArea);
bytecodeArea.setText(KrakatauDisassembler.decompileClassNode(cn));
bytecodeArea.setCaretPosition(0);
krakatau3 = bytecodeArea;
panel3.add(bytecodeSPane);
}
resetDivider(); resetDivider();
BytecodeViewer.viewer.setIcon(false); BytecodeViewer.viewer.setIcon(false);
} catch(Exception e) { } catch(Exception e) {
@ -783,6 +895,17 @@ public class ClassViewer extends JPanel {
return null; return null;
} }
public Object[] getKrakatau() {
if(krakatau1 != null)
return new Object[]{cn, krakatau1.getText()};
if(krakatau2 != null)
return new Object[]{cn, krakatau2.getText()};
if(krakatau3 != null)
return new Object[]{cn, krakatau3.getText()};
return null;
}
public static class MethodData { public static class MethodData {
public String name, desc; public String name, desc;
public int srcLN, bytecodeLN; public int srcLN, bytecodeLN;

View file

@ -35,6 +35,8 @@ import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.JavaDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.KrakatauDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.ProcyonDecompiler;
import the.bytecode.club.bytecodeviewer.obfuscators.RenameClasses; import the.bytecode.club.bytecodeviewer.obfuscators.RenameClasses;
import the.bytecode.club.bytecodeviewer.obfuscators.RenameFields; import the.bytecode.club.bytecodeviewer.obfuscators.RenameFields;
@ -50,9 +52,40 @@ import javax.swing.JRadioButtonMenuItem;
public class MainViewerGUI extends JFrame implements FileChangeNotifier { public class MainViewerGUI extends JFrame implements FileChangeNotifier {
final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler(); public void pythonC() {
final ProcyonDecompiler proc_dc = new ProcyonDecompiler(); JFileChooser fc = new JFileChooser();
final CFRDecompiler cfr_dc = new CFRDecompiler(); fc.setFileFilter(new PythonCFileFilter());
fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
if (returnVal == JFileChooser.APPROVE_OPTION)
try {
BytecodeViewer.python = fc.getSelectedFile().getAbsolutePath();
} catch (Exception e1) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
}
}
public void rtC() {
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new RTCFileFilter());
fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
if (returnVal == JFileChooser.APPROVE_OPTION)
try {
BytecodeViewer.rt = fc.getSelectedFile().getAbsolutePath();
} catch (Exception e1) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
}
}
final JavaDecompiler ff_dc = new FernFlowerDecompiler();
final JavaDecompiler proc_dc = new ProcyonDecompiler();
final JavaDecompiler cfr_dc = new CFRDecompiler();
final JavaDecompiler krak_dc = new KrakatauDecompiler();
private static final long serialVersionUID = 1851409230530948543L; private static final long serialVersionUID = 1851409230530948543L;
public JCheckBoxMenuItem debugHelpers = new JCheckBoxMenuItem( public JCheckBoxMenuItem debugHelpers = new JCheckBoxMenuItem(
@ -391,9 +424,18 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
public final JRadioButtonMenuItem panel1Smali = new JRadioButtonMenuItem("Smali Editable"); public final JRadioButtonMenuItem panel1Smali = new JRadioButtonMenuItem("Smali Editable");
public final JRadioButtonMenuItem panel2Smali = new JRadioButtonMenuItem("Smali Editable"); public final JRadioButtonMenuItem panel2Smali = new JRadioButtonMenuItem("Smali Editable");
public final JRadioButtonMenuItem panel3Smali = new JRadioButtonMenuItem("Smali Editable"); public final JRadioButtonMenuItem panel3Smali = new JRadioButtonMenuItem("Smali Editable");
public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile Smali On Save"); public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile On Save");
private final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile Smali"); private final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile");
public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile Smali On Refresh"); public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile On Refresh");
private final JMenuItem mntmSetPythonDirectory = new JMenuItem("Set Python 2.7 Executable");
private final JSeparator separator_13 = new JSeparator();
public final JRadioButtonMenuItem panel1Krakatau = new JRadioButtonMenuItem("Krakatau");
public final JRadioButtonMenuItem panel1KrakatauEditable = new JRadioButtonMenuItem("Krakatau Editable");
public final JRadioButtonMenuItem panel2Krakatau = new JRadioButtonMenuItem("Krakatau");
public final JRadioButtonMenuItem panel2KrakatauEditable = new JRadioButtonMenuItem("Krakatau Editable");
public final JRadioButtonMenuItem panel3Krakatau = new JRadioButtonMenuItem("Krakatau");
public final JRadioButtonMenuItem panel3KrakatauEditable = new JRadioButtonMenuItem("Krakatau Editable");
private final JMenuItem mntmSetJreRt = new JMenuItem("Set JRE RT Library");
public void setIcon(final boolean busy) { public void setIcon(final boolean busy) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
@ -439,6 +481,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
panelGroup1.add(panel1Bytecode); panelGroup1.add(panel1Bytecode);
panelGroup1.add(panel1Smali); panelGroup1.add(panel1Smali);
panelGroup1.add(panel1Hexcode); panelGroup1.add(panel1Hexcode);
panelGroup1.add(panel1Krakatau);
panelGroup1.add(panel1KrakatauEditable);
panelGroup1.setSelected(panel1Proc.getModel(), true);//my one true love panelGroup1.setSelected(panel1Proc.getModel(), true);//my one true love
panelGroup2.add(panel2None); panelGroup2.add(panel2None);
panelGroup2.add(panel2Fern); panelGroup2.add(panel2Fern);
@ -447,6 +491,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
panelGroup2.add(panel2Bytecode); panelGroup2.add(panel2Bytecode);
panelGroup2.add(panel2Smali); panelGroup2.add(panel2Smali);
panelGroup2.add(panel2Hexcode); panelGroup2.add(panel2Hexcode);
panelGroup2.add(panel2Krakatau);
panelGroup2.add(panel2KrakatauEditable);
panelGroup2.setSelected(panel2Bytecode.getModel(), true); panelGroup2.setSelected(panel2Bytecode.getModel(), true);
panelGroup3.add(panel3None); panelGroup3.add(panel3None);
panelGroup3.add(panel3Fern); panelGroup3.add(panel3Fern);
@ -455,6 +501,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
panelGroup3.add(panel3Bytecode); panelGroup3.add(panel3Bytecode);
panelGroup3.add(panel3Smali); panelGroup3.add(panel3Smali);
panelGroup3.add(panel3Hexcode); panelGroup3.add(panel3Hexcode);
panelGroup3.add(panel3Krakatau);
panelGroup3.add(panel3KrakatauEditable);
panelGroup3.setSelected(panel3None.getModel(), true); panelGroup3.setSelected(panel3None.getModel(), true);
ActionListener listener = new ActionListener() { ActionListener listener = new ActionListener() {
@ -547,7 +595,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return; return;
} }
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false)) if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return; return;
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(new ZipFileFilter()); fc.setFileFilter(new ZipFileFilter());
@ -603,7 +651,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return; return;
} }
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false)) if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return; return;
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(new JarFileFilter()); fc.setFileFilter(new JarFileFilter());
@ -643,7 +691,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
}); });
mntmNewMenuItem_13.addActionListener(new ActionListener() { mntmNewMenuItem_13.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
BytecodeViewer.compileSmali(true); BytecodeViewer.compile(true);
} }
}); });
@ -656,7 +704,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return; return;
} }
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false)) if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return; return;
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(new DexFileFilter()); fc.setFileFilter(new DexFileFilter());
@ -722,7 +770,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return; return;
} }
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false)) if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return; return;
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(new ZipFileFilter()); fc.setFileFilter(new ZipFileFilter());
@ -762,7 +810,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
JOptionPane pane = new JOptionPane( JOptionPane pane = new JOptionPane(
"What decompiler will you use?"); "What decompiler will you use?");
Object[] options = new String[] { "Procyon", "CFR", Object[] options = new String[] { "Procyon", "CFR",
"Fernflower", "Cancel" }; "Fernflower", "Krakatau", "Cancel" };
pane.setOptions(options); pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
"Bytecode Viewer - Select Decompiler"); "Bytecode Viewer - Select Decompiler");
@ -781,8 +829,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
proc_dc.decompileToZip(path); proc_dc.decompileToZip(path);
BytecodeViewer.viewer.setIcon(false); BytecodeViewer.viewer.setIcon(false);
} catch (Exception e) { } catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI( new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e);
} }
} }
}; };
@ -796,8 +843,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
cfr_dc.decompileToZip(path); cfr_dc.decompileToZip(path);
BytecodeViewer.viewer.setIcon(false); BytecodeViewer.viewer.setIcon(false);
} catch (Exception e) { } catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI( new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e);
} }
} }
}; };
@ -811,13 +857,31 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
ff_dc.decompileToZip(path); ff_dc.decompileToZip(path);
BytecodeViewer.viewer.setIcon(false); BytecodeViewer.viewer.setIcon(false);
} catch (Exception e) { } catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI( new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
e);
} }
} }
}; };
t.start(); t.start();
} }
if (result == 3) {
Thread t = new Thread() {
@Override
public void run() {
try {
krak_dc.decompileToZip(path);
BytecodeViewer.viewer.setIcon(false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
};
t.start();
}
if(result == 4) {
BytecodeViewer.viewer.setIcon(false);
}
} }
} }
}); });
@ -827,7 +891,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file."); BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return; return;
} }
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false)) if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return; return;
final String s = workPane.getCurrentClass().name; final String s = workPane.getCurrentClass().name;
@ -867,7 +931,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
JOptionPane pane = new JOptionPane( JOptionPane pane = new JOptionPane(
"What decompiler will you use?"); "What decompiler will you use?");
Object[] options = new String[] { "Procyon", "CFR", Object[] options = new String[] { "Procyon", "CFR",
"Fernflower", "Cancel" }; "Fernflower", "Krakatau", "Cancel" };
pane.setOptions(options); pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
"Bytecode Viewer - Select Decompiler"); "Bytecode Viewer - Select Decompiler");
@ -923,6 +987,25 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
}; };
t.start(); t.start();
} }
if (result == 3) {
Thread t = new Thread() {
@Override
public void run() {
try {
krak_dc.decompileToClass(s,path);
BytecodeViewer.viewer.setIcon(false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(
e);
}
}
};
t.start();
}
if(result == 4) {
BytecodeViewer.viewer.setIcon(false);
}
} }
} }
}); });
@ -983,10 +1066,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnNewMenu_7.add(panel1Fern); mnNewMenu_7.add(panel1Fern);
mnNewMenu_7.add(panel1Krakatau);
mnNewMenu_7.add(separator_8); mnNewMenu_7.add(separator_8);
mnNewMenu_7.add(panel1Bytecode); mnNewMenu_7.add(panel1Bytecode);
mnNewMenu_7.add(panel1KrakatauEditable);
mnNewMenu_7.add(panel1Smali); mnNewMenu_7.add(panel1Smali);
mnNewMenu_7.add(panel1Hexcode); mnNewMenu_7.add(panel1Hexcode);
@ -1003,10 +1090,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnNewMenu_8.add(panel2Fern); mnNewMenu_8.add(panel2Fern);
mnNewMenu_8.add(panel2Krakatau);
mnNewMenu_8.add(separator_10); mnNewMenu_8.add(separator_10);
mnNewMenu_8.add(panel2Bytecode); mnNewMenu_8.add(panel2Bytecode);
mnNewMenu_8.add(panel2KrakatauEditable);
mnNewMenu_8.add(panel2Smali); mnNewMenu_8.add(panel2Smali);
mnNewMenu_8.add(panel2Hexcode); mnNewMenu_8.add(panel2Hexcode);
@ -1023,8 +1114,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnNewMenu_9.add(panel3Fern); mnNewMenu_9.add(panel3Fern);
mnNewMenu_9.add(panel3Krakatau);
mnNewMenu_9.add(separator_12); mnNewMenu_9.add(separator_12);
mnNewMenu_9.add(panel3KrakatauEditable);
mnNewMenu_9.add(panel3Bytecode); mnNewMenu_9.add(panel3Bytecode);
mnNewMenu_9.add(panel3Smali); mnNewMenu_9.add(panel3Smali);
@ -1041,6 +1136,22 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnSettings.add(refreshOnChange); mnSettings.add(refreshOnChange);
mnSettings.add(separator_13);
mntmSetPythonDirectory.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
pythonC();
}
});
mnSettings.add(mntmSetPythonDirectory);
mntmSetJreRt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
rtC();
}
});
mnSettings.add(mntmSetJreRt);
mnSettings.add(separator_6); mnSettings.add(separator_6);
mnSettings.add(mnNewMenu_4); mnSettings.add(mnNewMenu_4);
@ -1260,8 +1371,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mntmNewMenuItem_6.addActionListener(new ActionListener() { mntmNewMenuItem_6.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
if (BytecodeViewer.runningObfuscation) { if (BytecodeViewer.runningObfuscation) {
BytecodeViewer BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
return; return;
} }
new RenameFields().start(); new RenameFields().start();
@ -1281,8 +1391,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mntmNewMenuItem_7.addActionListener(new ActionListener() { mntmNewMenuItem_7.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
if (BytecodeViewer.runningObfuscation) { if (BytecodeViewer.runningObfuscation) {
BytecodeViewer BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
return; return;
} }
new RenameMethods().start(); new RenameMethods().start();
@ -1293,8 +1402,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mntmNewMenuItem_11.addActionListener(new ActionListener() { mntmNewMenuItem_11.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
if (BytecodeViewer.runningObfuscation) { if (BytecodeViewer.runningObfuscation) {
BytecodeViewer BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
return; return;
} }
new RenameClasses().start(); new RenameClasses().start();
@ -1319,10 +1427,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
if (!BytecodeViewer.loadedClasses.isEmpty()) if (!BytecodeViewer.loadedClasses.isEmpty())
PluginManager.runPlugin(new CodeSequenceDiagram()); PluginManager.runPlugin(new CodeSequenceDiagram());
else { else {
System.out System.out.println("Plugin not ran, put some classes in first.");
.println("Plugin not ran, put some classes in first."); BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
BytecodeViewer
.showMessage("Plugin not ran, put some classes in first.");
} }
} }
}); });
@ -1336,10 +1442,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
if (!BytecodeViewer.loadedClasses.isEmpty()) if (!BytecodeViewer.loadedClasses.isEmpty())
new ReplaceStringsOptions().setVisible(true); new ReplaceStringsOptions().setVisible(true);
else { else {
System.out System.out.println("Plugin not ran, put some classes in first.");
.println("Plugin not ran, put some classes in first."); BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
BytecodeViewer
.showMessage("Plugin not ran, put some classes in first.");
} }
} }
}); });
@ -1352,10 +1456,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
if (!BytecodeViewer.loadedClasses.isEmpty()) if (!BytecodeViewer.loadedClasses.isEmpty())
new EZInjectionOptions().setVisible(true); new EZInjectionOptions().setVisible(true);
else { else {
System.out System.out.println("Plugin not ran, put some classes in first.");
.println("Plugin not ran, put some classes in first."); BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
BytecodeViewer
.showMessage("Plugin not ran, put some classes in first.");
} }
} }
}); });
@ -1367,7 +1469,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mntmStartExternalPlugin.addActionListener(new ActionListener() { mntmStartExternalPlugin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(new GroovyPythonRubyFileFilter()); fc.setFileFilter(new GroovyFileFilter());
fc.setFileHidingEnabled(false); fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false); fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer); int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
@ -1397,10 +1499,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
if (!BytecodeViewer.loadedClasses.isEmpty()) if (!BytecodeViewer.loadedClasses.isEmpty())
new MaliciousCodeScannerOptions().setVisible(true); new MaliciousCodeScannerOptions().setVisible(true);
else { else {
System.out System.out.println("Plugin not ran, put some classes in first.");
.println("Plugin not ran, put some classes in first."); BytecodeViewer.showMessage("Plugin not ran, put some classes in first.");
BytecodeViewer
.showMessage("Plugin not ran, put some classes in first.");
} }
} }
}); });
@ -1417,7 +1517,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
}); });
setSize(new Dimension(800, 400)); setSize(new Dimension(800, 400));
setTitle("Bytecode Viewer "+BytecodeViewer.version+" - https://the.bytecode.club - @Konloch"); setTitle("Bytecode Viewer "+BytecodeViewer.version+" - https://bytecodeviewer.com | https://the.bytecode.club - @Konloch");
getContentPane().setLayout( getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.X_AXIS)); new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
@ -1514,6 +1614,36 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
} }
} }
public class GroovyFileFilter extends FileFilter {
@Override
public boolean accept(File f) {
if (f.isDirectory())
return true;
String extension = getExtension(f);
if (extension != null)
return (extension.equals("gy") || extension.equals("groovy"));
return false;
}
@Override
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 { public class APKDEXJarZipClassFileFilter extends FileFilter {
@Override @Override
public boolean accept(File f) { public boolean accept(File f) {
@ -1665,4 +1795,28 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
return ext; return ext;
} }
} }
public class PythonCFileFilter extends FileFilter {
@Override
public boolean accept(File f) {
return true;
}
@Override
public String getDescription() {
return "Python 2.7 Executable";
}
}
public class RTCFileFilter extends FileFilter {
@Override
public boolean accept(File f) {
return true;
}
@Override
public String getDescription() {
return "JRE RT Library";
}
}
} }

View file

@ -121,7 +121,7 @@ public class WorkPane extends VisibleComponent implements ActionListener {
public void actionPerformed(final ActionEvent arg0) { public void actionPerformed(final ActionEvent arg0) {
if(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()) if(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected())
try { try {
if(!BytecodeViewer.compileSmali(false)) if(!BytecodeViewer.compile(false))
return; return;
} catch(java.lang.NullPointerException e) { } catch(java.lang.NullPointerException e) {

View file

@ -13,7 +13,6 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;
import the.bytecode.club.bytecodeviewer.api.BytecodeHook; import the.bytecode.club.bytecodeviewer.api.BytecodeHook;
import the.bytecode.club.bytecodeviewer.api.Plugin; import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole; import the.bytecode.club.bytecodeviewer.api.PluginConsole;
@ -28,9 +27,6 @@ import the.bytecode.club.bytecodeviewer.gui.GraphicialReflectionKit;
* *
* @author Konloch * @author Konloch
* *
* TODO: figure out a way to block runtime.exec without java agents,
* maybe by replacing the method call?
*
*/ */
public class EZInjection extends Plugin { public class EZInjection extends Plugin {
@ -114,21 +110,6 @@ public class EZInjection extends Plugin {
gui.appendText(message); gui.appendText(message);
} }
public static void exit(int i) {
print("[SANDBOX] Tried to call on System.exit(" + i
+ "), it's been blocked.");
}
public static void exitR(int i) {
print("[SANDBOX] Tried to call on Runtime.exit(" + i
+ "), it's been blocked.");
}
public static void announceSystem(String s) {
print("[SANDBOX] Tried to call on Runtime.exec(" + s
+ "), it's been blocked.");
}
@Override @Override
public void execute(ArrayList<ClassNode> classNodeList) { public void execute(ArrayList<ClassNode> classNodeList) {
BytecodeViewer.viewer.setIcon(true); BytecodeViewer.viewer.setIcon(true);
@ -252,18 +233,6 @@ public class EZInjection extends Plugin {
} }
} }
if (sandboxRuntime) {
ASMUtil_OLD.renameClassNode("java/lang/Runtime",
"the/bytecode/club/bytecodeviewer/RuntimeOverride");
}
if (sandboxSystem) {
ASMUtil_OLD.renameMethodNode("java/lang/System", "exit",
"(Ljava/lang/String;)V",
"the/bytecode/club/bytecodeviewer/plugins/EZInjection",
null, null);
}
if (useProxy) { if (useProxy) {
try { try {
String[] split = proxy.split(":"); String[] split = proxy.split(":");