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.
This commit is contained in:
parent
58020b0891
commit
1cd3bfa92f
28 changed files with 1111 additions and 280 deletions
Binary file not shown.
Binary file not shown.
23
README.txt
23
README.txt
|
@ -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.
|
||||
|
||||
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:
|
||||
J-RET by WaterWolf
|
||||
|
@ -16,6 +16,7 @@ Code from various projects has been used, including but not limited to:
|
|||
CFIDE by Bibl
|
||||
Smali by JesusFreke
|
||||
Dex2Jar by pxb1..?
|
||||
Krakatau by Storyyeller
|
||||
|
||||
Contributors:
|
||||
Konloch
|
||||
|
@ -31,7 +32,7 @@ Contribution Guide Lines:
|
|||
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)
|
||||
|
||||
Video: http://the.bytecode.club/bytecodeviewer-video/
|
||||
Website: https://bytecodeviewer.com
|
||||
Source Code: https://github.com/konloch/bytecode-viewer
|
||||
Bin/Archive: https://github.com/konloch/bytecode-viewer/releases
|
||||
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
|
||||
|
||||
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!
|
||||
Java Decompiler - It utilizes FernFlower, Procyon and CFR for decompilation.
|
||||
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.
|
||||
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)
|
||||
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.
|
||||
Recent Files & Recent Plugins.
|
||||
And more! Give it a try for yourself!
|
||||
|
@ -276,4 +278,13 @@ Changelog:
|
|||
01/27/2015 - Decided to scrap the JVM Sandbox POC and use the Security Manager.
|
||||
01/27/2015 - BCV now blocks exec and won't allow any ports to be bound.
|
||||
--- 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
libs/jruby.jar
BIN
libs/jruby.jar
Binary file not shown.
Binary file not shown.
BIN
src/krakatau.zip
Normal file
BIN
src/krakatau.zip
Normal file
Binary file not shown.
|
@ -7,16 +7,13 @@ import java.awt.image.BufferedImage;
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.security.Permission;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -37,7 +34,7 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.imgscalr.Scalr;
|
||||
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.FileNavigationPane;
|
||||
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
|
||||
* 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
|
||||
* pre-written plugins, or write your own. It supports groovy
|
||||
* 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
|
||||
* 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.
|
||||
* -----2.7.1-----:
|
||||
* 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
|
||||
*
|
||||
|
@ -310,20 +316,29 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
|||
|
||||
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 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, byte[]> loadedResources = new HashMap<String, byte[]>();
|
||||
private static int maxRecentFiles = 25;
|
||||
public static String fs = System.getProperty("file.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 pluginsName = getBCVDirectory() + fs + "recentplugins.bcv";
|
||||
public static String settingsName = getBCVDirectory() + fs + "settings.bcv";
|
||||
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> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
|
||||
public static boolean runningObfuscation = false;
|
||||
public static String version = "2.7.1";
|
||||
private static long start = System.currentTimeMillis();
|
||||
public static String lastDirectory = "";
|
||||
private static Thread versionChecker = new Thread() {
|
||||
|
@ -502,51 +517,8 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
checkKrakatau();
|
||||
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
|
||||
iconList = new ArrayList<BufferedImage>();
|
||||
int size = 16;
|
||||
|
@ -616,7 +588,7 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
//called whenever a save function is executed
|
||||
public static boolean compileSmali(boolean message) {
|
||||
public static boolean compile(boolean message) {
|
||||
if(getLoadedClasses().isEmpty())
|
||||
return false;
|
||||
|
||||
|
@ -624,10 +596,10 @@ public class BytecodeViewer {
|
|||
if(c instanceof ClassViewer) {
|
||||
ClassViewer cv = (ClassViewer) c;
|
||||
Object smali[] = cv.getSmali();
|
||||
ClassNode origNode = (ClassNode) smali[0];
|
||||
String smaliText = (String) smali[1];
|
||||
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) {
|
||||
ClassNode newNode = JarUtils.getNode(smaliCompiled);
|
||||
System.out.println(origNode.name+":"+newNode.name);
|
||||
|
@ -637,6 +609,22 @@ public class BytecodeViewer {
|
|||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
public static void openFiles(final File[] files, boolean recentFiles) {
|
||||
if(recentFiles)
|
||||
|
@ -741,7 +753,6 @@ public class BytecodeViewer {
|
|||
JOptionPane.showMessageDialog(viewer, message);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void resetWorkSpace(boolean ask) {
|
||||
if(!ask) {
|
||||
loadedResources.clear();
|
||||
|
@ -759,7 +770,7 @@ public class BytecodeViewer {
|
|||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(viewer,
|
||||
"Bytecode Viewer - Reset Workspace");
|
||||
dialog.show();
|
||||
dialog.setVisible(true);
|
||||
Object obj = pane.getValue();
|
||||
int result = -1;
|
||||
for (int k = 0; k < options.length; k++)
|
||||
|
@ -793,8 +804,7 @@ public class BytecodeViewer {
|
|||
killList.clear();
|
||||
}
|
||||
|
||||
if (recentFiles.contains(f.getAbsolutePath())) // already added on the
|
||||
// list
|
||||
if (recentFiles.contains(f.getAbsolutePath())) // already added on the list
|
||||
recentFiles.remove(f.getAbsolutePath());
|
||||
if (recentFiles.size() >= maxRecentFiles)
|
||||
recentFiles.remove(maxRecentFiles - 1); // zero indexing
|
||||
|
@ -818,8 +828,7 @@ public class BytecodeViewer {
|
|||
killList2.clear();
|
||||
}
|
||||
|
||||
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the
|
||||
// list
|
||||
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the list
|
||||
recentPlugins.remove(f.getAbsolutePath());
|
||||
if (recentPlugins.size() >= maxRecentFiles)
|
||||
recentPlugins.remove(maxRecentFiles - 1); // zero indexing
|
||||
|
@ -887,15 +896,13 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
public static String getBCVDirectory() {
|
||||
File f = new File(System.getProperty("user.home") + fs
|
||||
+ ".Bytecode-Viewer");
|
||||
while (!f.exists())
|
||||
f.mkdirs();
|
||||
while (!BCVDir.exists())
|
||||
BCVDir.mkdirs();
|
||||
|
||||
if (!f.isHidden() && isWindows())
|
||||
hideFile(f);
|
||||
if (!BCVDir.isHidden() && isWindows())
|
||||
hideFile(BCVDir);
|
||||
|
||||
return f.getAbsolutePath();
|
||||
return BCVDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
|
@ -903,13 +910,14 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
private static void hideFile(File f) {
|
||||
System.out.println("hiding file");
|
||||
sm.blocking = false;
|
||||
try {
|
||||
// Hide file by running attrib system command (on Windows)
|
||||
Runtime.getRuntime().exec("attrib +H " + f.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
sm.blocking = true;
|
||||
}
|
||||
|
||||
private static String quickConvert(ArrayList<String> a) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package the.bytecode.club.bytecodeviewer;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Random;
|
||||
|
||||
public class MiscUtils {
|
||||
|
@ -20,4 +21,35 @@ public class MiscUtils {
|
|||
sb.append(AN.charAt(rnd.nextInt(AN.length())));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
53
src/the/bytecode/club/bytecodeviewer/SecurityMan.java
Normal file
53
src/the/bytecode/club/bytecodeviewer/SecurityMan.java
Normal 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) {}
|
||||
|
||||
}
|
|
@ -111,6 +111,10 @@ public class Settings {
|
|||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel()))
|
||||
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()))
|
||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
||||
|
@ -126,6 +130,10 @@ public class Settings {
|
|||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel()))
|
||||
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()))
|
||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
||||
|
@ -141,12 +149,18 @@ public class Settings {
|
|||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel()))
|
||||
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.isMaximized), 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, BytecodeViewer.lastDirectory, false);
|
||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python, false);
|
||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.rt, false);
|
||||
} catch(Exception 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);
|
||||
else if(decompiler == 6)
|
||||
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));
|
||||
if(decompiler == 0)
|
||||
|
@ -265,6 +283,10 @@ public class Settings {
|
|||
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true);
|
||||
else if(decompiler == 6)
|
||||
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));
|
||||
if(decompiler == 0)
|
||||
|
@ -281,6 +303,10 @@ public class Settings {
|
|||
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true);
|
||||
else if(decompiler == 6)
|
||||
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)));
|
||||
|
||||
|
@ -292,6 +318,8 @@ public class Settings {
|
|||
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.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) {
|
||||
//ignore because errors are expected, first start up and outdated settings.
|
||||
}
|
||||
|
|
|
@ -279,4 +279,47 @@ public final class ZipUtils {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,26 +17,21 @@ import the.bytecode.club.bytecodeviewer.plugins.EZInjection;
|
|||
|
||||
public class BytecodeViewer {
|
||||
|
||||
/**
|
||||
* This is used to define a global loader.
|
||||
*/
|
||||
private static ClassNodeLoader loader = new ClassNodeLoader();
|
||||
|
||||
/**
|
||||
* Grab the loader instance
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static ClassNodeLoader getClassNodeLoader() {
|
||||
return loader;
|
||||
return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of the ClassNode loader.
|
||||
*/
|
||||
public static void createNewClassNodeLoaderInstance() {
|
||||
loader.clear();
|
||||
loader = new ClassNodeLoader();
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear();
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,14 @@ public class ExceptionUI extends JFrame {
|
|||
public ExceptionUI(Exception e) {
|
||||
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
|
||||
|
@ -41,6 +49,16 @@ public class ExceptionUI extends JFrame {
|
|||
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) {
|
||||
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
|
@ -62,6 +80,23 @@ public class ExceptionUI extends JFrame {
|
|||
this.setLocationRelativeTo(null);
|
||||
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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,80 +1,19 @@
|
|||
package the.bytecode.club.bytecodeviewer.decompilers;
|
||||
package the.bytecode.club.bytecodeviewer.compilers;
|
||||
|
||||
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 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 Smali {
|
||||
|
||||
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 class SmaliAssembler {
|
||||
|
||||
public static byte[] compile(String contents) {
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
int fileNumber = JavaDecompiler.getClassNumber(fileStart, ".dex");
|
||||
int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex");
|
||||
|
||||
final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder"+BytecodeViewer.fs);
|
||||
tempSmaliFolder.mkdir();
|
|
@ -23,6 +23,7 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
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);
|
||||
cn.accept(cw);
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
|
||||
final File tempClass = new File(getUniqueName(fileStart, ".class") + ".class");
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs;
|
||||
|
||||
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
|
||||
|
||||
try {
|
||||
final FileOutputStream fos = new FileOutputStream(tempClass);
|
||||
|
@ -96,12 +96,12 @@ public class CFRDecompiler extends JavaDecompiler {
|
|||
e.printStackTrace();
|
||||
|
||||
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 "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) {
|
||||
|
@ -230,8 +230,7 @@ public class CFRDecompiler extends JavaDecompiler {
|
|||
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
|
||||
tempZip.getAbsolutePath());
|
||||
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
|
||||
+ "temp";
|
||||
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs;
|
||||
|
||||
String fuckery = fuckery(fileStart);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.JarUtils;
|
||||
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
cn.accept(cw);
|
||||
|
||||
String start = getUniqueName("", ".class");
|
||||
String start = MiscUtils.getUniqueName("", ".class");
|
||||
|
||||
final File tempClass = new File(start + ".class");
|
||||
|
||||
|
@ -104,7 +105,7 @@ public class FernFlowerDecompiler extends JavaDecompiler {
|
|||
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) {
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
package the.bytecode.club.bytecodeviewer.decompilers;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Konloch
|
||||
|
@ -19,33 +15,4 @@ public abstract class JavaDecompiler {
|
|||
public abstract void decompileToZip(String zipName);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,6 +39,7 @@ import com.strobel.assembler.metadata.TypeReference;
|
|||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
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
|
||||
+ "temp";
|
||||
|
||||
final File tempClass = new File(getUniqueName(fileStart, ".class") + ".class");
|
||||
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
|
||||
|
||||
try {
|
||||
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();
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -14,7 +14,7 @@ import java.awt.Color;
|
|||
public class AboutWindow extends JFrame {
|
||||
public AboutWindow() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
setSize(new Dimension(446, 374));
|
||||
setSize(new Dimension(446, 434));
|
||||
setType(Type.UTILITY);
|
||||
setTitle("Bytecode Viewer - About");
|
||||
getContentPane().setLayout(new CardLayout(0, 0));
|
||||
|
@ -24,9 +24,7 @@ public class AboutWindow extends JFrame {
|
|||
txtrBytecodeViewerIs.setWrapStyleWord(true);
|
||||
getContentPane().add(txtrBytecodeViewerIs, "name_140466526081695");
|
||||
txtrBytecodeViewerIs
|
||||
.setText("Bytecode Viewer "+BytecodeViewer.version+" is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\nDir: "
|
||||
+ 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");
|
||||
.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");
|
||||
txtrBytecodeViewerIs.setEnabled(false);
|
||||
this.setResizable(false);
|
||||
this.setLocationRelativeTo(null);
|
||||
|
|
|
@ -47,8 +47,11 @@ import com.jhe.hexed.JHexEditor;
|
|||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler;
|
||||
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.Smali;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.SmaliDisassembler;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler;
|
||||
|
||||
/**
|
||||
|
@ -118,6 +121,9 @@ public class ClassViewer extends JPanel {
|
|||
public RSyntaxTextArea smali1 = null;
|
||||
public RSyntaxTextArea smali2 = null;
|
||||
public RSyntaxTextArea smali3 = null;
|
||||
public RSyntaxTextArea krakatau1 = null;
|
||||
public RSyntaxTextArea krakatau2 = null;
|
||||
public RSyntaxTextArea krakatau3 = null;
|
||||
|
||||
/**
|
||||
* This was really interesting to write.
|
||||
|
@ -453,9 +459,10 @@ public class ClassViewer extends JPanel {
|
|||
}
|
||||
}
|
||||
|
||||
static FernFlowerDecompiler ff_dc = new FernFlowerDecompiler();
|
||||
static ProcyonDecompiler proc_dc = new ProcyonDecompiler();
|
||||
static CFRDecompiler cfr_dc = new CFRDecompiler();
|
||||
static JavaDecompiler ff_dc = new FernFlowerDecompiler();
|
||||
static JavaDecompiler proc_dc = new ProcyonDecompiler();
|
||||
static JavaDecompiler cfr_dc = new CFRDecompiler();
|
||||
static JavaDecompiler krak_dc = new KrakatauDecompiler();
|
||||
PaneUpdaterThread t;
|
||||
|
||||
public void startPaneUpdater(final JButton button) {
|
||||
|
@ -481,6 +488,12 @@ public class ClassViewer extends JPanel {
|
|||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1Smali.getModel()))
|
||||
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
|
||||
.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||
|
@ -503,6 +516,12 @@ public class ClassViewer extends JPanel {
|
|||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2Smali.getModel()))
|
||||
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
|
||||
.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||
|
@ -525,6 +544,12 @@ public class ClassViewer extends JPanel {
|
|||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3Smali.getModel()))
|
||||
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() {
|
||||
@Override
|
||||
|
@ -612,12 +637,41 @@ public class ClassViewer extends JPanel {
|
|||
bytecodeArea.setAntiAliasingEnabled(true);
|
||||
RTextScrollPane bytecodeSPane = new RTextScrollPane(
|
||||
bytecodeArea);
|
||||
bytecodeArea.setText(Smali.decompileClassNode(cn));
|
||||
bytecodeArea.setText(SmaliDisassembler.decompileClassNode(cn));
|
||||
bytecodeArea.setCaretPosition(0);
|
||||
smali1 = bytecodeArea;
|
||||
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) {
|
||||
RSyntaxTextArea panelArea = new RSyntaxTextArea();
|
||||
panelArea
|
||||
|
@ -682,12 +736,41 @@ public class ClassViewer extends JPanel {
|
|||
paneArea.setCodeFoldingEnabled(true);
|
||||
paneArea.setAntiAliasingEnabled(true);
|
||||
RTextScrollPane scrollPane = new RTextScrollPane(paneArea);
|
||||
paneArea.setText(Smali.decompileClassNode(cn));
|
||||
paneArea.setText(SmaliDisassembler.decompileClassNode(cn));
|
||||
paneArea.setCaretPosition(0);
|
||||
smali2 = paneArea;
|
||||
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) {
|
||||
RSyntaxTextArea panelArea = new RSyntaxTextArea();
|
||||
panelArea
|
||||
|
@ -752,12 +835,41 @@ public class ClassViewer extends JPanel {
|
|||
paneArea.setCodeFoldingEnabled(true);
|
||||
paneArea.setAntiAliasingEnabled(true);
|
||||
RTextScrollPane scrollPane = new RTextScrollPane(paneArea);
|
||||
paneArea.setText(Smali.decompileClassNode(cn));
|
||||
paneArea.setText(SmaliDisassembler.decompileClassNode(cn));
|
||||
paneArea.setCaretPosition(0);
|
||||
smali3 = paneArea;
|
||||
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();
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
} catch(Exception e) {
|
||||
|
@ -771,7 +883,7 @@ public class ClassViewer extends JPanel {
|
|||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
||||
public Object[] getSmali() {
|
||||
if(smali1 != null)
|
||||
return new Object[]{cn, smali1.getText()};
|
||||
|
@ -782,6 +894,17 @@ public class ClassViewer extends JPanel {
|
|||
|
||||
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 String name, desc;
|
||||
|
|
|
@ -35,6 +35,8 @@ import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
|||
import the.bytecode.club.bytecodeviewer.JarUtils;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.CFRDecompiler;
|
||||
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.obfuscators.RenameClasses;
|
||||
import the.bytecode.club.bytecodeviewer.obfuscators.RenameFields;
|
||||
|
@ -49,10 +51,41 @@ import java.util.ArrayList;
|
|||
import javax.swing.JRadioButtonMenuItem;
|
||||
|
||||
public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||
|
||||
public void pythonC() {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileFilter(new PythonCFileFilter());
|
||||
fc.setFileHidingEnabled(false);
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
|
||||
|
||||
final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler();
|
||||
final ProcyonDecompiler proc_dc = new ProcyonDecompiler();
|
||||
final CFRDecompiler cfr_dc = new CFRDecompiler();
|
||||
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;
|
||||
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 panel2Smali = new JRadioButtonMenuItem("Smali Editable");
|
||||
public final JRadioButtonMenuItem panel3Smali = new JRadioButtonMenuItem("Smali Editable");
|
||||
public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile Smali On Save");
|
||||
private final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile Smali");
|
||||
public final JCheckBoxMenuItem autoCompileOnRefresh = new JCheckBoxMenuItem("Compile Smali On Refresh");
|
||||
public final JCheckBoxMenuItem autoCompileSmali = new JCheckBoxMenuItem("Compile On Save");
|
||||
private final JMenuItem mntmNewMenuItem_13 = new JMenuItem("Compile");
|
||||
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) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
|
@ -439,6 +481,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
panelGroup1.add(panel1Bytecode);
|
||||
panelGroup1.add(panel1Smali);
|
||||
panelGroup1.add(panel1Hexcode);
|
||||
panelGroup1.add(panel1Krakatau);
|
||||
panelGroup1.add(panel1KrakatauEditable);
|
||||
panelGroup1.setSelected(panel1Proc.getModel(), true);//my one true love
|
||||
panelGroup2.add(panel2None);
|
||||
panelGroup2.add(panel2Fern);
|
||||
|
@ -447,6 +491,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
panelGroup2.add(panel2Bytecode);
|
||||
panelGroup2.add(panel2Smali);
|
||||
panelGroup2.add(panel2Hexcode);
|
||||
panelGroup2.add(panel2Krakatau);
|
||||
panelGroup2.add(panel2KrakatauEditable);
|
||||
panelGroup2.setSelected(panel2Bytecode.getModel(), true);
|
||||
panelGroup3.add(panel3None);
|
||||
panelGroup3.add(panel3Fern);
|
||||
|
@ -455,6 +501,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
panelGroup3.add(panel3Bytecode);
|
||||
panelGroup3.add(panel3Smali);
|
||||
panelGroup3.add(panel3Hexcode);
|
||||
panelGroup3.add(panel3Krakatau);
|
||||
panelGroup3.add(panel3KrakatauEditable);
|
||||
panelGroup3.setSelected(panel3None.getModel(), true);
|
||||
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false))
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
|
||||
return;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false))
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
|
||||
return;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileFilter(new JarFileFilter());
|
||||
|
@ -643,7 +691,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
});
|
||||
mntmNewMenuItem_13.addActionListener(new ActionListener() {
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false))
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
|
||||
return;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false))
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
|
||||
return;
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileFilter(new ZipFileFilter());
|
||||
|
@ -762,7 +810,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
JOptionPane pane = new JOptionPane(
|
||||
"What decompiler will you use?");
|
||||
Object[] options = new String[] { "Procyon", "CFR",
|
||||
"Fernflower", "Cancel" };
|
||||
"Fernflower", "Krakatau", "Cancel" };
|
||||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||
"Bytecode Viewer - Select Decompiler");
|
||||
|
@ -781,8 +829,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
proc_dc.decompileToZip(path);
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(
|
||||
e);
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -796,8 +843,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
cfr_dc.decompileToZip(path);
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(
|
||||
e);
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -811,13 +857,31 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
ff_dc.decompileToZip(path);
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
} catch (Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(
|
||||
e);
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compileSmali(false))
|
||||
if(autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
|
||||
return;
|
||||
final String s = workPane.getCurrentClass().name;
|
||||
|
||||
|
@ -867,7 +931,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
JOptionPane pane = new JOptionPane(
|
||||
"What decompiler will you use?");
|
||||
Object[] options = new String[] { "Procyon", "CFR",
|
||||
"Fernflower", "Cancel" };
|
||||
"Fernflower", "Krakatau", "Cancel" };
|
||||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||
"Bytecode Viewer - Select Decompiler");
|
||||
|
@ -923,6 +987,25 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
};
|
||||
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(panel1Krakatau);
|
||||
|
||||
mnNewMenu_7.add(separator_8);
|
||||
|
||||
mnNewMenu_7.add(panel1Bytecode);
|
||||
|
||||
mnNewMenu_7.add(panel1KrakatauEditable);
|
||||
|
||||
mnNewMenu_7.add(panel1Smali);
|
||||
|
||||
mnNewMenu_7.add(panel1Hexcode);
|
||||
|
@ -1003,10 +1090,14 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
mnNewMenu_8.add(panel2Fern);
|
||||
|
||||
mnNewMenu_8.add(panel2Krakatau);
|
||||
|
||||
mnNewMenu_8.add(separator_10);
|
||||
|
||||
mnNewMenu_8.add(panel2Bytecode);
|
||||
|
||||
mnNewMenu_8.add(panel2KrakatauEditable);
|
||||
|
||||
mnNewMenu_8.add(panel2Smali);
|
||||
|
||||
mnNewMenu_8.add(panel2Hexcode);
|
||||
|
@ -1023,7 +1114,11 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
mnNewMenu_9.add(panel3Fern);
|
||||
|
||||
mnNewMenu_9.add(panel3Krakatau);
|
||||
|
||||
mnNewMenu_9.add(separator_12);
|
||||
|
||||
mnNewMenu_9.add(panel3KrakatauEditable);
|
||||
|
||||
mnNewMenu_9.add(panel3Bytecode);
|
||||
|
||||
|
@ -1041,6 +1136,22 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
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(mnNewMenu_4);
|
||||
|
||||
|
@ -1260,8 +1371,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mntmNewMenuItem_6.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (BytecodeViewer.runningObfuscation) {
|
||||
BytecodeViewer
|
||||
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
return;
|
||||
}
|
||||
new RenameFields().start();
|
||||
|
@ -1281,8 +1391,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mntmNewMenuItem_7.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (BytecodeViewer.runningObfuscation) {
|
||||
BytecodeViewer
|
||||
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
return;
|
||||
}
|
||||
new RenameMethods().start();
|
||||
|
@ -1293,8 +1402,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mntmNewMenuItem_11.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (BytecodeViewer.runningObfuscation) {
|
||||
BytecodeViewer
|
||||
.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
BytecodeViewer.showMessage("You're currently running an obfuscation task, wait for this to finish.");
|
||||
return;
|
||||
}
|
||||
new RenameClasses().start();
|
||||
|
@ -1319,10 +1427,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
if (!BytecodeViewer.loadedClasses.isEmpty())
|
||||
PluginManager.runPlugin(new CodeSequenceDiagram());
|
||||
else {
|
||||
System.out
|
||||
.println("Plugin not ran, put some classes in first.");
|
||||
BytecodeViewer
|
||||
.showMessage("Plugin not ran, put some classes in first.");
|
||||
System.out.println("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())
|
||||
new ReplaceStringsOptions().setVisible(true);
|
||||
else {
|
||||
System.out
|
||||
.println("Plugin not ran, put some classes in first.");
|
||||
BytecodeViewer
|
||||
.showMessage("Plugin not ran, put some classes in first.");
|
||||
System.out.println("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())
|
||||
new EZInjectionOptions().setVisible(true);
|
||||
else {
|
||||
System.out
|
||||
.println("Plugin not ran, put some classes in first.");
|
||||
BytecodeViewer
|
||||
.showMessage("Plugin not ran, put some classes in first.");
|
||||
System.out.println("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() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileFilter(new GroovyPythonRubyFileFilter());
|
||||
fc.setFileFilter(new GroovyFileFilter());
|
||||
fc.setFileHidingEnabled(false);
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
|
||||
|
@ -1397,10 +1499,8 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
if (!BytecodeViewer.loadedClasses.isEmpty())
|
||||
new MaliciousCodeScannerOptions().setVisible(true);
|
||||
else {
|
||||
System.out
|
||||
.println("Plugin not ran, put some classes in first.");
|
||||
BytecodeViewer
|
||||
.showMessage("Plugin not ran, put some classes in first.");
|
||||
System.out.println("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));
|
||||
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(
|
||||
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 {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
|
@ -1665,4 +1795,28 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
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";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,7 +121,7 @@ public class WorkPane extends VisibleComponent implements ActionListener {
|
|||
public void actionPerformed(final ActionEvent arg0) {
|
||||
if(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected())
|
||||
try {
|
||||
if(!BytecodeViewer.compileSmali(false))
|
||||
if(!BytecodeViewer.compile(false))
|
||||
return;
|
||||
} catch(java.lang.NullPointerException e) {
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import org.objectweb.asm.tree.MethodInsnNode;
|
|||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
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.Plugin;
|
||||
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
||||
|
@ -28,9 +27,6 @@ import the.bytecode.club.bytecodeviewer.gui.GraphicialReflectionKit;
|
|||
*
|
||||
* @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 {
|
||||
|
@ -114,21 +110,6 @@ public class EZInjection extends Plugin {
|
|||
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
|
||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||
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) {
|
||||
try {
|
||||
String[] split = proxy.split(":");
|
||||
|
|
Loading…
Reference in a new issue