2.5.0
12/28/2014 - Improved the outdated version pane by including an automatic downloader - http://i.imgur.com/4MXeBGb.png - http://i.imgur.com/v50Pghe.png - http://i.imgur.com/bVZqxZ2.png - http://i.imgur.com/l8nIMzD.png 12/28/2014 - Updated CFR to cfr_0.92.jar 12/31/2014 - Adrianherrera updated the Malicious Code Scanner to detect the security manager being set to null. **HAPPY NEW YEAR** 01/01/2015 - Added refresh class on decompiler/pane view change 01/01/2015 - Moved all of the settings into a settings pane 01/01/2015 - Added some debug code when you first start it up, it also includes how long it took to fully load up. 01/02/2015 - Cached the busy icon. 01/02/2015 - ADDED APK SUPPORT, had to downgrade to ASM 3.3, which means losing some annotation debugging for the Bytecode Decompiler. 01/03/2015 - Wrapped the search pane in a JScrollPane. 01/06/2015 - Added save as DEX and import .dex files.
This commit is contained in:
parent
8adee814cc
commit
bb95011f47
29 changed files with 673 additions and 311 deletions
Binary file not shown.
24
README.txt
24
README.txt
|
@ -1,4 +1,4 @@
|
||||||
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
|
Bytecode Viewer is an Advanced Lightweight Java Bytecode Viewer, GUI APK Decompiler, GUI DEX Decompiler, GUI Procyon Java Decompiler, GUI CFR Java Decompiler, GUI FernFlower Java Decompiler, GUI Jar-Jar, Hex Viewer, Code Searcher, Debugger and more.
|
||||||
It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch.
|
It's written completely in Java, and it's open sourced. It's currently being maintained and developed by Konloch.
|
||||||
|
|
||||||
There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of.
|
There is also a plugin system that will allow you to interact with the loaded classfiles, for example you can write a String deobfuscator, a malicious code searcher, or something else you can think of.
|
||||||
|
@ -38,15 +38,15 @@ Report Bugs (or below): https://github.com/Konloch/bytecode-viewer/issues
|
||||||
Discussion Forum: https://the.bytecode.club/forumdisplay.php?fid=69
|
Discussion Forum: https://the.bytecode.club/forumdisplay.php?fid=69
|
||||||
|
|
||||||
Key Features:
|
Key Features:
|
||||||
Java Decompiler - It uses a modified version of FernFlower, Procyon and CFR.
|
Java Decompiler - It utilizes FernFlower, Procyon and CFR for decompilation.
|
||||||
Bytecode Decompiler - A modified version of CFIDE's.
|
Bytecode Decompiler - A modified version of CFIDE's.
|
||||||
Hex Viewer - Powered by JHexPane.
|
Hex Viewer - Powered by JHexPane.
|
||||||
Each Decompiler/Viewer is toggleable.
|
Each Decompiler/Viewer is toggleable, you can also select what will display on each pane.
|
||||||
Fully Featured Search System.
|
Fully Featured Search System - Search through strings, functions, variables and more!
|
||||||
A Plugin System With Built In Plugins. (Show All Strings, Malicious Code Scanner, String Decrypters, etc)
|
A Plugin System With Built In Plugins - (Show All Strings, Malicious Code Scanner, String Decrypters, etc)
|
||||||
Fully Featured Scripting System That Supports Groovy, Python And Ruby.
|
Fully Featured Scripting System That Supports Groovy, Python And Ruby.
|
||||||
Recent Files & Recent Plugins.
|
|
||||||
EZ-Inject - Graphically insert hooks and debugging code, invoke main and start the program.
|
EZ-Inject - Graphically insert hooks and debugging code, invoke main and start the program.
|
||||||
|
Recent Files & Recent Plugins.
|
||||||
And more! Give it a try for yourself!
|
And more! Give it a try for yourself!
|
||||||
|
|
||||||
Are you a Java Reverse Engineer? Do you want to learn?
|
Are you a Java Reverse Engineer? Do you want to learn?
|
||||||
|
@ -219,3 +219,15 @@ Changelog:
|
||||||
12/20/2014 - If the class file does not start with CAFEBABE it won't be processed.
|
12/20/2014 - If the class file does not start with CAFEBABE it won't be processed.
|
||||||
12/20/2014 - Properly handled file not found error.
|
12/20/2014 - Properly handled file not found error.
|
||||||
12/21/2014 - Fixed the Refresh Class causing a dupe.
|
12/21/2014 - Fixed the Refresh Class causing a dupe.
|
||||||
|
--- 2.5.0 ---:
|
||||||
|
12/28/2014 - Improved the outdated version pane by including an automatic downloader - http://i.imgur.com/4MXeBGb.png - http://i.imgur.com/v50Pghe.png - http://i.imgur.com/bVZqxZ2.png - http://i.imgur.com/l8nIMzD.png
|
||||||
|
12/28/2014 - Updated CFR to cfr_0.92.jar
|
||||||
|
12/31/2014 - Adrianherrera updated the Malicious Code Scanner to detect the security manager being set to null.
|
||||||
|
**HAPPY NEW YEAR**
|
||||||
|
01/01/2015 - Added refresh class on decompiler/pane view change
|
||||||
|
01/01/2015 - Moved all of the settings into a settings pane
|
||||||
|
01/01/2015 - Added some debug code when you first start it up, it also includes how long it took to fully load up.
|
||||||
|
01/02/2015 - Cached the busy icon.
|
||||||
|
01/02/2015 - ADDED APK SUPPORT, had to downgrade to ASM 3.3, which means losing some annotation debugging for the Bytecode Decompiler.
|
||||||
|
01/03/2015 - Wrapped the search pane in a JScrollPane.
|
||||||
|
01/06/2015 - Added save as DEX and import .dex files.
|
BIN
libs/asm-all-3.3.1.jar
Normal file
BIN
libs/asm-all-3.3.1.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
libs/dex-ir-1.12.jar
Normal file
BIN
libs/dex-ir-1.12.jar
Normal file
Binary file not shown.
BIN
libs/dex-reader-1.15.jar
Normal file
BIN
libs/dex-reader-1.15.jar
Normal file
Binary file not shown.
BIN
libs/dex-tools-0.0.9.15.jar
Normal file
BIN
libs/dex-tools-0.0.9.15.jar
Normal file
Binary file not shown.
BIN
libs/dex-translator-0.0.9.15.jar
Normal file
BIN
libs/dex-translator-0.0.9.15.jar
Normal file
Binary file not shown.
BIN
libs/dx.jar
Normal file
BIN
libs/dx.jar
Normal file
Binary file not shown.
BIN
libs/jar-rename-1.6.jar
Normal file
BIN
libs/jar-rename-1.6.jar
Normal file
Binary file not shown.
BIN
libs/jasmin-p2.5.jar
Normal file
BIN
libs/jasmin-p2.5.jar
Normal file
Binary file not shown.
|
@ -8,6 +8,9 @@ import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -18,6 +21,7 @@ import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
@ -62,14 +66,16 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
||||||
* TODO:
|
* TODO:
|
||||||
* The import jar method eats up a lot of memory, look into some how reducing this.
|
* The import jar method eats up a lot of memory, look into some how reducing this.
|
||||||
* Add a tool to build a flowchart of all the classes, and what methods execute what classes, and those method, read chatlog
|
* Add a tool to build a flowchart of all the classes, and what methods execute what classes, and those method, read chatlog
|
||||||
* Add obfuscation
|
* Add obfuscation:
|
||||||
* Add progress bars on saving all zips/java decompile jar
|
|
||||||
* Add the jump/save mark system Ida Pro has.
|
|
||||||
* Add integer boxing and other obfuscation methods contra implemented
|
* Add integer boxing and other obfuscation methods contra implemented
|
||||||
* Insert unadded/debug opcodes to try to fuck up decompilers
|
* Insert unadded/debug opcodes to try to fuck up decompilers
|
||||||
* ClassAnylyzterAdapter
|
* ClassAnylyzterAdapter
|
||||||
|
* Add progress bars on saving all zips/java decompile jar
|
||||||
|
* Add the jump/save mark system Ida Pro has.
|
||||||
* Add class annotations to bytecode decompiler.
|
* Add class annotations to bytecode decompiler.
|
||||||
* Option to make the bytecode pane automatically scroll to where the source code pane is
|
* Option to make the bytecode pane automatically scroll to where the source code pane is
|
||||||
|
* Replacing all string field calls with the string instance - would require EZ-Injection to run code?
|
||||||
|
* Spiffy up the plugin console with red text optional, would require JTextPane, not JTextArea.
|
||||||
*
|
*
|
||||||
* ----Beta 1.0.0-----:
|
* ----Beta 1.0.0-----:
|
||||||
* 10/4/2014 - Designed a POC GUI, still needs a lot of work.
|
* 10/4/2014 - Designed a POC GUI, still needs a lot of work.
|
||||||
|
@ -236,6 +242,18 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
||||||
* 12/20/2014 - If the class file does not start with CAFEBABE it won't be processed.
|
* 12/20/2014 - If the class file does not start with CAFEBABE it won't be processed.
|
||||||
* 12/20/2014 - Properly handled file not found error.
|
* 12/20/2014 - Properly handled file not found error.
|
||||||
* 12/21/2014 - Fixed the Refresh Class causing a dupe.
|
* 12/21/2014 - Fixed the Refresh Class causing a dupe.
|
||||||
|
* -----2.5.0-----:
|
||||||
|
* 12/28/2014 - Improved the outdated version pane by including an automatic downloader - http://i.imgur.com/4MXeBGb.png - http://i.imgur.com/v50Pghe.png - http://i.imgur.com/bVZqxZ2.png - http://i.imgur.com/l8nIMzD.png
|
||||||
|
* 12/28/2014 - Updated CFR to cfr_0.92.jar
|
||||||
|
* 12/31/2014 - Adrianherrera updated the Malicious Code Scanner to detect the security manager being set to null.
|
||||||
|
* **HAPPY NEW YEAR**
|
||||||
|
* 01/01/2015 - Added refresh class on decompiler/pane view change
|
||||||
|
* 01/01/2015 - Moved all of the settings into a settings pane
|
||||||
|
* 01/01/2015 - Added some debug code when you first start it up, it also includes how long it took to fully load up.
|
||||||
|
* 01/02/2015 - Cached the busy icon.
|
||||||
|
* 01/02/2015 - ADDED APK SUPPORT, had to downgrade to ASM 3.3, which means losing some annotation debugging for the Bytecode Decompiler.
|
||||||
|
* 01/03/2015 - Wrapped the search pane in a JScrollPane.
|
||||||
|
* 01/06/2015 - Added save as DEX and import .dex files.
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
*
|
*
|
||||||
|
@ -256,9 +274,11 @@ public class BytecodeViewer {
|
||||||
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
|
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
|
||||||
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
|
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
|
||||||
public static boolean runningObfuscation = false;
|
public static boolean runningObfuscation = false;
|
||||||
public static String version = "2.4.0";
|
public static String version = "2.5.0";
|
||||||
|
private static long start = System.currentTimeMillis();
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
|
||||||
iconList = new ArrayList<BufferedImage>();
|
iconList = new ArrayList<BufferedImage>();
|
||||||
int size = 16;
|
int size = 16;
|
||||||
for (int i = 0; i < 24; i++) {
|
for (int i = 0; i < 24; i++) {
|
||||||
|
@ -295,7 +315,7 @@ public class BytecodeViewer {
|
||||||
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0");
|
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0");
|
||||||
BufferedReader reader = new BufferedReader(
|
BufferedReader reader = new BufferedReader(
|
||||||
new InputStreamReader(connection.getInputStream()));
|
new InputStreamReader(connection.getInputStream()));
|
||||||
String version = reader.readLine();
|
final String version = reader.readLine();
|
||||||
reader.close();
|
reader.close();
|
||||||
if (!BytecodeViewer.version.equals(version)) {
|
if (!BytecodeViewer.version.equals(version)) {
|
||||||
connection = (HttpURLConnection) new URL(
|
connection = (HttpURLConnection) new URL(
|
||||||
|
@ -312,11 +332,13 @@ public class BytecodeViewer {
|
||||||
readme.add(s);
|
readme.add(s);
|
||||||
reader.close();
|
reader.close();
|
||||||
|
|
||||||
String changelog = "";
|
String changelog = "Unable to load change log, please try again later."+nl;
|
||||||
boolean trigger = false;
|
boolean trigger = false;
|
||||||
for(String st : readme) {
|
for(String st : readme) {
|
||||||
if(st.equals("--- "+version+" ---:"))
|
if(st.equals("--- "+version+" ---:")) {
|
||||||
|
changelog = "";
|
||||||
trigger = true;
|
trigger = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(trigger == true && !st.equals("--- "+version+" ---:")) {
|
if(trigger == true && !st.equals("--- "+version+" ---:")) {
|
||||||
if(st.startsWith("--- "))
|
if(st.startsWith("--- "))
|
||||||
|
@ -336,8 +358,8 @@ public class BytecodeViewer {
|
||||||
+ nl
|
+ nl
|
||||||
+ changelog
|
+ changelog
|
||||||
+ nl
|
+ nl
|
||||||
+ "Would you like to automatically open the download page? (https://github.com/Konloch/bytecode-viewer/releases)");
|
+ "What would you like to do?");
|
||||||
Object[] options = new String[] { "Yes", "No" };
|
Object[] options = new String[] { "Open The Download Page", "Download The Updated Jar", "Do Nothing" };
|
||||||
pane.setOptions(options);
|
pane.setOptions(options);
|
||||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||||
"Bytecode Viewer - Outdated Version");
|
"Bytecode Viewer - Outdated Version");
|
||||||
|
@ -356,6 +378,92 @@ public class BytecodeViewer {
|
||||||
showMessage("Cannot open the page, please manually type it.");
|
showMessage("Cannot open the page, please manually type it.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(result == 1) {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
try {
|
||||||
|
fc.setCurrentDirectory(new File(".").getAbsoluteFile()); //set the current working directory
|
||||||
|
} catch(Exception e) {
|
||||||
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
}
|
||||||
|
fc.setFileFilter(viewer.new JarFileFilter());
|
||||||
|
fc.setFileHidingEnabled(false);
|
||||||
|
fc.setAcceptAllFileFilterUsed(false);
|
||||||
|
int returnVal = fc.showSaveDialog(viewer);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = fc.getSelectedFile();
|
||||||
|
if(!file.getAbsolutePath().endsWith(".jar"))
|
||||||
|
file = new File(file.getAbsolutePath()+".jar");
|
||||||
|
|
||||||
|
if(file.exists()) {
|
||||||
|
pane = new JOptionPane("The file " + file + " exists, would you like to overwrite it?");
|
||||||
|
options = new String[] { "Yes", "No" };
|
||||||
|
pane.setOptions(options);
|
||||||
|
dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||||
|
"Bytecode Viewer - Overwrite File");
|
||||||
|
dialog.setVisible(true);
|
||||||
|
obj = pane.getValue();
|
||||||
|
result = -1;
|
||||||
|
for (int k = 0; k < options.length; k++)
|
||||||
|
if (options[k].equals(obj))
|
||||||
|
result = k;
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
final File finalFile = file;
|
||||||
|
Thread downloadThread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
InputStream is = new URL("https://github.com/Konloch/bytecode-viewer/releases/download/v"+version+"/BytecodeViewer."+version+".jar").openConnection().getInputStream();
|
||||||
|
FileOutputStream fos = new FileOutputStream(finalFile);
|
||||||
|
try {
|
||||||
|
System.out.println("Downloading from https://github.com/Konloch/bytecode-viewer/releases/download/v"+version+"/BytecodeViewer."+version+".jar");
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int len;
|
||||||
|
int downloaded = 0;
|
||||||
|
boolean flag = false;
|
||||||
|
showMessage("Downloading the jar in the background, when it's finished you will be alerted with another message box."+nl+nl+"Expect this to take several minutes.");
|
||||||
|
while ((len = is.read(buffer)) > 0) {
|
||||||
|
fos.write(buffer, 0, len);
|
||||||
|
fos.flush();
|
||||||
|
downloaded += 8192;
|
||||||
|
int mbs = downloaded / 1048576;
|
||||||
|
if(mbs % 5 == 0 && mbs != 0) {
|
||||||
|
if(!flag)
|
||||||
|
System.out.println("Downloaded " + mbs + "MBs so far");
|
||||||
|
flag = true;
|
||||||
|
} else
|
||||||
|
flag = false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (fos != null) {
|
||||||
|
fos.flush();
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Download finished!");
|
||||||
|
showMessage("Download successful! You can find the updated jar at " + finalFile.getAbsolutePath());
|
||||||
|
} catch(FileNotFoundException e) {
|
||||||
|
showMessage("Unable to download, the jar file has not been uploaded yet, please try again later in an hour.");
|
||||||
|
} catch(Exception e) {
|
||||||
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
downloadThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
@ -368,10 +476,11 @@ public class BytecodeViewer {
|
||||||
|
|
||||||
if (args.length >= 1)
|
if (args.length >= 1)
|
||||||
for (String s : args) {
|
for (String s : args) {
|
||||||
openFiles(new File[] { new File(s) });
|
openFiles(new File[] { new File(s) }, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer.setVisible(true);
|
viewer.setVisible(true);
|
||||||
|
System.out.println("Start up took " + ((System.currentTimeMillis() - start) / 1000) + " seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassNode getClassNode(String name) {
|
public static ClassNode getClassNode(String name) {
|
||||||
|
@ -398,21 +507,26 @@ public class BytecodeViewer {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openFiles(File[] files) {
|
public static void openFiles(File[] files, boolean recentFiles) {
|
||||||
|
if(recentFiles)
|
||||||
for (File f : files)
|
for (File f : files)
|
||||||
BytecodeViewer.addRecentFile(f);
|
BytecodeViewer.addRecentFile(f);
|
||||||
|
|
||||||
BytecodeViewer.viewer.setC(true);
|
|
||||||
BytecodeViewer.viewer.setIcon(true);
|
BytecodeViewer.viewer.setIcon(true);
|
||||||
boolean update = true;
|
boolean update = true;
|
||||||
|
|
||||||
for (final File f : files) {
|
for (final File f : files) {
|
||||||
final String fn = f.getName();
|
final String fn = f.getName();
|
||||||
if (fn.endsWith(".jar")) {
|
if(!f.exists()) {
|
||||||
|
update = false;
|
||||||
|
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
||||||
|
} else {
|
||||||
|
if (fn.endsWith(".jar") || fn.endsWith(".zip")) {
|
||||||
try {
|
try {
|
||||||
JarUtils.put(f, BytecodeViewer.loadedClasses);
|
JarUtils.put(f, BytecodeViewer.loadedClasses);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (fn.endsWith(".class")) {
|
} else if (fn.endsWith(".class")) {
|
||||||
|
@ -429,20 +543,38 @@ public class BytecodeViewer {
|
||||||
showMessage(fn+": Header does not start with CAFEBABE, ignoring.");
|
showMessage(fn+": Header does not start with CAFEBABE, ignoring.");
|
||||||
update = false;
|
update = false;
|
||||||
}
|
}
|
||||||
} catch (java.io.FileNotFoundException e) {
|
} catch (final Exception e) {
|
||||||
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
update = false;
|
update = false;
|
||||||
|
}
|
||||||
|
} else if(fn.endsWith(".apk")) {
|
||||||
|
Thread t = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
String name = getRandomizedName()+".jar";
|
||||||
|
File output = new File(tempDirectory + fs + name);
|
||||||
|
Dex2Jar.dex2Jar(f, output);
|
||||||
|
BytecodeViewer.viewer.setIcon(false);
|
||||||
|
openFiles(new File[]{output}, false);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
t.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeViewer.viewer.setC(false);
|
|
||||||
BytecodeViewer.viewer.setIcon(false);
|
BytecodeViewer.viewer.setIcon(false);
|
||||||
|
|
||||||
if(update)
|
if(update)
|
||||||
|
try {
|
||||||
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
|
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
|
||||||
|
} catch(java.lang.NullPointerException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startPlugin(File plugin) {
|
public static void startPlugin(File plugin) {
|
||||||
|
@ -462,7 +594,17 @@ public class BytecodeViewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static void resetWorkSpace() {
|
public static void resetWorkSpace(boolean ask) {
|
||||||
|
if(!ask) {
|
||||||
|
loadedResources.clear();
|
||||||
|
loadedClasses.clear();
|
||||||
|
MainViewerGUI.getComponent(FileNavigationPane.class)
|
||||||
|
.resetWorkspace();
|
||||||
|
MainViewerGUI.getComponent(WorkPane.class).resetWorkspace();
|
||||||
|
MainViewerGUI.getComponent(SearchingPane.class).resetWorkspace();
|
||||||
|
the.bytecode.club.bytecodeviewer.api.BytecodeViewer
|
||||||
|
.getClassNodeLoader().clear();
|
||||||
|
} else {
|
||||||
JOptionPane pane = new JOptionPane(
|
JOptionPane pane = new JOptionPane(
|
||||||
"Are you sure you want to reset the workspace?\n\rIt will also reset your file navigator and search.");
|
"Are you sure you want to reset the workspace?\n\rIt will also reset your file navigator and search.");
|
||||||
Object[] options = new String[] { "Yes", "No" };
|
Object[] options = new String[] { "Yes", "No" };
|
||||||
|
@ -487,6 +629,7 @@ public class BytecodeViewer {
|
||||||
.getClassNodeLoader().clear();
|
.getClassNodeLoader().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static ArrayList<String> killList = new ArrayList<String>();
|
private static ArrayList<String> killList = new ArrayList<String>();
|
||||||
|
|
||||||
|
@ -546,7 +689,7 @@ public class BytecodeViewer {
|
||||||
m.addActionListener(new ActionListener() {
|
m.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JMenuItem m = (JMenuItem) e.getSource();
|
JMenuItem m = (JMenuItem) e.getSource();
|
||||||
openFiles(new File[] { new File(m.getText()) });
|
openFiles(new File[] { new File(m.getText()) }, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
viewer.mnRecentFiles.add(m);
|
viewer.mnRecentFiles.add(m);
|
||||||
|
@ -569,16 +712,30 @@ public class BytecodeViewer {
|
||||||
|
|
||||||
public static void cleanup() {
|
public static void cleanup() {
|
||||||
tempF = new File(tempDirectory);
|
tempF = new File(tempDirectory);
|
||||||
while (tempF.exists()) { // delete dirs
|
|
||||||
try {
|
try {
|
||||||
FileUtils.deleteDirectory(tempF);
|
FileUtils.deleteDirectory(tempF);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (!tempF.exists()) // keep making dirs
|
||||||
|
tempF.mkdir();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!tempF.exists())
|
public static ArrayList<String> createdRandomizedNames = new ArrayList<String>();
|
||||||
// keep making dirs
|
|
||||||
tempF.mkdir();
|
public static String getRandomizedName() {
|
||||||
|
boolean generated = false;
|
||||||
|
String name = "";
|
||||||
|
while(!generated) {
|
||||||
|
String randomizedName = MiscUtils.randomString(25);
|
||||||
|
if(!createdRandomizedNames.contains(randomizedName)) {
|
||||||
|
createdRandomizedNames.add(randomizedName);
|
||||||
|
name = randomizedName;
|
||||||
|
generated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getBCVDirectory() {
|
public static String getBCVDirectory() {
|
||||||
|
|
35
src/the/bytecode/club/bytecodeviewer/Dex2Jar.java
Normal file
35
src/the/bytecode/club/bytecodeviewer/Dex2Jar.java
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple 'wrapper' for Dex2Jar.
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Dex2Jar {
|
||||||
|
|
||||||
|
public static void dex2Jar(File input, File output) {
|
||||||
|
try {
|
||||||
|
com.googlecode.dex2jar.tools.Dex2jarCmd.main(new String[]{"--force", input.getAbsolutePath()});
|
||||||
|
String realOutput = input.getName().replaceAll(".apk", "-dex2jar.jar");
|
||||||
|
File realOutputF = new File(realOutput);
|
||||||
|
realOutputF.renameTo(output);
|
||||||
|
} catch(Exception e) {
|
||||||
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveAsDex(File input, File output) {
|
||||||
|
try {
|
||||||
|
com.googlecode.dex2jar.tools.Jar2Dex.main(new String[]{"--force", input.getAbsolutePath()});
|
||||||
|
String realOutput = input.getName().replaceAll(".jar", "-jar2dex.dex");
|
||||||
|
File realOutputF = new File(realOutput);
|
||||||
|
realOutputF.renameTo(output);
|
||||||
|
} catch(Exception e) {
|
||||||
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,9 @@ import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.jar.JarEntry;
|
|
||||||
import java.util.jar.JarInputStream;
|
|
||||||
import java.util.jar.JarOutputStream;
|
import java.util.jar.JarOutputStream;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
import org.objectweb.asm.ClassReader;
|
import org.objectweb.asm.ClassReader;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
@ -28,13 +27,13 @@ import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
public class JarUtils {
|
public class JarUtils {
|
||||||
|
|
||||||
private static JarInputStream jis;
|
private static ZipInputStream jis;
|
||||||
private static JarEntry entry;
|
private static ZipEntry entry;
|
||||||
|
|
||||||
public static void put(final File jarFile,
|
public static void put(final File jarFile,
|
||||||
final HashMap<String, ClassNode> clazzList) throws IOException {
|
final HashMap<String, ClassNode> clazzList) throws IOException {
|
||||||
jis = new JarInputStream(new FileInputStream(jarFile));
|
jis = new ZipInputStream(new FileInputStream(jarFile));
|
||||||
while ((entry = jis.getNextJarEntry()) != null) {
|
while ((entry = jis.getNextEntry()) != null) {
|
||||||
try {
|
try {
|
||||||
final String name = entry.getName();
|
final String name = entry.getName();
|
||||||
if (!name.endsWith(".class")) {
|
if (!name.endsWith(".class")) {
|
||||||
|
@ -56,7 +55,7 @@ public class JarUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
} finally {
|
} finally {
|
||||||
jis.closeEntry();
|
jis.closeEntry();
|
||||||
}
|
}
|
||||||
|
|
23
src/the/bytecode/club/bytecodeviewer/MiscUtils.java
Normal file
23
src/the/bytecode/club/bytecodeviewer/MiscUtils.java
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package the.bytecode.club.bytecodeviewer;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class MiscUtils {
|
||||||
|
private static final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
private static final String AN = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
private static Random rnd = new Random();
|
||||||
|
|
||||||
|
public static String randomString(int len) {
|
||||||
|
StringBuilder sb = new StringBuilder(len);
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
sb.append(AB.charAt(rnd.nextInt(AB.length())));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String randomStringNum(int len) {
|
||||||
|
StringBuilder sb = new StringBuilder(len);
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
sb.append(AN.charAt(rnd.nextInt(AN.length())));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,44 +95,46 @@ public class Settings {
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.debugHelpers.isSelected()), false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.debugHelpers.isSelected()), false);
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "deprecated", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "deprecated", false);
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.isSelected()), false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.isSelected()), false);
|
||||||
if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
|
if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||||
|
|
||||||
if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||||
|
|
||||||
if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
|
||||||
else if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
|
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
|
||||||
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
|
||||||
|
|
||||||
|
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
}
|
}
|
||||||
|
@ -222,43 +224,45 @@ public class Settings {
|
||||||
BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 80, false)));
|
BytecodeViewer.viewer.chckbxmntmNewCheckItem_12.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 80, false)));
|
||||||
int decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 81, false));
|
int decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 81, false));
|
||||||
if(decompiler == 0)
|
if(decompiler == 0)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1None.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1None.getModel(), true);
|
||||||
else if(decompiler == 1)
|
else if(decompiler == 1)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true);
|
||||||
else if(decompiler == 2)
|
else if(decompiler == 2)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1CFR.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1CFR.getModel(), true);
|
||||||
else if(decompiler == 3)
|
else if(decompiler == 3)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true);
|
||||||
else if(decompiler == 4)
|
else if(decompiler == 4)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Bytecode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Bytecode.getModel(), true);
|
||||||
else if(decompiler == 5)
|
else if(decompiler == 5)
|
||||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true);
|
||||||
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false));
|
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false));
|
||||||
if(decompiler == 0)
|
if(decompiler == 0)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2None.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2None.getModel(), true);
|
||||||
else if(decompiler == 1)
|
else if(decompiler == 1)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true);
|
||||||
else if(decompiler == 2)
|
else if(decompiler == 2)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2CFR.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2CFR.getModel(), true);
|
||||||
else if(decompiler == 3)
|
else if(decompiler == 3)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true);
|
||||||
else if(decompiler == 4)
|
else if(decompiler == 4)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Bytecode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Bytecode.getModel(), true);
|
||||||
else if(decompiler == 5)
|
else if(decompiler == 5)
|
||||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true);
|
||||||
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false));
|
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false));
|
||||||
if(decompiler == 0)
|
if(decompiler == 0)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3None.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3None.getModel(), true);
|
||||||
else if(decompiler == 1)
|
else if(decompiler == 1)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true);
|
||||||
else if(decompiler == 2)
|
else if(decompiler == 2)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3CFR.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3CFR.getModel(), true);
|
||||||
else if(decompiler == 3)
|
else if(decompiler == 3)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true);
|
||||||
else if(decompiler == 4)
|
else if(decompiler == 4)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Bytecode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Bytecode.getModel(), true);
|
||||||
else if(decompiler == 5)
|
else if(decompiler == 5)
|
||||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true);
|
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true);
|
||||||
|
|
||||||
|
BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 84, false)));
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
//ignore because errors are expected, first start up and outdated settings.
|
//ignore because errors are expected, first start up and outdated settings.
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,11 @@ public class BytecodeViewer {
|
||||||
*
|
*
|
||||||
* @param files
|
* @param files
|
||||||
* an array of the files you want loaded.
|
* an array of the files you want loaded.
|
||||||
|
* @param recentFiles
|
||||||
|
* if it should save to the recent files menu.
|
||||||
*/
|
*/
|
||||||
public static void openFiles(File[] files) {
|
public static void openFiles(File[] files, boolean recentFiles) {
|
||||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files);
|
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files, recentFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,9 +95,12 @@ public class BytecodeViewer {
|
||||||
/**
|
/**
|
||||||
* This will ask the user if they really want to reset the workspace, then
|
* This will ask the user if they really want to reset the workspace, then
|
||||||
* it'll reset the work space.
|
* it'll reset the work space.
|
||||||
|
*
|
||||||
|
* @param ask
|
||||||
|
* if it should ask the user about resetting the workspace
|
||||||
*/
|
*/
|
||||||
public static void resetWorkSpace() {
|
public static void resetWorkSpace(boolean ask) {
|
||||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace();
|
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -183,9 +183,17 @@ public class InstructionPrinter {
|
||||||
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " "
|
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " "
|
||||||
+ min.name + "(");
|
+ min.name + "(");
|
||||||
|
|
||||||
String desc = Type.getType(min.desc).getClassName();
|
String desc = min.desc;
|
||||||
|
try {
|
||||||
|
if(Type.getType(min.desc) != null)
|
||||||
|
desc = Type.getType(min.desc).getClassName();
|
||||||
|
|
||||||
if (desc == null || desc.equals("null"))
|
if (desc == null || desc.equals("null"))
|
||||||
desc = min.desc;
|
desc = min.desc;
|
||||||
|
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sb.append(desc);
|
sb.append(desc);
|
||||||
|
|
||||||
sb.append(");");
|
sb.append(");");
|
||||||
|
@ -224,9 +232,16 @@ public class InstructionPrinter {
|
||||||
|
|
||||||
protected String printTypeInsnNode(TypeInsnNode tin) {
|
protected String printTypeInsnNode(TypeInsnNode tin) {
|
||||||
try {
|
try {
|
||||||
String desc = Type.getType(tin.desc).getClassName();
|
String desc = tin.desc;
|
||||||
|
try {
|
||||||
|
if(Type.getType(tin.desc) != null)
|
||||||
|
desc = Type.getType(tin.desc).getClassName();
|
||||||
|
|
||||||
if (desc == null || desc.equals("null"))
|
if (desc == null || desc.equals("null"))
|
||||||
desc = tin.desc;
|
desc = tin.desc;
|
||||||
|
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
|
||||||
|
|
||||||
|
}
|
||||||
return nameOpcode(tin.getOpcode()) + " " + desc;
|
return nameOpcode(tin.getOpcode()) + " " + desc;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||||
|
|
|
@ -116,14 +116,14 @@ public class MethodNodeDecompiler {
|
||||||
addAttrList(m.invisibleAnnotations, "invisAnno", sb, insnPrinter);
|
addAttrList(m.invisibleAnnotations, "invisAnno", sb, insnPrinter);
|
||||||
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb,
|
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb,
|
||||||
insnPrinter);
|
insnPrinter);
|
||||||
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
|
/*addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
|
||||||
insnPrinter);
|
insnPrinter);*/
|
||||||
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
|
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
|
||||||
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
|
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
|
||||||
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
|
/*addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
|
||||||
sb, insnPrinter);
|
sb, insnPrinter);
|
||||||
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb,
|
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb,
|
||||||
insnPrinter);
|
insnPrinter);*/
|
||||||
|
|
||||||
for (Object o : m.tryCatchBlocks) {
|
for (Object o : m.tryCatchBlocks) {
|
||||||
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
|
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
|
||||||
|
|
|
@ -455,60 +455,60 @@ public class ClassViewer extends JPanel {
|
||||||
PaneUpdaterThread t;
|
PaneUpdaterThread t;
|
||||||
|
|
||||||
public void startPaneUpdater(final JButton button) {
|
public void startPaneUpdater(final JButton button) {
|
||||||
if (BytecodeViewer.viewer.decompilerGroup1
|
if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
|
||||||
pane1 = 0;
|
pane1 = 0;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
else if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
|
||||||
pane1 = 1;
|
pane1 = 1;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
else if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
|
||||||
pane1 = 2;
|
pane1 = 2;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
else if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
|
||||||
pane1 = 3;
|
pane1 = 3;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
else if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
|
||||||
pane1 = 4;
|
pane1 = 4;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
else if (BytecodeViewer.viewer.panelGroup1
|
||||||
.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
|
||||||
pane1 = 5;
|
pane1 = 5;
|
||||||
|
|
||||||
if (BytecodeViewer.viewer.decompilerGroup2
|
if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||||
pane2 = 0;
|
pane2 = 0;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
else if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
|
||||||
pane2 = 1;
|
pane2 = 1;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
else if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
|
||||||
pane2 = 2;
|
pane2 = 2;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
else if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
|
||||||
pane2 = 3;
|
pane2 = 3;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
else if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
|
||||||
pane2 = 4;
|
pane2 = 4;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
else if (BytecodeViewer.viewer.panelGroup2
|
||||||
.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
|
||||||
pane2 = 5;
|
pane2 = 5;
|
||||||
|
|
||||||
if (BytecodeViewer.viewer.decompilerGroup3
|
if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||||
pane3 = 0;
|
pane3 = 0;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
else if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
|
||||||
pane3 = 1;
|
pane3 = 1;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
else if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
|
||||||
pane3 = 2;
|
pane3 = 2;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
else if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
|
||||||
pane3 = 3;
|
pane3 = 3;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
else if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
|
||||||
pane3 = 4;
|
pane3 = 4;
|
||||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
else if (BytecodeViewer.viewer.panelGroup3
|
||||||
.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
|
.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
|
||||||
pane3 = 5;
|
pane3 = 5;
|
||||||
|
|
||||||
|
|
|
@ -238,7 +238,7 @@ public class FileNavigationPane extends VisibleComponent implements
|
||||||
public void filesDropped(final File[] files) {
|
public void filesDropped(final File[] files) {
|
||||||
if (files.length < 1)
|
if (files.length < 1)
|
||||||
return;
|
return;
|
||||||
BytecodeViewer.openFiles(files);
|
BytecodeViewer.openFiles(files, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateTree() {
|
public void updateTree() {
|
||||||
|
|
|
@ -24,6 +24,7 @@ import javax.swing.JCheckBoxMenuItem;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Dex2Jar;
|
||||||
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
||||||
import the.bytecode.club.bytecodeviewer.JarUtils;
|
import the.bytecode.club.bytecodeviewer.JarUtils;
|
||||||
import the.bytecode.club.bytecodeviewer.decompilers.java.CFRDecompiler;
|
import the.bytecode.club.bytecodeviewer.decompilers.java.CFRDecompiler;
|
||||||
|
@ -44,6 +45,7 @@ import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.swing.JRadioButtonMenuItem;
|
import javax.swing.JRadioButtonMenuItem;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
|
||||||
public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
|
@ -248,10 +250,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
"Light Obfuscation");
|
"Light Obfuscation");
|
||||||
private final JMenuItem mntmNewMenuItem_11 = new JMenuItem("Rename Classes");
|
private final JMenuItem mntmNewMenuItem_11 = new JMenuItem("Rename Classes");
|
||||||
private final JSeparator separator_2 = new JSeparator();
|
private final JSeparator separator_2 = new JSeparator();
|
||||||
public final ButtonGroup decompilerGroup1 = new ButtonGroup();
|
public final ButtonGroup panelGroup1 = new ButtonGroup();
|
||||||
public final ButtonGroup decompilerGroup2 = new ButtonGroup();
|
public final ButtonGroup panelGroup2 = new ButtonGroup();
|
||||||
public final ButtonGroup decompilerGroup3 = new ButtonGroup();
|
public final ButtonGroup panelGroup3 = new ButtonGroup();
|
||||||
private final JMenu mnNewMenu_6 = new JMenu("View");
|
private final JMenu mnNewMenu_6 = new JMenu("View Panes");
|
||||||
private final JMenu mnNewMenu_7 = new JMenu("Pane 1");
|
private final JMenu mnNewMenu_7 = new JMenu("Pane 1");
|
||||||
private final JMenu mnNewMenu_8 = new JMenu("Pane 2");
|
private final JMenu mnNewMenu_8 = new JMenu("Pane 2");
|
||||||
private final JMenu mnNewMenu_9 = new JMenu("Pane 3");
|
private final JMenu mnNewMenu_9 = new JMenu("Pane 3");
|
||||||
|
@ -293,6 +295,11 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
"Hexcode");
|
"Hexcode");
|
||||||
private final JMenuItem mntmNewMenuItem_12 = new JMenuItem("Save Java File..");
|
private final JMenuItem mntmNewMenuItem_12 = new JMenuItem("Save Java File..");
|
||||||
public WorkPane workPane = new WorkPane(this);
|
public WorkPane workPane = new WorkPane(this);
|
||||||
|
private final JMenu mnSettings = new JMenu("Settings");
|
||||||
|
private final JSeparator separator_6 = new JSeparator();
|
||||||
|
public final JCheckBox refreshOnChange = new JCheckBox("Refresh On View Change");
|
||||||
|
|
||||||
|
final MainViewerGUI This = this;
|
||||||
|
|
||||||
public void setC(boolean busy) {
|
public void setC(boolean busy) {
|
||||||
if (busy) {
|
if (busy) {
|
||||||
|
@ -332,18 +339,17 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageIcon busy = new ImageIcon(getClass().getResource("/resources/1.gif"));
|
||||||
|
ImageIcon busyB64 = new ImageIcon(BytecodeViewer.b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"));
|
||||||
|
private final JMenuItem mntmSaveAsApk = new JMenuItem("Save As DEX..");
|
||||||
public void setIcon(final boolean busy) {
|
public void setIcon(final boolean busy) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (busy) {
|
if (busy) {
|
||||||
try {
|
try {
|
||||||
mntmNewMenuItem_4.setIcon(new ImageIcon(getClass()
|
mntmNewMenuItem_4.setIcon(This.busy);
|
||||||
.getResource("/resources/1.gif")));
|
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
mntmNewMenuItem_4.setIcon(new ImageIcon(
|
mntmNewMenuItem_4.setIcon(busyB64);
|
||||||
BytecodeViewer
|
|
||||||
.b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"),
|
|
||||||
""));
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
mntmNewMenuItem_4.setIcon(null);
|
mntmNewMenuItem_4.setIcon(null);
|
||||||
|
@ -354,92 +360,65 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
public MainViewerGUI() {
|
public MainViewerGUI() {
|
||||||
this.setIconImages(BytecodeViewer.iconList);
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
decompilerGroup1.add(panel1None);
|
panelGroup1.add(panel1None);
|
||||||
decompilerGroup1.add(panel1Fern);
|
panelGroup1.add(panel1Fern);
|
||||||
decompilerGroup1.add(panel1Proc);
|
panelGroup1.add(panel1Proc);
|
||||||
decompilerGroup1.add(panel1CFR);
|
panelGroup1.add(panel1CFR);
|
||||||
decompilerGroup1.add(panel1Bytecode);
|
panelGroup1.add(panel1Bytecode);
|
||||||
decompilerGroup1.add(panel1Hexcode);
|
panelGroup1.add(panel1Hexcode);
|
||||||
decompilerGroup1.setSelected(panel1Proc.getModel(), true);
|
panelGroup1.setSelected(panel1Proc.getModel(), true);//my one true love
|
||||||
decompilerGroup2.add(panel2None);
|
panelGroup2.add(panel2None);
|
||||||
decompilerGroup2.add(panel2Fern);
|
panelGroup2.add(panel2Fern);
|
||||||
decompilerGroup2.add(panel2Proc);
|
panelGroup2.add(panel2Proc);
|
||||||
decompilerGroup2.add(panel2CFR);
|
panelGroup2.add(panel2CFR);
|
||||||
decompilerGroup2.add(panel2Bytecode);
|
panelGroup2.add(panel2Bytecode);
|
||||||
decompilerGroup2.add(panel2Hexcode);
|
panelGroup2.add(panel2Hexcode);
|
||||||
decompilerGroup2.setSelected(panel2Bytecode.getModel(), true);
|
panelGroup2.setSelected(panel2Bytecode.getModel(), true);
|
||||||
decompilerGroup3.add(panel3None);
|
panelGroup3.add(panel3None);
|
||||||
decompilerGroup3.add(panel3Fern);
|
panelGroup3.add(panel3Fern);
|
||||||
decompilerGroup3.add(panel3Proc);
|
panelGroup3.add(panel3Proc);
|
||||||
decompilerGroup3.add(panel3CFR);
|
panelGroup3.add(panel3CFR);
|
||||||
decompilerGroup3.add(panel3Bytecode);
|
panelGroup3.add(panel3Bytecode);
|
||||||
decompilerGroup3.add(panel3Hexcode);
|
panelGroup3.add(panel3Hexcode);
|
||||||
decompilerGroup3.setSelected(panel3None.getModel(), true);
|
panelGroup3.setSelected(panel3None.getModel(), true);
|
||||||
|
|
||||||
|
ActionListener listener = new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
if(refreshOnChange.isSelected()) {
|
||||||
|
if(workPane.getCurrentClass() == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
workPane.refreshClass.doClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
panel1None.addActionListener(listener);
|
||||||
|
panel1Fern.addActionListener(listener);
|
||||||
|
panel1Proc.addActionListener(listener);
|
||||||
|
panel1CFR.addActionListener(listener);
|
||||||
|
panel1Bytecode.addActionListener(listener);
|
||||||
|
panel1Hexcode.addActionListener(listener);
|
||||||
|
panel2None.addActionListener(listener);
|
||||||
|
panel2Fern.addActionListener(listener);
|
||||||
|
panel2Proc.addActionListener(listener);
|
||||||
|
panel2CFR.addActionListener(listener);
|
||||||
|
panel2Bytecode.addActionListener(listener);
|
||||||
|
panel2Hexcode.addActionListener(listener);
|
||||||
|
panel3None.addActionListener(listener);
|
||||||
|
panel3Fern.addActionListener(listener);
|
||||||
|
panel3Proc.addActionListener(listener);
|
||||||
|
panel3CFR.addActionListener(listener);
|
||||||
|
panel3Bytecode.addActionListener(listener);
|
||||||
|
panel3Hexcode.addActionListener(listener);
|
||||||
obfuscatorGroup.add(strongObf);
|
obfuscatorGroup.add(strongObf);
|
||||||
obfuscatorGroup.add(lightObf);
|
obfuscatorGroup.add(lightObf);
|
||||||
obfuscatorGroup.setSelected(strongObf.getModel(), true);
|
obfuscatorGroup.setSelected(strongObf.getModel(), true);
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
// fernflower
|
|
||||||
rbr.setSelected(true);
|
|
||||||
rsy.setSelected(false);
|
|
||||||
din.setSelected(true);
|
|
||||||
das.setSelected(true);
|
|
||||||
dgs.setSelected(false);
|
|
||||||
den.setSelected(true);
|
|
||||||
uto.setSelected(true);
|
|
||||||
udv.setSelected(true);
|
|
||||||
fdi.setSelected(true);
|
|
||||||
asc.setSelected(false);
|
|
||||||
debugHelpers.setSelected(true);
|
|
||||||
// cfr
|
|
||||||
decodeenumswitch.setSelected(true);
|
|
||||||
sugarenums.setSelected(true);
|
|
||||||
decodestringswitch.setSelected(true);
|
|
||||||
arrayiter.setSelected(true);
|
|
||||||
collectioniter.setSelected(true);
|
|
||||||
innerclasses.setSelected(true);
|
|
||||||
removeboilerplate.setSelected(true);
|
|
||||||
removeinnerclasssynthetics.setSelected(true);
|
|
||||||
decodelambdas.setSelected(true);
|
|
||||||
hidebridgemethods.setSelected(true);
|
|
||||||
liftconstructorinit.setSelected(true);
|
|
||||||
removedeadmethods.setSelected(true);
|
|
||||||
removebadgenerics.setSelected(true);
|
|
||||||
sugarasserts.setSelected(true);
|
|
||||||
sugarboxing.setSelected(true);
|
|
||||||
showversion.setSelected(true);
|
|
||||||
decodefinally.setSelected(true);
|
|
||||||
tidymonitors.setSelected(true);
|
|
||||||
lenient.setSelected(false);
|
|
||||||
dumpclasspath.setSelected(false);
|
|
||||||
comments.setSelected(true);
|
|
||||||
forcetopsort.setSelected(true);
|
|
||||||
forcetopsortaggress.setSelected(true);
|
|
||||||
forceexceptionprune.setSelected(true);
|
|
||||||
stringbuffer.setSelected(false);
|
|
||||||
stringbuilder.setSelected(true);
|
|
||||||
silent.setSelected(true);
|
|
||||||
recover.setSelected(true);
|
|
||||||
eclipse.setSelected(true);
|
|
||||||
override.setSelected(true);
|
|
||||||
showinferrable.setSelected(true);
|
|
||||||
aexagg.setSelected(true);
|
|
||||||
forcecondpropagate.setSelected(true);
|
|
||||||
hideutf.setSelected(true);
|
|
||||||
hidelongstrings.setSelected(false);
|
|
||||||
commentmonitor.setSelected(false);
|
|
||||||
allowcorrecting.setSelected(true);
|
|
||||||
labelledblocks.setSelected(true);
|
|
||||||
j14classobj.setSelected(false);
|
|
||||||
hidelangimports.setSelected(true);
|
|
||||||
recoverytypeclash.setSelected(true);
|
|
||||||
recoverytypehints.setSelected(true);
|
|
||||||
forceturningifs.setSelected(true);
|
|
||||||
forloopaggcapture.setSelected(true);
|
|
||||||
// procyon
|
// procyon
|
||||||
/* none */
|
/* none */
|
||||||
// other
|
|
||||||
chckbxmntmAppendBrackets.setSelected(true);
|
|
||||||
chckbxmntmNewCheckItem_12.setSelected(true);
|
chckbxmntmNewCheckItem_12.setSelected(true);
|
||||||
|
|
||||||
setJMenuBar(menuBar);
|
setJMenuBar(menuBar);
|
||||||
|
@ -447,10 +426,9 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
JMenu mnNewMenu = new JMenu("File");
|
JMenu mnNewMenu = new JMenu("File");
|
||||||
menuBar.add(mnNewMenu);
|
menuBar.add(mnNewMenu);
|
||||||
|
|
||||||
final JFrame This = this;
|
|
||||||
mntmNewWorkspace.addActionListener(new ActionListener() {
|
mntmNewWorkspace.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
BytecodeViewer.resetWorkSpace();
|
BytecodeViewer.resetWorkSpace(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -458,7 +436,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
mntmLoadJar.addActionListener(new ActionListener() {
|
mntmLoadJar.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
JFileChooser fc = new JFileChooser();
|
JFileChooser fc = new JFileChooser();
|
||||||
fc.setFileFilter(new JarZipClassFileFilter());
|
fc.setFileFilter(new APKDEXJarZipClassFileFilter());
|
||||||
fc.setFileHidingEnabled(false);
|
fc.setFileHidingEnabled(false);
|
||||||
fc.setAcceptAllFileFilterUsed(false);
|
fc.setAcceptAllFileFilterUsed(false);
|
||||||
int returnVal = fc.showOpenDialog(This);
|
int returnVal = fc.showOpenDialog(This);
|
||||||
|
@ -467,7 +445,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
try {
|
try {
|
||||||
BytecodeViewer.viewer.setC(true);
|
BytecodeViewer.viewer.setC(true);
|
||||||
BytecodeViewer.openFiles(new File[] { fc
|
BytecodeViewer.openFiles(new File[] { fc
|
||||||
.getSelectedFile() });
|
.getSelectedFile() }, true);
|
||||||
BytecodeViewer.viewer.setC(false);
|
BytecodeViewer.viewer.setC(false);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
|
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
|
||||||
|
@ -515,6 +493,55 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
});
|
});
|
||||||
|
|
||||||
mnNewMenu.add(mntmNewMenuItem_3);
|
mnNewMenu.add(mntmNewMenuItem_3);
|
||||||
|
mntmSaveAsApk.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
JFileChooser fc = new JFileChooser();
|
||||||
|
fc.setFileFilter(new DexFileFilter());
|
||||||
|
fc.setFileHidingEnabled(false);
|
||||||
|
fc.setAcceptAllFileFilterUsed(false);
|
||||||
|
int returnVal = fc.showSaveDialog(MainViewerGUI.this);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
final File file = fc.getSelectedFile();
|
||||||
|
if(file.exists()) {
|
||||||
|
JOptionPane pane = new JOptionPane(
|
||||||
|
"Are you sure you wish to overwrite this existing file?");
|
||||||
|
Object[] options = new String[] { "Yes", "No" };
|
||||||
|
pane.setOptions(options);
|
||||||
|
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||||
|
"Bytecode Viewer - Overwrite File");
|
||||||
|
dialog.setVisible(true);
|
||||||
|
Object obj = pane.getValue();
|
||||||
|
int result = -1;
|
||||||
|
for (int k = 0; k < options.length; k++)
|
||||||
|
if (options[k].equals(obj))
|
||||||
|
result = k;
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
file.delete();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread t = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
BytecodeViewer.viewer.setIcon(true);
|
||||||
|
String input = BytecodeViewer.tempDirectory+BytecodeViewer.fs+BytecodeViewer.getRandomizedName()+".jar";
|
||||||
|
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), input);
|
||||||
|
String output = file.getAbsolutePath();
|
||||||
|
if (!output.endsWith(".dex"))
|
||||||
|
output = output + ".dex";
|
||||||
|
Dex2Jar.saveAsDex(new File(input), new File(output));
|
||||||
|
BytecodeViewer.viewer.setIcon(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mnNewMenu.add(mntmSaveAsApk);
|
||||||
mnNewMenu.add(mntmSave);
|
mnNewMenu.add(mntmSave);
|
||||||
mntmNewMenuItem.addActionListener(new ActionListener() {
|
mntmNewMenuItem.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
|
@ -696,7 +723,6 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
JMenuItem mntmExit = new JMenuItem("Exit");
|
JMenuItem mntmExit = new JMenuItem("Exit");
|
||||||
mntmExit.addActionListener(new ActionListener() {
|
mntmExit.addActionListener(new ActionListener() {
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
JOptionPane pane = new JOptionPane(
|
JOptionPane pane = new JOptionPane(
|
||||||
"Are you sure you want to exit?");
|
"Are you sure you want to exit?");
|
||||||
|
@ -704,7 +730,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
pane.setOptions(options);
|
pane.setOptions(options);
|
||||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||||
"Bytecode Viewer - Exit");
|
"Bytecode Viewer - Exit");
|
||||||
dialog.show();
|
dialog.setVisible(true);
|
||||||
Object obj = pane.getValue();
|
Object obj = pane.getValue();
|
||||||
int result = -1;
|
int result = -1;
|
||||||
for (int k = 0; k < options.length; k++)
|
for (int k = 0; k < options.length; k++)
|
||||||
|
@ -762,7 +788,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
mnNewMenu_9.add(panel3Hexcode);
|
mnNewMenu_9.add(panel3Hexcode);
|
||||||
|
|
||||||
menuBar.add(mnNewMenu_4);
|
menuBar.add(mnSettings);
|
||||||
|
|
||||||
|
mnSettings.add(refreshOnChange);
|
||||||
|
|
||||||
|
mnSettings.add(separator_6);
|
||||||
|
mnSettings.add(mnNewMenu_4);
|
||||||
|
|
||||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_6);
|
mnNewMenu_4.add(chckbxmntmNewCheckItem_6);
|
||||||
|
|
||||||
|
@ -791,8 +822,52 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_5);
|
mnNewMenu_4.add(chckbxmntmNewCheckItem_5);
|
||||||
|
|
||||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_1);
|
mnNewMenu_4.add(chckbxmntmNewCheckItem_1);
|
||||||
|
// cfr
|
||||||
menuBar.add(mnNewMenu_3);
|
decodeenumswitch.setSelected(true);
|
||||||
|
sugarenums.setSelected(true);
|
||||||
|
decodestringswitch.setSelected(true);
|
||||||
|
arrayiter.setSelected(true);
|
||||||
|
collectioniter.setSelected(true);
|
||||||
|
innerclasses.setSelected(true);
|
||||||
|
removeboilerplate.setSelected(true);
|
||||||
|
removeinnerclasssynthetics.setSelected(true);
|
||||||
|
decodelambdas.setSelected(true);
|
||||||
|
hidebridgemethods.setSelected(true);
|
||||||
|
liftconstructorinit.setSelected(true);
|
||||||
|
removedeadmethods.setSelected(true);
|
||||||
|
removebadgenerics.setSelected(true);
|
||||||
|
sugarasserts.setSelected(true);
|
||||||
|
sugarboxing.setSelected(true);
|
||||||
|
showversion.setSelected(true);
|
||||||
|
decodefinally.setSelected(true);
|
||||||
|
tidymonitors.setSelected(true);
|
||||||
|
lenient.setSelected(false);
|
||||||
|
dumpclasspath.setSelected(false);
|
||||||
|
comments.setSelected(true);
|
||||||
|
forcetopsort.setSelected(true);
|
||||||
|
forcetopsortaggress.setSelected(true);
|
||||||
|
forceexceptionprune.setSelected(true);
|
||||||
|
stringbuffer.setSelected(false);
|
||||||
|
stringbuilder.setSelected(true);
|
||||||
|
silent.setSelected(true);
|
||||||
|
recover.setSelected(true);
|
||||||
|
eclipse.setSelected(true);
|
||||||
|
override.setSelected(true);
|
||||||
|
showinferrable.setSelected(true);
|
||||||
|
aexagg.setSelected(true);
|
||||||
|
forcecondpropagate.setSelected(true);
|
||||||
|
hideutf.setSelected(true);
|
||||||
|
hidelongstrings.setSelected(false);
|
||||||
|
commentmonitor.setSelected(false);
|
||||||
|
allowcorrecting.setSelected(true);
|
||||||
|
labelledblocks.setSelected(true);
|
||||||
|
j14classobj.setSelected(false);
|
||||||
|
hidelangimports.setSelected(true);
|
||||||
|
recoverytypeclash.setSelected(true);
|
||||||
|
recoverytypehints.setSelected(true);
|
||||||
|
forceturningifs.setSelected(true);
|
||||||
|
forloopaggcapture.setSelected(true);
|
||||||
|
mnSettings.add(mnNewMenu_3);
|
||||||
|
|
||||||
mnNewMenu_3.add(decodeenumswitch);
|
mnNewMenu_3.add(decodeenumswitch);
|
||||||
|
|
||||||
|
@ -881,9 +956,20 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
mnNewMenu_3.add(forceturningifs);
|
mnNewMenu_3.add(forceturningifs);
|
||||||
|
|
||||||
mnNewMenu_3.add(forloopaggcapture);
|
mnNewMenu_3.add(forloopaggcapture);
|
||||||
|
// fernflower
|
||||||
|
rbr.setSelected(true);
|
||||||
|
rsy.setSelected(false);
|
||||||
|
din.setSelected(true);
|
||||||
|
das.setSelected(true);
|
||||||
|
dgs.setSelected(false);
|
||||||
|
den.setSelected(true);
|
||||||
|
uto.setSelected(true);
|
||||||
|
udv.setSelected(true);
|
||||||
|
fdi.setSelected(true);
|
||||||
|
asc.setSelected(false);
|
||||||
|
|
||||||
JMenu mnDecompilerSettings = new JMenu("FernFlower");
|
JMenu mnDecompilerSettings = new JMenu("FernFlower");
|
||||||
menuBar.add(mnDecompilerSettings);
|
mnSettings.add(mnDecompilerSettings);
|
||||||
dc4.setSelected(true);
|
dc4.setSelected(true);
|
||||||
mnDecompilerSettings.add(dc4);
|
mnDecompilerSettings.add(dc4);
|
||||||
nns.setSelected(true);
|
nns.setSelected(true);
|
||||||
|
@ -910,9 +996,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
mnDecompilerSettings.add(udv);
|
mnDecompilerSettings.add(udv);
|
||||||
mnDecompilerSettings.add(fdi);
|
mnDecompilerSettings.add(fdi);
|
||||||
mnDecompilerSettings.add(asc);
|
mnDecompilerSettings.add(asc);
|
||||||
|
debugHelpers.setSelected(true);
|
||||||
|
// other
|
||||||
|
chckbxmntmAppendBrackets.setSelected(true);
|
||||||
|
|
||||||
JMenu mnBytecodeDecompilerSettings = new JMenu("Bytecode Decompiler");
|
JMenu mnBytecodeDecompilerSettings = new JMenu("Bytecode Decompiler");
|
||||||
menuBar.add(mnBytecodeDecompilerSettings);
|
mnSettings.add(mnBytecodeDecompilerSettings);
|
||||||
|
|
||||||
mnBytecodeDecompilerSettings.add(debugHelpers);
|
mnBytecodeDecompilerSettings.add(debugHelpers);
|
||||||
|
|
||||||
|
@ -1157,7 +1246,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class JarZipClassFileFilter extends FileFilter {
|
public class APKDEXJarZipClassFileFilter extends FileFilter {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File f) {
|
public boolean accept(File f) {
|
||||||
if (f.isDirectory())
|
if (f.isDirectory())
|
||||||
|
@ -1165,15 +1254,16 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
String extension = getExtension(f);
|
String extension = getExtension(f);
|
||||||
if (extension != null)
|
if (extension != null)
|
||||||
return (extension.equals("jar") || extension.equals("zip") || extension
|
return (extension.equals("jar") || extension.equals("zip")
|
||||||
.equals("class"));
|
|| extension.equals("class") || extension.equals("apk")
|
||||||
|
|| extension.equals("dex"));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return "Class Files or Zip/Jar Archives";
|
return "APKs, DEX, Class Files or Zip/Jar Archives";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExtension(File f) {
|
public String getExtension(File f) {
|
||||||
|
@ -1256,7 +1346,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
|
|
||||||
String extension = getExtension(f);
|
String extension = getExtension(f);
|
||||||
if (extension != null)
|
if (extension != null)
|
||||||
return (extension.equals("Java"));
|
return (extension.equals("java"));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1277,4 +1367,34 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||||
return ext;
|
return ext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DexFileFilter extends FileFilter {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File f) {
|
||||||
|
if (f.isDirectory())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
String extension = getExtension(f);
|
||||||
|
if (extension != null)
|
||||||
|
return (extension.equals("dex"));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return "Android DEX Files";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtension(File f) {
|
||||||
|
String ext = null;
|
||||||
|
String s = f.getName();
|
||||||
|
int i = s.lastIndexOf('.');
|
||||||
|
|
||||||
|
if (i > 0 && i < s.length() - 1)
|
||||||
|
ext = s.substring(i + 1).toLowerCase();
|
||||||
|
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,14 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple GUI to select the Malicious Code Scanner options.
|
||||||
|
*
|
||||||
|
* @author Konloch
|
||||||
|
* @author Adrianherrera
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
public class MaliciousCodeScannerOptions extends JFrame {
|
public class MaliciousCodeScannerOptions extends JFrame {
|
||||||
public MaliciousCodeScannerOptions() {
|
public MaliciousCodeScannerOptions() {
|
||||||
this.setIconImages(BytecodeViewer.iconList);
|
this.setIconImages(BytecodeViewer.iconList);
|
||||||
|
|
|
@ -176,7 +176,7 @@ public class SearchingPane extends VisibleComponent {
|
||||||
|
|
||||||
getContentPane().setLayout(new BorderLayout());
|
getContentPane().setLayout(new BorderLayout());
|
||||||
|
|
||||||
getContentPane().add(optionPanel, BorderLayout.NORTH);
|
getContentPane().add(new JScrollPane(optionPanel), BorderLayout.NORTH);
|
||||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||||
|
|
||||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class WorkPane extends VisibleComponent implements ActionListener {
|
||||||
|
|
||||||
buttonPanel = new JPanel(new FlowLayout());
|
buttonPanel = new JPanel(new FlowLayout());
|
||||||
|
|
||||||
refreshClass = new JButton("Refresh class");
|
refreshClass = new JButton("Refresh Class");
|
||||||
refreshClass.addActionListener(this);
|
refreshClass.addActionListener(this);
|
||||||
|
|
||||||
buttonPanel.add(refreshClass);
|
buttonPanel.add(refreshClass);
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package the.bytecode.club.bytecodeviewer.obfuscators;
|
package the.bytecode.club.bytecodeviewer.obfuscators;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
||||||
|
|
||||||
public abstract class JavaObfuscator extends Thread {
|
public abstract class JavaObfuscator extends Thread {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
System.out.println("mibbzz is gay");
|
||||||
BytecodeViewer.viewer.setIcon(true);
|
BytecodeViewer.viewer.setIcon(true);
|
||||||
BytecodeViewer.runningObfuscation = true;
|
BytecodeViewer.runningObfuscation = true;
|
||||||
obfuscate();
|
obfuscate();
|
||||||
|
@ -29,29 +30,12 @@ public abstract class JavaObfuscator extends Thread {
|
||||||
public static int MAX_STRING_LENGTH = 250;
|
public static int MAX_STRING_LENGTH = 250;
|
||||||
public static int MIN_STRING_LENGTH = 20;
|
public static int MIN_STRING_LENGTH = 20;
|
||||||
private ArrayList<String> names = new ArrayList<String>();
|
private ArrayList<String> names = new ArrayList<String>();
|
||||||
private static final String AB = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
||||||
private static final String AN = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
||||||
private static Random rnd = new Random();
|
|
||||||
|
|
||||||
private static String randomString(int len) {
|
|
||||||
StringBuilder sb = new StringBuilder(len);
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
sb.append(AB.charAt(rnd.nextInt(AB.length())));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String randomStringNum(int len) {
|
|
||||||
StringBuilder sb = new StringBuilder(len);
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
sb.append(AN.charAt(rnd.nextInt(AN.length())));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String generateUniqueName(int length) {
|
protected String generateUniqueName(int length) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
String name = "";
|
String name = "";
|
||||||
while (!found) {
|
while (!found) {
|
||||||
String nameTry = randomString(1) + randomStringNum(length - 1);
|
String nameTry = MiscUtils.randomString(1) + MiscUtils.randomStringNum(length - 1);
|
||||||
if (!names.contains(nameTry)) {
|
if (!names.contains(nameTry)) {
|
||||||
names.add(nameTry);
|
names.add(nameTry);
|
||||||
name = nameTry;
|
name = nameTry;
|
||||||
|
|
|
@ -129,7 +129,6 @@ public class EZInjection extends Plugin {
|
||||||
+ "), it's been blocked.");
|
+ "), it's been blocked.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||||
BytecodeViewer.viewer.setIcon(true);
|
BytecodeViewer.viewer.setIcon(true);
|
||||||
|
|
|
@ -21,6 +21,7 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
||||||
* and added more stuff to search for.
|
* and added more stuff to search for.
|
||||||
*
|
*
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
|
* @author Adrianherrera
|
||||||
* @author WaterWolf
|
* @author WaterWolf
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue