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
Binary file not shown.
26
README.txt
26
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.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
Hex Viewer - Powered by JHexPane.
|
||||
Each Decompiler/Viewer is toggleable.
|
||||
Fully Featured Search System.
|
||||
A Plugin System With Built In Plugins. (Show All Strings, Malicious Code Scanner, String Decrypters, etc)
|
||||
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.
|
||||
Recent Files & Recent Plugins.
|
||||
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!
|
||||
|
||||
Are you a Java Reverse Engineer? Do you want to learn?
|
||||
|
@ -218,4 +218,16 @@ Changelog:
|
|||
12/20/2014 - Moved all of the settings to the.bytecode.club.bytecodeviewer.Settings
|
||||
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/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.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URI;
|
||||
|
@ -18,6 +21,7 @@ import java.util.Map.Entry;
|
|||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.UIManager;
|
||||
|
@ -62,14 +66,16 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
|
|||
* TODO:
|
||||
* 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 obfuscation
|
||||
* Add obfuscation:
|
||||
* Add integer boxing and other obfuscation methods contra implemented
|
||||
* Insert unadded/debug opcodes to try to fuck up decompilers
|
||||
* ClassAnylyzterAdapter
|
||||
* 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
|
||||
* Insert unadded/debug opcodes to try to fuck up decompilers
|
||||
* ClassAnylyzterAdapter
|
||||
* Add class annotations to bytecode decompiler.
|
||||
* 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-----:
|
||||
* 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 - Properly handled file not found error.
|
||||
* 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
|
||||
*
|
||||
|
@ -256,9 +274,11 @@ public class BytecodeViewer {
|
|||
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.4.0";
|
||||
public static String version = "2.5.0";
|
||||
private static long start = System.currentTimeMillis();
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
|
||||
iconList = new ArrayList<BufferedImage>();
|
||||
int size = 16;
|
||||
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");
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream()));
|
||||
String version = reader.readLine();
|
||||
final String version = reader.readLine();
|
||||
reader.close();
|
||||
if (!BytecodeViewer.version.equals(version)) {
|
||||
connection = (HttpURLConnection) new URL(
|
||||
|
@ -312,11 +332,13 @@ public class BytecodeViewer {
|
|||
readme.add(s);
|
||||
reader.close();
|
||||
|
||||
String changelog = "";
|
||||
String changelog = "Unable to load change log, please try again later."+nl;
|
||||
boolean trigger = false;
|
||||
for(String st : readme) {
|
||||
if(st.equals("--- "+version+" ---:"))
|
||||
if(st.equals("--- "+version+" ---:")) {
|
||||
changelog = "";
|
||||
trigger = true;
|
||||
}
|
||||
|
||||
if(trigger == true && !st.equals("--- "+version+" ---:")) {
|
||||
if(st.startsWith("--- "))
|
||||
|
@ -336,8 +358,8 @@ public class BytecodeViewer {
|
|||
+ nl
|
||||
+ changelog
|
||||
+ nl
|
||||
+ "Would you like to automatically open the download page? (https://github.com/Konloch/bytecode-viewer/releases)");
|
||||
Object[] options = new String[] { "Yes", "No" };
|
||||
+ "What would you like to do?");
|
||||
Object[] options = new String[] { "Open The Download Page", "Download The Updated Jar", "Do Nothing" };
|
||||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||
"Bytecode Viewer - Outdated Version");
|
||||
|
@ -356,6 +378,92 @@ public class BytecodeViewer {
|
|||
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) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
|
@ -368,10 +476,11 @@ public class BytecodeViewer {
|
|||
|
||||
if (args.length >= 1)
|
||||
for (String s : args) {
|
||||
openFiles(new File[] { new File(s) });
|
||||
openFiles(new File[] { new File(s) }, true);
|
||||
}
|
||||
|
||||
viewer.setVisible(true);
|
||||
System.out.println("Start up took " + ((System.currentTimeMillis() - start) / 1000) + " seconds");
|
||||
}
|
||||
|
||||
public static ClassNode getClassNode(String name) {
|
||||
|
@ -398,52 +507,75 @@ public class BytecodeViewer {
|
|||
return a;
|
||||
}
|
||||
|
||||
public static void openFiles(File[] files) {
|
||||
for (File f : files)
|
||||
BytecodeViewer.addRecentFile(f);
|
||||
public static void openFiles(File[] files, boolean recentFiles) {
|
||||
if(recentFiles)
|
||||
for (File f : files)
|
||||
BytecodeViewer.addRecentFile(f);
|
||||
|
||||
BytecodeViewer.viewer.setC(true);
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
boolean update = true;
|
||||
|
||||
for (final File f : files) {
|
||||
final String fn = f.getName();
|
||||
if (fn.endsWith(".jar")) {
|
||||
try {
|
||||
JarUtils.put(f, BytecodeViewer.loadedClasses);
|
||||
} catch (final Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
|
||||
} else if (fn.endsWith(".class")) {
|
||||
try {
|
||||
byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
|
||||
String cafebabe = String.format("%02X", bytes[0])
|
||||
+ String.format("%02X", bytes[1])
|
||||
+ String.format("%02X", bytes[2])
|
||||
+ String.format("%02X", bytes[3]);
|
||||
if(cafebabe.toLowerCase().equals("cafebabe")) {
|
||||
final ClassNode cn = JarUtils.getNode(bytes);
|
||||
BytecodeViewer.loadedClasses.put(cn.name, cn);
|
||||
} else {
|
||||
showMessage(fn+": Header does not start with CAFEBABE, ignoring.");
|
||||
if(!f.exists()) {
|
||||
update = false;
|
||||
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
||||
} else {
|
||||
if (fn.endsWith(".jar") || fn.endsWith(".zip")) {
|
||||
try {
|
||||
JarUtils.put(f, BytecodeViewer.loadedClasses);
|
||||
} catch (final Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
update = false;
|
||||
}
|
||||
} catch (java.io.FileNotFoundException e) {
|
||||
showMessage("The file " + f.getAbsolutePath() + " could not be found.");
|
||||
update = false;
|
||||
} catch (final Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
|
||||
} else if (fn.endsWith(".class")) {
|
||||
try {
|
||||
byte[] bytes = JarUtils.getBytes(new FileInputStream(f));
|
||||
String cafebabe = String.format("%02X", bytes[0])
|
||||
+ String.format("%02X", bytes[1])
|
||||
+ String.format("%02X", bytes[2])
|
||||
+ String.format("%02X", bytes[3]);
|
||||
if(cafebabe.toLowerCase().equals("cafebabe")) {
|
||||
final ClassNode cn = JarUtils.getNode(bytes);
|
||||
BytecodeViewer.loadedClasses.put(cn.name, cn);
|
||||
} else {
|
||||
showMessage(fn+": Header does not start with CAFEBABE, ignoring.");
|
||||
update = false;
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
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) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BytecodeViewer.viewer.setC(false);
|
||||
BytecodeViewer.viewer.setIcon(false);
|
||||
|
||||
if(update)
|
||||
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
|
||||
}
|
||||
try {
|
||||
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
|
||||
} catch(java.lang.NullPointerException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void startPlugin(File plugin) {
|
||||
if (!plugin.exists())
|
||||
|
@ -462,21 +594,8 @@ public class BytecodeViewer {
|
|||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void resetWorkSpace() {
|
||||
JOptionPane pane = new JOptionPane(
|
||||
"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" };
|
||||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(viewer,
|
||||
"Bytecode Viewer - Reset Workspace");
|
||||
dialog.show();
|
||||
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) {
|
||||
public static void resetWorkSpace(boolean ask) {
|
||||
if(!ask) {
|
||||
loadedResources.clear();
|
||||
loadedClasses.clear();
|
||||
MainViewerGUI.getComponent(FileNavigationPane.class)
|
||||
|
@ -485,6 +604,30 @@ public class BytecodeViewer {
|
|||
MainViewerGUI.getComponent(SearchingPane.class).resetWorkspace();
|
||||
the.bytecode.club.bytecodeviewer.api.BytecodeViewer
|
||||
.getClassNodeLoader().clear();
|
||||
} else {
|
||||
JOptionPane pane = new JOptionPane(
|
||||
"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" };
|
||||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(viewer,
|
||||
"Bytecode Viewer - Reset Workspace");
|
||||
dialog.show();
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,7 +689,7 @@ public class BytecodeViewer {
|
|||
m.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JMenuItem m = (JMenuItem) e.getSource();
|
||||
openFiles(new File[] { new File(m.getText()) });
|
||||
openFiles(new File[] { new File(m.getText()) }, true);
|
||||
}
|
||||
});
|
||||
viewer.mnRecentFiles.add(m);
|
||||
|
@ -569,17 +712,31 @@ public class BytecodeViewer {
|
|||
|
||||
public static void cleanup() {
|
||||
tempF = new File(tempDirectory);
|
||||
while (tempF.exists()) { // delete dirs
|
||||
try {
|
||||
FileUtils.deleteDirectory(tempF);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
try {
|
||||
FileUtils.deleteDirectory(tempF);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
while (!tempF.exists())
|
||||
// keep making dirs
|
||||
while (!tempF.exists()) // keep making dirs
|
||||
tempF.mkdir();
|
||||
}
|
||||
|
||||
public static ArrayList<String> createdRandomizedNames = new ArrayList<String>();
|
||||
|
||||
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() {
|
||||
File f = new File(System.getProperty("user.home") + fs
|
||||
|
|
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.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
|
@ -28,13 +27,13 @@ import org.objectweb.asm.tree.ClassNode;
|
|||
|
||||
public class JarUtils {
|
||||
|
||||
private static JarInputStream jis;
|
||||
private static JarEntry entry;
|
||||
private static ZipInputStream jis;
|
||||
private static ZipEntry entry;
|
||||
|
||||
public static void put(final File jarFile,
|
||||
final HashMap<String, ClassNode> clazzList) throws IOException {
|
||||
jis = new JarInputStream(new FileInputStream(jarFile));
|
||||
while ((entry = jis.getNextJarEntry()) != null) {
|
||||
jis = new ZipInputStream(new FileInputStream(jarFile));
|
||||
while ((entry = jis.getNextEntry()) != null) {
|
||||
try {
|
||||
final String name = entry.getName();
|
||||
if (!name.endsWith(".class")) {
|
||||
|
@ -56,7 +55,7 @@ public class JarUtils {
|
|||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
|
||||
} finally {
|
||||
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, "deprecated", 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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
if(BytecodeViewer.viewer.decompilerGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||
if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
if(BytecodeViewer.viewer.decompilerGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||
|
||||
if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false);
|
||||
} catch(Exception 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)));
|
||||
int decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 81, false));
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true);
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true);
|
||||
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)
|
||||
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));
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true);
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true);
|
||||
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)
|
||||
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));
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true);
|
||||
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)
|
||||
BytecodeViewer.viewer.decompilerGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true);
|
||||
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true);
|
||||
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)
|
||||
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) {
|
||||
//ignore because errors are expected, first start up and outdated settings.
|
||||
}
|
||||
|
|
|
@ -53,10 +53,12 @@ public class BytecodeViewer {
|
|||
* Used to load classes/jars into BCV.
|
||||
*
|
||||
* @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) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files);
|
||||
public static void openFiles(File[] files, boolean recentFiles) {
|
||||
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
|
||||
* it'll reset the work space.
|
||||
*
|
||||
* @param ask
|
||||
* if it should ask the user about resetting the workspace
|
||||
*/
|
||||
public static void resetWorkSpace() {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace();
|
||||
public static void resetWorkSpace(boolean ask) {
|
||||
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -183,9 +183,17 @@ public class InstructionPrinter {
|
|||
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " "
|
||||
+ min.name + "(");
|
||||
|
||||
String desc = Type.getType(min.desc).getClassName();
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = min.desc;
|
||||
String desc = min.desc;
|
||||
try {
|
||||
if(Type.getType(min.desc) != null)
|
||||
desc = Type.getType(min.desc).getClassName();
|
||||
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = min.desc;
|
||||
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
|
||||
|
||||
}
|
||||
|
||||
sb.append(desc);
|
||||
|
||||
sb.append(");");
|
||||
|
@ -224,9 +232,16 @@ public class InstructionPrinter {
|
|||
|
||||
protected String printTypeInsnNode(TypeInsnNode tin) {
|
||||
try {
|
||||
String desc = Type.getType(tin.desc).getClassName();
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = tin.desc;
|
||||
String desc = tin.desc;
|
||||
try {
|
||||
if(Type.getType(tin.desc) != null)
|
||||
desc = Type.getType(tin.desc).getClassName();
|
||||
|
||||
if (desc == null || desc.equals("null"))
|
||||
desc = tin.desc;
|
||||
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
|
||||
|
||||
}
|
||||
return nameOpcode(tin.getOpcode()) + " " + desc;
|
||||
} catch (Exception 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, "invisLocalVarAnno", sb,
|
||||
insnPrinter);
|
||||
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
|
||||
insnPrinter);
|
||||
/*addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb,
|
||||
insnPrinter);*/
|
||||
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
|
||||
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
|
||||
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
|
||||
/*addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno",
|
||||
sb, insnPrinter);
|
||||
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb,
|
||||
insnPrinter);
|
||||
insnPrinter);*/
|
||||
|
||||
for (Object o : m.tryCatchBlocks) {
|
||||
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
|
||||
|
|
|
@ -455,60 +455,60 @@ public class ClassViewer extends JPanel {
|
|||
PaneUpdaterThread t;
|
||||
|
||||
public void startPaneUpdater(final JButton button) {
|
||||
if (BytecodeViewer.viewer.decompilerGroup1
|
||||
if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
|
||||
pane1 = 0;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
||||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
|
||||
pane1 = 1;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
||||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
|
||||
pane1 = 2;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
||||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
|
||||
pane1 = 3;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
||||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
|
||||
pane1 = 4;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup1
|
||||
else if (BytecodeViewer.viewer.panelGroup1
|
||||
.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
|
||||
pane1 = 5;
|
||||
|
||||
if (BytecodeViewer.viewer.decompilerGroup2
|
||||
if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
|
||||
pane2 = 0;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
||||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
|
||||
pane2 = 1;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
||||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
|
||||
pane2 = 2;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
||||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
|
||||
pane2 = 3;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
||||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
|
||||
pane2 = 4;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup2
|
||||
else if (BytecodeViewer.viewer.panelGroup2
|
||||
.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
|
||||
pane2 = 5;
|
||||
|
||||
if (BytecodeViewer.viewer.decompilerGroup3
|
||||
if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
|
||||
pane3 = 0;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
||||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
|
||||
pane3 = 1;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
||||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
|
||||
pane3 = 2;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
||||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
|
||||
pane3 = 3;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
||||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
|
||||
pane3 = 4;
|
||||
else if (BytecodeViewer.viewer.decompilerGroup3
|
||||
else if (BytecodeViewer.viewer.panelGroup3
|
||||
.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
|
||||
pane3 = 5;
|
||||
|
||||
|
|
|
@ -238,7 +238,7 @@ public class FileNavigationPane extends VisibleComponent implements
|
|||
public void filesDropped(final File[] files) {
|
||||
if (files.length < 1)
|
||||
return;
|
||||
BytecodeViewer.openFiles(files);
|
||||
BytecodeViewer.openFiles(files, true);
|
||||
}
|
||||
|
||||
public void updateTree() {
|
||||
|
|
|
@ -24,6 +24,7 @@ import javax.swing.JCheckBoxMenuItem;
|
|||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.Dex2Jar;
|
||||
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
|
||||
import the.bytecode.club.bytecodeviewer.JarUtils;
|
||||
import the.bytecode.club.bytecodeviewer.decompilers.java.CFRDecompiler;
|
||||
|
@ -44,6 +45,7 @@ import java.io.File;
|
|||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JRadioButtonMenuItem;
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
||||
|
||||
|
@ -248,10 +250,10 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
"Light Obfuscation");
|
||||
private final JMenuItem mntmNewMenuItem_11 = new JMenuItem("Rename Classes");
|
||||
private final JSeparator separator_2 = new JSeparator();
|
||||
public final ButtonGroup decompilerGroup1 = new ButtonGroup();
|
||||
public final ButtonGroup decompilerGroup2 = new ButtonGroup();
|
||||
public final ButtonGroup decompilerGroup3 = new ButtonGroup();
|
||||
private final JMenu mnNewMenu_6 = new JMenu("View");
|
||||
public final ButtonGroup panelGroup1 = new ButtonGroup();
|
||||
public final ButtonGroup panelGroup2 = new ButtonGroup();
|
||||
public final ButtonGroup panelGroup3 = new ButtonGroup();
|
||||
private final JMenu mnNewMenu_6 = new JMenu("View Panes");
|
||||
private final JMenu mnNewMenu_7 = new JMenu("Pane 1");
|
||||
private final JMenu mnNewMenu_8 = new JMenu("Pane 2");
|
||||
private final JMenu mnNewMenu_9 = new JMenu("Pane 3");
|
||||
|
@ -293,6 +295,11 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
"Hexcode");
|
||||
private final JMenuItem mntmNewMenuItem_12 = new JMenuItem("Save Java File..");
|
||||
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) {
|
||||
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) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (busy) {
|
||||
try {
|
||||
mntmNewMenuItem_4.setIcon(new ImageIcon(getClass()
|
||||
.getResource("/resources/1.gif")));
|
||||
mntmNewMenuItem_4.setIcon(This.busy);
|
||||
} catch (NullPointerException e) {
|
||||
mntmNewMenuItem_4.setIcon(new ImageIcon(
|
||||
BytecodeViewer
|
||||
.b642IMG("R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gcHBwAAAC8vL4KCgmFhYbq6uiMjI0tLS4qKimVlZb6+vicnJwUFBU9PT+bm5tjY2PT09Dk5Odzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH5BAkLAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7"),
|
||||
""));
|
||||
mntmNewMenuItem_4.setIcon(busyB64);
|
||||
}
|
||||
} else
|
||||
mntmNewMenuItem_4.setIcon(null);
|
||||
|
@ -354,92 +360,65 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
public MainViewerGUI() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
decompilerGroup1.add(panel1None);
|
||||
decompilerGroup1.add(panel1Fern);
|
||||
decompilerGroup1.add(panel1Proc);
|
||||
decompilerGroup1.add(panel1CFR);
|
||||
decompilerGroup1.add(panel1Bytecode);
|
||||
decompilerGroup1.add(panel1Hexcode);
|
||||
decompilerGroup1.setSelected(panel1Proc.getModel(), true);
|
||||
decompilerGroup2.add(panel2None);
|
||||
decompilerGroup2.add(panel2Fern);
|
||||
decompilerGroup2.add(panel2Proc);
|
||||
decompilerGroup2.add(panel2CFR);
|
||||
decompilerGroup2.add(panel2Bytecode);
|
||||
decompilerGroup2.add(panel2Hexcode);
|
||||
decompilerGroup2.setSelected(panel2Bytecode.getModel(), true);
|
||||
decompilerGroup3.add(panel3None);
|
||||
decompilerGroup3.add(panel3Fern);
|
||||
decompilerGroup3.add(panel3Proc);
|
||||
decompilerGroup3.add(panel3CFR);
|
||||
decompilerGroup3.add(panel3Bytecode);
|
||||
decompilerGroup3.add(panel3Hexcode);
|
||||
decompilerGroup3.setSelected(panel3None.getModel(), true);
|
||||
panelGroup1.add(panel1None);
|
||||
panelGroup1.add(panel1Fern);
|
||||
panelGroup1.add(panel1Proc);
|
||||
panelGroup1.add(panel1CFR);
|
||||
panelGroup1.add(panel1Bytecode);
|
||||
panelGroup1.add(panel1Hexcode);
|
||||
panelGroup1.setSelected(panel1Proc.getModel(), true);//my one true love
|
||||
panelGroup2.add(panel2None);
|
||||
panelGroup2.add(panel2Fern);
|
||||
panelGroup2.add(panel2Proc);
|
||||
panelGroup2.add(panel2CFR);
|
||||
panelGroup2.add(panel2Bytecode);
|
||||
panelGroup2.add(panel2Hexcode);
|
||||
panelGroup2.setSelected(panel2Bytecode.getModel(), true);
|
||||
panelGroup3.add(panel3None);
|
||||
panelGroup3.add(panel3Fern);
|
||||
panelGroup3.add(panel3Proc);
|
||||
panelGroup3.add(panel3CFR);
|
||||
panelGroup3.add(panel3Bytecode);
|
||||
panelGroup3.add(panel3Hexcode);
|
||||
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(lightObf);
|
||||
obfuscatorGroup.setSelected(strongObf.getModel(), true);
|
||||
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
|
||||
/* none */
|
||||
// other
|
||||
chckbxmntmAppendBrackets.setSelected(true);
|
||||
chckbxmntmNewCheckItem_12.setSelected(true);
|
||||
|
||||
setJMenuBar(menuBar);
|
||||
|
@ -447,10 +426,9 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
JMenu mnNewMenu = new JMenu("File");
|
||||
menuBar.add(mnNewMenu);
|
||||
|
||||
final JFrame This = this;
|
||||
mntmNewWorkspace.addActionListener(new ActionListener() {
|
||||
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() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileFilter(new JarZipClassFileFilter());
|
||||
fc.setFileFilter(new APKDEXJarZipClassFileFilter());
|
||||
fc.setFileHidingEnabled(false);
|
||||
fc.setAcceptAllFileFilterUsed(false);
|
||||
int returnVal = fc.showOpenDialog(This);
|
||||
|
@ -467,7 +445,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
try {
|
||||
BytecodeViewer.viewer.setC(true);
|
||||
BytecodeViewer.openFiles(new File[] { fc
|
||||
.getSelectedFile() });
|
||||
.getSelectedFile() }, true);
|
||||
BytecodeViewer.viewer.setC(false);
|
||||
} catch (Exception e1) {
|
||||
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
|
||||
|
@ -515,6 +493,55 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
});
|
||||
|
||||
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);
|
||||
mntmNewMenuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
|
@ -696,7 +723,6 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
JMenuItem mntmExit = new JMenuItem("Exit");
|
||||
mntmExit.addActionListener(new ActionListener() {
|
||||
@SuppressWarnings("deprecation")
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
JOptionPane pane = new JOptionPane(
|
||||
"Are you sure you want to exit?");
|
||||
|
@ -704,7 +730,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
pane.setOptions(options);
|
||||
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
|
||||
"Bytecode Viewer - Exit");
|
||||
dialog.show();
|
||||
dialog.setVisible(true);
|
||||
Object obj = pane.getValue();
|
||||
int result = -1;
|
||||
for (int k = 0; k < options.length; k++)
|
||||
|
@ -761,38 +787,87 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mnNewMenu_9.add(panel3Bytecode);
|
||||
|
||||
mnNewMenu_9.add(panel3Hexcode);
|
||||
|
||||
menuBar.add(mnNewMenu_4);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_6);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_11);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmShowDebugLine);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_3);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_4);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_7);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmSimplifyMemberReferences);
|
||||
|
||||
mnNewMenu_4.add(mnMergeVariables);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_8);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_9);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_10);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_2);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_5);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_1);
|
||||
|
||||
menuBar.add(mnNewMenu_3);
|
||||
|
||||
menuBar.add(mnSettings);
|
||||
|
||||
mnSettings.add(refreshOnChange);
|
||||
|
||||
mnSettings.add(separator_6);
|
||||
mnSettings.add(mnNewMenu_4);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_6);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_11);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmShowDebugLine);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_3);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_4);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_7);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmSimplifyMemberReferences);
|
||||
|
||||
mnNewMenu_4.add(mnMergeVariables);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_8);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_9);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_10);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_2);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_5);
|
||||
|
||||
mnNewMenu_4.add(chckbxmntmNewCheckItem_1);
|
||||
// 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);
|
||||
mnSettings.add(mnNewMenu_3);
|
||||
|
||||
mnNewMenu_3.add(decodeenumswitch);
|
||||
|
||||
|
@ -881,9 +956,20 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mnNewMenu_3.add(forceturningifs);
|
||||
|
||||
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");
|
||||
menuBar.add(mnDecompilerSettings);
|
||||
mnSettings.add(mnDecompilerSettings);
|
||||
dc4.setSelected(true);
|
||||
mnDecompilerSettings.add(dc4);
|
||||
nns.setSelected(true);
|
||||
|
@ -910,9 +996,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
mnDecompilerSettings.add(udv);
|
||||
mnDecompilerSettings.add(fdi);
|
||||
mnDecompilerSettings.add(asc);
|
||||
debugHelpers.setSelected(true);
|
||||
// other
|
||||
chckbxmntmAppendBrackets.setSelected(true);
|
||||
|
||||
JMenu mnBytecodeDecompilerSettings = new JMenu("Bytecode Decompiler");
|
||||
menuBar.add(mnBytecodeDecompilerSettings);
|
||||
mnSettings.add(mnBytecodeDecompilerSettings);
|
||||
|
||||
mnBytecodeDecompilerSettings.add(debugHelpers);
|
||||
|
||||
|
@ -1124,7 +1213,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public class GroovyPythonRubyFileFilter extends FileFilter {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
|
@ -1157,7 +1246,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
}
|
||||
}
|
||||
|
||||
public class JarZipClassFileFilter extends FileFilter {
|
||||
public class APKDEXJarZipClassFileFilter extends FileFilter {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
if (f.isDirectory())
|
||||
|
@ -1165,15 +1254,16 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
String extension = getExtension(f);
|
||||
if (extension != null)
|
||||
return (extension.equals("jar") || extension.equals("zip") || extension
|
||||
.equals("class"));
|
||||
return (extension.equals("jar") || extension.equals("zip")
|
||||
|| extension.equals("class") || extension.equals("apk")
|
||||
|| extension.equals("dex"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Class Files or Zip/Jar Archives";
|
||||
return "APKs, DEX, Class Files or Zip/Jar Archives";
|
||||
}
|
||||
|
||||
public String getExtension(File f) {
|
||||
|
@ -1256,7 +1346,7 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
|
||||
String extension = getExtension(f);
|
||||
if (extension != null)
|
||||
return (extension.equals("Java"));
|
||||
return (extension.equals("java"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1277,4 +1367,34 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
|
|||
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.ActionEvent;
|
||||
|
||||
/**
|
||||
* A simple GUI to select the Malicious Code Scanner options.
|
||||
*
|
||||
* @author Konloch
|
||||
* @author Adrianherrera
|
||||
*
|
||||
*/
|
||||
|
||||
public class MaliciousCodeScannerOptions extends JFrame {
|
||||
public MaliciousCodeScannerOptions() {
|
||||
this.setIconImages(BytecodeViewer.iconList);
|
||||
|
@ -93,4 +101,4 @@ public class MaliciousCodeScannerOptions extends JFrame {
|
|||
}
|
||||
|
||||
private static final long serialVersionUID = -2662514582647810868L;
|
||||
}
|
||||
}
|
|
@ -176,7 +176,7 @@ public class SearchingPane extends VisibleComponent {
|
|||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
|
||||
getContentPane().add(optionPanel, BorderLayout.NORTH);
|
||||
getContentPane().add(new JScrollPane(optionPanel), BorderLayout.NORTH);
|
||||
getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
|
||||
|
||||
this.tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
|
|
|
@ -55,7 +55,7 @@ public class WorkPane extends VisibleComponent implements ActionListener {
|
|||
|
||||
buttonPanel = new JPanel(new FlowLayout());
|
||||
|
||||
refreshClass = new JButton("Refresh class");
|
||||
refreshClass = new JButton("Refresh Class");
|
||||
refreshClass.addActionListener(this);
|
||||
|
||||
buttonPanel.add(refreshClass);
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
package the.bytecode.club.bytecodeviewer.obfuscators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||
import the.bytecode.club.bytecodeviewer.MiscUtils;
|
||||
|
||||
public abstract class JavaObfuscator extends Thread {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
System.out.println("mibbzz is gay");
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
BytecodeViewer.runningObfuscation = true;
|
||||
obfuscate();
|
||||
|
@ -29,29 +30,12 @@ public abstract class JavaObfuscator extends Thread {
|
|||
public static int MAX_STRING_LENGTH = 250;
|
||||
public static int MIN_STRING_LENGTH = 20;
|
||||
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) {
|
||||
boolean found = false;
|
||||
String name = "";
|
||||
while (!found) {
|
||||
String nameTry = randomString(1) + randomStringNum(length - 1);
|
||||
String nameTry = MiscUtils.randomString(1) + MiscUtils.randomStringNum(length - 1);
|
||||
if (!names.contains(nameTry)) {
|
||||
names.add(nameTry);
|
||||
name = nameTry;
|
||||
|
|
|
@ -129,7 +129,6 @@ public class EZInjection extends Plugin {
|
|||
+ "), it's been blocked.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(ArrayList<ClassNode> classNodeList) {
|
||||
BytecodeViewer.viewer.setIcon(true);
|
||||
|
|
|
@ -21,6 +21,7 @@ import the.bytecode.club.bytecodeviewer.api.PluginConsole;
|
|||
* and added more stuff to search for.
|
||||
*
|
||||
* @author Konloch
|
||||
* @author Adrianherrera
|
||||
* @author WaterWolf
|
||||
*
|
||||
*/
|
||||
|
@ -148,4 +149,4 @@ public class MaliciousCodeScanner extends Plugin {
|
|||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user