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:
Kalen Kinloch 2015-01-06 04:54:14 -08:00
parent 8adee814cc
commit bb95011f47
29 changed files with 673 additions and 311 deletions

View file

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

Binary file not shown.

Binary file not shown.

BIN
libs/dex-ir-1.12.jar Normal file

Binary file not shown.

BIN
libs/dex-reader-1.15.jar Normal file

Binary file not shown.

BIN
libs/dex-tools-0.0.9.15.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
libs/dx.jar Normal file

Binary file not shown.

BIN
libs/jar-rename-1.6.jar Normal file

Binary file not shown.

BIN
libs/jasmin-p2.5.jar Normal file

Binary file not shown.

View file

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

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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