This commit is contained in:
Konloch 2015-11-18 20:30:59 -07:00
parent 722a7cb959
commit 5668fa4c05
92 changed files with 4656 additions and 7374 deletions

View file

@ -30,6 +30,7 @@ Contributors:
Afffsdd
Szperak
Zooty
samczsun
If I missed you, please feel free to contact me @Konloch or konloch@gmail.com
Contribution Guide Lines/Coding Conventions:

View file

@ -69,7 +69,7 @@ public class JHexEditorASCII extends JComponent implements MouseListener,
g.setColor(Color.black);
}
String s = "" + new Character((char) he.buff[n]);
String s = String.valueOf(he.buff[n]);
if ((he.buff[n] < 20) || (he.buff[n] > 126))
s = "" + (char) 16;
he.printString(g, s, (x++), y);

View file

@ -1,94 +0,0 @@
package me.konloch.kontainer.io;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
/**
* Used to load from the disk, optional caching
*
* @author Konloch
*/
public class DiskReader {
public static Random random = new Random();
public static HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
/**
* Used to load from file, allows caching
*/
public synchronized static ArrayList<String> loadArrayList(String fileName,
boolean cache) {
ArrayList<String> array = new ArrayList<String>();
if (!map.containsKey(fileName)) {
try {
File file = new File(fileName);
if (!file.exists()) // doesnt exist, return empty
return array;
BufferedReader reader = new BufferedReader(new FileReader(file));
String add;
while ((add = reader.readLine()) != null)
array.add(add);
reader.close();
if (cache)
map.put(fileName, array);
} catch (Exception e) {
e.printStackTrace();
}
} else {
array = map.get(fileName);
}
return array;
}
/**
* Used to load from file
*/
public static String loadAsString(String fileName) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Files.copy(new File(fileName).toPath(), outputStream);
return outputStream.toString("UTF-8");
}
/**
* Used to load a string via line number lineNumber = -1 means random.
*/
public static String loadString(String fileName, int lineNumber,
boolean cache) throws Exception {
ArrayList<String> array;
if (!map.containsKey(fileName)) {
array = new ArrayList<String>();
File file = new File(fileName);
BufferedReader reader = new BufferedReader(new FileReader(file));
String add;
while ((add = reader.readLine()) != null)
array.add(add);
reader.close();
if (cache)
map.put(fileName, array);
} else {
array = map.get(fileName);
}
if (lineNumber == -1) {
int size = array.size();
return array.get(random.nextInt(size));
} else
return array.get(lineNumber);
}
}

View file

@ -1,200 +0,0 @@
package me.konloch.kontainer.io;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
/**
* This method will save to disk
*
* @author Konloch
*
*/
public class DiskWriter {
/**
* Used to insert a difference string with preserving the file extension
*
* @param fileName
* The file name
* @param difference
* Normally an integer
* @return The filename with the difference inserted and the file extension
* preserved
*/
public static String insertFileName(String fileName, String difference) {
String[] babe = fileName.split("\\.");
int count = 0;
int math = babe.length;
String m = "";
for (String s2 : babe) {
m += s2;
if (math - 2 == count)
m += difference + ".";
else if (math - 1 != count)
m += ".";
count++;
}
return m;
}
/**
* Writes a new line to the file, if it doesn't exist it will automatically
* create it.
*
* @param filename
* @param fileContents
* @param debug
*/
public static synchronized void writeNewLine(String filename,
byte[] fileContents, boolean debug) {
PrintWriter writer = null;
String original = filename;
int counter = 0;
boolean saved = false;
while (!saved) {
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(
filename, true)));
writer.println(fileContents);
if (debug)
System.out.println("Saved " + filename + " to disk");
saved = true;
} catch (Exception e) {
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
filename = insertFileName(original, "" + counter);
} else
filename = original + counter;
counter++;
}
}
writer.close();
}
/**
* Writes a string to the file
*
* @param filename
* @param lineToWrite
* @param debug
*/
public static synchronized void writeNewLine(String filename,
String lineToWrite, boolean debug) {
PrintWriter writer = null;
String original = filename;
int counter = 0;
boolean saved = false;
while (!saved) {
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(
filename, true)));
writer.println(lineToWrite);
if (debug)
System.out.println("Saved " + filename + ">" + lineToWrite
+ " to disk");
saved = true;
} catch (Exception e) {
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
filename = insertFileName(original, "" + counter);
} else
filename = original + counter;
counter++;
}
}
writer.close();
}
/**
* Deletes the original file if it exists, then writes the fileContents[] to
* the file.
*
* @param filename
* @param fileContents
* @param debug
*/
public static synchronized void replaceFile(String filename,
byte[] fileContents, boolean debug) {
File f = new File(filename);
if (f.exists())
f.delete();
PrintWriter writer = null;
String original = filename;
int counter = 0;
boolean saved = false;
while (!saved) {
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(
filename, true)));
writer.println(fileContents);
if (debug)
System.out.println("Saved " + filename + " to disk");
saved = true;
} catch (Exception e) {
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename);
if (original.contains(".")) {
filename = insertFileName(original, "" + counter);
} else
filename = original + counter;
counter++;
}
}
writer.close();
}
/**
* Deletes the original file if it exists, then writes the lineToWrite to
* the file.
*
* @param filename
* @param lineToWrite
* @param debug
*/
public static synchronized void replaceFile(String filename,
String lineToWrite, boolean debug) {
File f = new File(filename);
if (f.exists())
f.delete();
PrintWriter writer = null;
String original = filename;
int counter = 0;
boolean saved = false;
while (!saved) {
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(
filename, true)));
writer.println(lineToWrite);
if (debug)
System.out.println("Saved " + filename + ">" + lineToWrite
+ " to disk");
saved = true;
} catch (Exception e) {
if (debug)
System.out.println("Failed saving, trying to save as "
+ filename + "_");
if (original.contains(".")) {
filename = insertFileName(original, "" + counter);
} else
filename = original + counter;
counter++;
}
}
writer.close();
}
}

View file

@ -1,47 +1,47 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
public class APKTool {
public static synchronized void decodeResources(File input, File output) {
try {
File dir = new File(BytecodeViewer.tempDirectory+BytecodeViewer.fs+"Decoded Resources");
FileUtils.deleteDirectory(dir);
brut.apktool.Main.main(new String[]{"-s", "-f", "-o", dir.getAbsolutePath(), "decode", input.getAbsolutePath()});
File original = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "original");
FileUtils.deleteDirectory(original);
File classes = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "classes.dex");
classes.delete();
File apktool = new File(dir.getAbsolutePath() + BytecodeViewer.fs + "apktool.yml");
apktool.delete();
File zip = new File(BytecodeViewer.tempDirectory+BytecodeViewer.fs+MiscUtils.randomString(12)+".zip");
ZipUtils.zipFolder(dir.getAbsolutePath(), zip.getAbsolutePath(), null);
if(zip.exists())
zip.renameTo(output);
FileUtils.deleteDirectory(dir);
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
public static synchronized void decodeResources(File input, File output) {
try {
Path temporaryDirectory = Files.createTempDirectory("apkresources");
Files.delete(temporaryDirectory);
brut.apktool.Main.main(new String[]{"-s", "-f", "-o", temporaryDirectory.toAbsolutePath().toString(), "decode", input.getAbsolutePath()});
File directory = temporaryDirectory.toFile();
File original = new File(directory, "original");
FileUtils.deleteDirectory(original);
File classes = new File(directory, "classes.dex");
classes.delete();
File apktool = new File(directory, "apktool.yml");
apktool.delete();
ZipUtil.pack(directory, output);
FileUtils.deleteDirectory(directory);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}

View file

@ -1,9 +1,10 @@
package the.bytecode.club.bytecodeviewer;
import org.apache.commons.io.FileUtils;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import javax.swing.*;
import javax.swing.SwingUtilities;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
@ -44,8 +45,6 @@ public class Boot {
}
public static void boot() throws Exception {
BytecodeViewer.enjarifyWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion + BytecodeViewer.fs + "enjarify-master";
BytecodeViewer.krakatauWorkingDirectory = BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion + BytecodeViewer.fs + "Krakatau-master";
File enjarifyDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "enjarify_" + BytecodeViewer.enjarifyVersion);
File krakatauDirectory = new File(BytecodeViewer.getBCVDirectory() + BytecodeViewer.fs + "krakatau_" + BytecodeViewer.krakatauVersion);
if (!enjarifyDirectory.exists() || !krakatauDirectory.exists()) {
@ -99,7 +98,7 @@ public class Boot {
Files.delete(temporaryEnjarifyZip);
InputStream inputStream = Boot.class.getResourceAsStream("/enjarify-2.zip");
Files.copy(inputStream, temporaryEnjarifyZip);
ZipUtils.unzipFilesToPath(temporaryEnjarifyZip.normalize().toString(), enjarifyDirectory.getAbsolutePath());
ZipUtil.unpack(temporaryEnjarifyZip.toFile(), enjarifyDirectory);
Files.delete(temporaryEnjarifyZip);
} catch (Exception e) {
BytecodeViewer.showMessage("ERROR: There was an issue unzipping enjarify (possibly corrupt). Restart BCV." + BytecodeViewer.nl +
@ -131,7 +130,7 @@ public class Boot {
Files.delete(temporaryKrakatauZip);
InputStream inputStream = Boot.class.getResourceAsStream("/Krakatau-8.zip");
Files.copy(inputStream, temporaryKrakatauZip);
ZipUtils.unzipFilesToPath(temporaryKrakatauZip.normalize().toString(), krakatauDirectory.getAbsolutePath());
ZipUtil.unpack(temporaryKrakatauZip.toFile(), krakatauDirectory);
Files.delete(temporaryKrakatauZip);
} catch (Exception e) {
BytecodeViewer.showMessage("ERROR: There was an issue unzipping Krakatau decompiler (possibly corrupt). Restart BCV." + BytecodeViewer.nl +
@ -160,5 +159,5 @@ public class Boot {
public String getMessage() {
return this.message;
}
}
}
}

View file

@ -1,28 +1,43 @@
package the.bytecode.club.bytecodeviewer;
import me.konloch.kontainer.io.DiskReader;
import me.konloch.kontainer.io.DiskWriter;
import me.konloch.kontainer.io.HTTPRequest;
import org.apache.commons.io.FileUtils;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.api.ClassNodeLoader;
import the.bytecode.club.bytecodeviewer.gui.*;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.gui.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.FileNavigationPane;
import the.bytecode.club.bytecodeviewer.gui.MainViewerGUI;
import the.bytecode.club.bytecodeviewer.gui.RunOptions;
import the.bytecode.club.bytecodeviewer.gui.SearchingPane;
import the.bytecode.club.bytecodeviewer.gui.SystemErrConsole;
import the.bytecode.club.bytecodeviewer.gui.WorkPane;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.Refactorer;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import javax.swing.*;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/***************************************************************************
@ -107,37 +122,31 @@ import java.util.Map;
public class BytecodeViewer {
/*per version*/
public static String version = "3.0.0";
public static boolean previewCopy = false;
public static final String version = "3.0.0";
public static final String krakatauVersion = "8";
public static final String enjarifyVersion = "2";
public static final boolean previewCopy = false;
/* Constants */
public static final String fs = System.getProperty("file.separator");
public static final String nl = System.getProperty("line.separator");
public static final File dataDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer");
public static final File filesFile = new File(dataDir, "recentfiles.bcv");
public static final File pluginsFile = new File(dataDir, "recentplugins.bcv");
public static final File settingsFile = new File(dataDir, "settings.bcv");
public static final File krakatauDirectory = new File(dataDir + fs + "krakatau_" + krakatauVersion + fs + "Krakatau-master");
public static final File enjarifyDirectory = new File(dataDir + fs + "enjarify_" + enjarifyVersion + fs + "enjarify-master");
@Deprecated
public static final File tempDir = new File(dataDir, "bcv_temp");
private static final long start = System.currentTimeMillis();
/*the rest*/
public static String[] args;
public static MainViewerGUI viewer = null;
public static ClassNodeLoader loader = new ClassNodeLoader(); //might be insecure due to assholes targeting BCV, however that's highly unlikely.
public static SecurityMan sm = new SecurityMan(); //might be insecure due to assholes targeting BCV, however that's highly unlikely.
public static String python = "";
public static String python3 = "";
public static String rt = "";
public static String library = "";
public static String javac = "";
public static String java = "";
public static ClassNodeLoader loader = new ClassNodeLoader(); // TODO MAKE SECURE BECAUSE THIS IS INSECURE
public static SecurityMan sm = new SecurityMan(); // TODO MAKE SECURE BECAUSE THIS IS INSECURE
public static ArrayList<FileContainer> files = new ArrayList<FileContainer>(); //all of BCV's loaded files/classes/etc
private static int maxRecentFiles = 25;
public static String fs = System.getProperty("file.separator");
public static String nl = System.getProperty("line.separator");
private static File BCVDir = new File(System.getProperty("user.home") + fs + ".Bytecode-Viewer");
private static String filesName = getBCVDirectory() + fs + "recentfiles.bcv";
private static String pluginsName = getBCVDirectory() + fs + "recentplugins.bcv";
public static String settingsName = getBCVDirectory() + fs + "settings.bcv";
public static String tempDirectory = getBCVDirectory() + fs + "bcv_temp" + fs;
public static String libsDirectory = getBCVDirectory() + fs + "libs" + fs;
public static String krakatauWorkingDirectory = "";
public static String krakatauVersion = "8";
public static String enjarifyWorkingDirectory = "";
public static String enjarifyVersion = "2";
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
private static List<String> recentFiles = new ArrayList<>();
private static List<String> recentPlugins = new ArrayList<>();
public static boolean runningObfuscation = false;
private static long start = System.currentTimeMillis();
public static String lastDirectory = "";
public static ArrayList<Process> createdProcesses = new ArrayList<Process>();
public static Refactorer refactorer = new Refactorer();
@ -150,30 +159,36 @@ public class BytecodeViewer {
* @param args files you want to open or CLI
*/
public static void main(String[] args) {
System.setSecurityManager(sm);
BytecodeViewer.args = args;
System.out.println("https://the.bytecode.club - Created by @Konloch - Bytecode Viewer " + version);
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
if (previewCopy && !CommandLineInput.containsCommand(args))
} catch (Exception e) {
new ExceptionUI(e);
}
try {
System.setSecurityManager(sm);
System.out.println("https://the.bytecode.club - Created by @Konloch and @samczsun - Bytecode Viewer " + version);
CommandLineInput input = new CommandLineInput(args);
if (previewCopy && !input.containsCommand())
showMessage("WARNING: This is a preview/dev copy, you WON'T be alerted when " + version + " is actually out if you use this." + nl +
"Make sure to watch the repo: https://github.com/Konloch/bytecode-viewer for " + version + "'s release");
viewer = new MainViewerGUI();
Settings.loadGUI();
int CLI = CommandLineInput.parseCommandLine(args);
if (CLI == CommandLineInput.STOP)
return;
Boot.boot();
if (CLI == CommandLineInput.OPEN_FILE)
BytecodeViewer.BOOT(false);
else {
BytecodeViewer.BOOT(true);
CommandLineInput.executeCommandLine(args);
if (!filesFile.exists() && !filesFile.createNewFile()) {
throw new RuntimeException("Could not create recent files file");
}
if (!pluginsFile.exists() && !pluginsFile.createNewFile()) {
throw new RuntimeException("Could not create recent plugins file");
}
recentFiles.addAll(FileUtils.readLines(filesFile, "UTF-8"));
recentPlugins.addAll(FileUtils.readLines(pluginsFile, "UTF-8"));
int CLI = input.parseCommandLine();
if (CLI == CommandLineInput.STOP) return;
if (CLI == CommandLineInput.OPEN_FILE) {
viewer = new MainViewerGUI();
Settings.loadGUI();
Boot.boot();
BytecodeViewer.BOOT(args, false);
} else {
BytecodeViewer.BOOT(args, true);
input.executeCommandLine();
}
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
@ -183,7 +198,7 @@ public class BytecodeViewer {
/**
* The version checker thread
*/
private static Thread versionChecker = new Thread() {
private static final Thread versionChecker = new Thread() {
@Override
public void run() {
try {
@ -192,8 +207,7 @@ public class BytecodeViewer {
try {
int simplemaths = Integer.parseInt(version.replace(".", ""));
int simplemaths2 = Integer.parseInt(BytecodeViewer.version.replace(".", ""));
if (simplemaths2 > simplemaths)
return; //developer version
if (simplemaths2 > simplemaths) return; //developer version
} catch (Exception e) {
}
@ -210,35 +224,21 @@ public class BytecodeViewer {
changelog = "";
trigger = true;
} else if (trigger) {
if (st.startsWith("--- "))
finalTrigger = true;
if (st.startsWith("--- ")) finalTrigger = true;
if (finalTrigger)
changelog += st + nl;
if (finalTrigger) changelog += st + nl;
}
}
JOptionPane pane = new JOptionPane("Your version: "
+ BytecodeViewer.version
+ ", latest version: "
+ version
+ nl
+ nl
+ "Changes since your version:"
+ nl
+ changelog
+ nl
+ "What would you like to do?");
JOptionPane pane = new JOptionPane("Your version: " + BytecodeViewer.version + ", latest version: " + version + nl + nl + "Changes since your version:" + nl + changelog + nl + "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");
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Outdated Version");
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 (options[k].equals(obj)) result = k;
if (result == 0) {
if (Desktop.isDesktopSupported()) {
@ -277,17 +277,14 @@ public class BytecodeViewer {
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 = 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 (options[k].equals(obj)) result = k;
if (result != 0)
return;
if (result != 0) return;
file.delete();
}
@ -312,11 +309,9 @@ public class BytecodeViewer {
downloaded += 8192;
int mbs = downloaded / 1048576;
if (mbs % 5 == 0 && mbs != 0) {
if (!flag)
System.out.println("Downloaded " + mbs + "MBs so far");
if (!flag) System.out.println("Downloaded " + mbs + "MBs so far");
flag = true;
} else
flag = false;
} else flag = false;
}
} finally {
try {
@ -353,7 +348,7 @@ public class BytecodeViewer {
/**
* Pings back to bytecodeviewer.com to be added into the total running statistics
*/
private static Thread PingBack = new Thread() {
private static final Thread PingBack = new Thread() {
@Override
public void run() {
try {
@ -365,59 +360,43 @@ public class BytecodeViewer {
};
public static void pingback() {
JOptionPane pane = new JOptionPane(
"Would you like to 'pingback' to https://bytecodeviewer.com to be counted in the global users for BCV?");
JOptionPane pane = new JOptionPane("Would you like to 'pingback' to https://bytecodeviewer.com to be counted in the global users for BCV?");
Object[] options = new String[]{"Yes", "No"};
pane.setOptions(options);
JDialog dialog = pane.createDialog(BytecodeViewer.viewer,
"Bytecode Viewer - Optional Pingback");
JDialog dialog = pane.createDialog(BytecodeViewer.viewer, "Bytecode Viewer - Optional Pingback");
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 (options[k].equals(obj)) result = k;
if (result == 0) {
try {
if (!PingBack.isAlive())
PingBack.start();
if (!PingBack.isAlive()) PingBack.start();
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}
/**
* Grab the byte array from the loaded Class object
*
* @param clazz
* @return
* @throws IOException
*/
public static byte[] getClassFile(Class<?> clazz) throws IOException {
InputStream is = clazz.getResourceAsStream("/" + clazz.getName().replace('.', '/') + ".class");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int r = 0;
byte[] buffer = new byte[8192];
while ((r = is.read(buffer)) >= 0) {
baos.write(buffer, 0, r);
}
return baos.toByteArray();
}
/**
* Boot after all of the libraries have been loaded
*
* @param cli is it running CLI mode or not
*/
public static void BOOT(boolean cli) {
public static void BOOT(String[] args, boolean cli) {
cleanup();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
for (Process proc : createdProcesses)
proc.destroy();
try {
FileUtils.writeLines(filesFile, recentFiles);
FileUtils.writeLines(pluginsFile, recentPlugins);
} catch (IOException e) {
new ExceptionUI(e);
}
Settings.saveGUI();
cleanup();
}
@ -431,19 +410,15 @@ public class BytecodeViewer {
pingback = true;
}
if (viewer.chckbxmntmNewCheckItem_12.isSelected())
versionChecker.start();
if (viewer.chckbxmntmNewCheckItem_12.isSelected()) versionChecker.start();
if (!cli)
viewer.setVisible(true);
if (!cli) viewer.setVisible(true);
System.out.println("Start up took " + ((System.currentTimeMillis() - start) / 1000) + " seconds");
if (!cli)
if (args.length >= 1)
for (String s : args) {
openFiles(new File[]{new File(s)}, true);
}
if (!cli) if (args.length >= 1) for (String s : args) {
openFiles(new File[]{new File(s)}, true);
}
}
/**
@ -455,32 +430,6 @@ public class BytecodeViewer {
}
/**
* Returns the java command it can use to launch the decompilers
*
* @return
*/
public static synchronized String getJavaCommand() {
try {
sm.stopBlocking();
ProcessBuilder pb = new ProcessBuilder("java", "-version");
Process p = pb.start();
sm.setBlocking();
if (p != null)
return "java"; //java is set
} catch (Exception e) { //ignore
sm.setBlocking();
boolean empty = java.isEmpty();
while (empty) {
showMessage("You need to set your Java path, this requires the JRE to be downloaded." + BytecodeViewer.nl +
"(C:/programfiles/Java/JRE_xx/bin/java.exe)");
viewer.java();
empty = java.isEmpty();
}
}
return java;
}
/**
* Returns the currently opened ClassNode
*
@ -498,11 +447,19 @@ public class BytecodeViewer {
*/
public static ClassNode getClassNode(String name) {
for (FileContainer container : files) {
if (container.getClassNode(name) != null) {
if (container.getData().containsKey(name + ".class")) {
return container.getClassNode(name);
}
}
return null;
}
public static byte[] getClassBytes(String name) {
for (FileContainer container : files) {
if (container.getData().containsKey(name)) {
return container.getData().get(name);
}
}
return null;
}
@ -515,8 +472,7 @@ public class BytecodeViewer {
public static byte[] getFileContents(String name) {
for (FileContainer container : files) {
HashMap<String, byte[]> files = container.files;
if (files.containsKey(name))
return files.get(name);
if (files.containsKey(name)) return files.get(name);
}
return null;
@ -530,8 +486,7 @@ public class BytecodeViewer {
*/
public static void updateNode(ClassNode oldNode, ClassNode newNode) {
for (FileContainer container : files) {
if (container.remove(oldNode))
container.add(newNode);
if (container.remove(oldNode)) container.add(newNode);
}
}
@ -545,8 +500,21 @@ public class BytecodeViewer {
for (FileContainer container : files)
for (ClassNode c : container.values())
if (!a.contains(c))
a.add(c);
if (!a.contains(c)) a.add(c);
return a;
}
public static ArrayList<ClassNode> loadAllClasses() {
ArrayList<ClassNode> a = new ArrayList<ClassNode>();
for (FileContainer container : files) {
for (String s : container.files.keySet()) {
ClassNode loaded = container.getClassNode(s.substring(0, s.length() - 6));
if (loaded != null) {
a.add(loaded);
}
}
}
return a;
}
@ -572,9 +540,13 @@ public class BytecodeViewer {
for (java.awt.Component c : BytecodeViewer.viewer.workPane.getLoadedViewers()) {
if (c instanceof ClassViewer) {
ClassViewer cv = (ClassViewer) c;
if (cv.smali1 != null && cv.smali1.isEditable() ||
cv.smali2 != null && cv.smali2.isEditable() ||
cv.smali3 != null && cv.smali3.isEditable()) {
boolean valid = false;
for (int i = 0; i < cv.panels.size(); i++) {
if (cv.smalis.get(i) != null && cv.smalis.get(i).isEditable()) {
valid = true;
}
}
if (valid) {
actuallyTried = true;
Object smali[] = cv.getSmali();
if (smali != null) {
@ -591,11 +563,13 @@ public class BytecodeViewer {
}
}
}
if (cv.krakatau1 != null && cv.krakatau1.isEditable() ||
cv.krakatau2 != null && cv.krakatau2.isEditable() ||
cv.krakatau3 != null && cv.krakatau3.isEditable()) {
valid = false;
for (int i = 0; i < cv.panels.size(); i++) {
if (cv.krakataus.get(i) != null && cv.krakataus.get(i).isEditable()) {
valid = true;
}
}
if (valid) {
actuallyTried = true;
Object krakatau[] = cv.getKrakatau();
if (krakatau != null) {
@ -612,10 +586,13 @@ public class BytecodeViewer {
}
}
}
if (cv.java1 != null && cv.java1.isEditable() ||
cv.java2 != null && cv.java2.isEditable() ||
cv.java3 != null && cv.java3.isEditable()) {
valid = false;
for (int i = 0; i < cv.panels.size(); i++) {
if (cv.javas.get(i) != null && cv.javas.get(i).isEditable()) {
valid = true;
}
}
if (valid) {
actuallyTried = true;
Object java[] = cv.getJava();
if (java != null) {
@ -642,11 +619,8 @@ public class BytecodeViewer {
}
}
if (message)
if (actuallyTried)
BytecodeViewer.showMessage("Compiled Successfully.");
else
BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again.");
if (message) if (actuallyTried) BytecodeViewer.showMessage("Compiled Successfully.");
else BytecodeViewer.showMessage("You have no editable panes opened, make one editable and try again.");
BytecodeViewer.viewer.setIcon(false);
return true;
@ -661,10 +635,8 @@ public class BytecodeViewer {
* @param recentFiles if it should append to the recent files menu
*/
public static void openFiles(final File[] files, boolean recentFiles) {
if (recentFiles)
for (File f : files)
if (f.exists())
BytecodeViewer.addRecentFile(f);
if (recentFiles) for (File f : files)
if (f.exists()) BytecodeViewer.addRecentFile(f);
BytecodeViewer.viewer.setIcon(true);
update = true;
@ -691,12 +663,11 @@ public class BytecodeViewer {
boolean added = false;
for (int i = 0; i < totalFiles.size(); i++) {
File child = totalFiles.get(i);
if (child.listFiles() != null)
for (File rocket : child.listFiles())
if (!totalFiles.contains(rocket)) {
totalFiles.add(rocket);
added = true;
}
if (child.listFiles() != null) for (File rocket : child.listFiles())
if (!totalFiles.contains(rocket)) {
totalFiles.add(rocket);
added = true;
}
}
if (!added) {
@ -746,7 +717,7 @@ public class BytecodeViewer {
FileContainer container = new FileContainer(f);
if (viewer.decodeAPKResources.isSelected()) {
File decodedResources = new File(tempDirectory + fs + MiscUtils.randomString(32) + ".apk");
File decodedResources = new File(tempDir, MiscUtils.randomString(32) + ".apk");
APKTool.decodeResources(f, decodedResources);
container.files = JarUtils.loadResources(decodedResources);
}
@ -754,7 +725,7 @@ public class BytecodeViewer {
container.files.putAll(JarUtils.loadResources(f));
String name = getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
File output = new File(tempDir, name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(f, output);
@ -777,7 +748,7 @@ public class BytecodeViewer {
FileContainer container = new FileContainer(f);
String name = getRandomizedName() + ".jar";
File output = new File(tempDirectory + fs + name);
File output = new File(tempDir, name);
if (BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
Dex2Jar.dex2Jar(f, output);
@ -811,11 +782,10 @@ public class BytecodeViewer {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.viewer.setIcon(false);
if (update)
try {
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
} catch (java.lang.NullPointerException e) {
}
if (update) try {
MainViewerGUI.getComponent(FileNavigationPane.class).updateTree();
} catch (java.lang.NullPointerException e) {
}
}
}
};
@ -828,8 +798,7 @@ public class BytecodeViewer {
* @param file the file of the plugin
*/
public static void startPlugin(File file) {
if (!file.exists())
return;
if (!file.exists()) return;
try {
PluginManager.runPlugin(file);
@ -861,18 +830,15 @@ 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.");
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");
JDialog dialog = pane.createDialog(viewer, "Bytecode Viewer - Reset Workspace");
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 (options[k].equals(obj)) result = k;
if (result == 0) {
files.clear();
@ -894,8 +860,7 @@ public class BytecodeViewer {
public static void addRecentFile(File f) {
for (int i = 0; i < recentFiles.size(); i++) { // remove dead strings
String s = recentFiles.get(i);
if (s.isEmpty() || i > maxRecentFiles)
killList.add(s);
if (s.isEmpty() || i > maxRecentFiles) killList.add(s);
}
if (!killList.isEmpty()) {
for (String s : killList)
@ -905,11 +870,9 @@ public class BytecodeViewer {
if (recentFiles.contains(f.getAbsolutePath())) // already added on the list
recentFiles.remove(f.getAbsolutePath());
if (recentFiles.size() >= maxRecentFiles)
recentFiles.remove(maxRecentFiles - 1); // zero indexing
if (recentFiles.size() >= maxRecentFiles) recentFiles.remove(maxRecentFiles - 1); // zero indexing
recentFiles.add(0, f.getAbsolutePath());
DiskWriter.replaceFile(filesName, quickConvert(recentFiles), false);
resetRecentFilesMenu();
}
@ -923,8 +886,7 @@ public class BytecodeViewer {
public static void addRecentPlugin(File f) {
for (int i = 0; i < recentPlugins.size(); i++) { // remove dead strings
String s = recentPlugins.get(i);
if (s.isEmpty() || i > maxRecentFiles)
killList2.add(s);
if (s.isEmpty() || i > maxRecentFiles) killList2.add(s);
}
if (!killList2.isEmpty()) {
for (String s : killList2)
@ -934,11 +896,9 @@ public class BytecodeViewer {
if (recentPlugins.contains(f.getAbsolutePath())) // already added on the list
recentPlugins.remove(f.getAbsolutePath());
if (recentPlugins.size() >= maxRecentFiles)
recentPlugins.remove(maxRecentFiles - 1); // zero indexing
if (recentPlugins.size() >= maxRecentFiles) recentPlugins.remove(maxRecentFiles - 1); // zero indexing
recentPlugins.add(0, f.getAbsolutePath());
DiskWriter.replaceFile(pluginsName, quickConvert(recentPlugins), false);
resetRecentFilesMenu();
}
@ -974,21 +934,14 @@ public class BytecodeViewer {
}
}
private static File tempF = null;
/**
* Clears the temp directory
*/
public static void cleanup() {
tempF = new File(tempDirectory);
try {
FileUtils.deleteDirectory(tempF);
FileUtils.cleanDirectory(tempDir);
} catch (Exception e) {
}
while (!tempF.exists()) // keep making dirs
tempF.mkdir();
}
public static ArrayList<String> createdRandomizedNames = new ArrayList<String>();
@ -1018,13 +971,11 @@ public class BytecodeViewer {
* @return the static BCV directory
*/
public static String getBCVDirectory() {
while (!BCVDir.exists())
BCVDir.mkdirs();
while (!dataDir.exists()) dataDir.mkdirs();
if (!BCVDir.isHidden() && isWindows())
hideFile(BCVDir);
if (!dataDir.isHidden() && isWindows()) hideFile(dataDir);
return BCVDir.getAbsolutePath();
return dataDir.getAbsolutePath();
}
/**
@ -1052,19 +1003,6 @@ public class BytecodeViewer {
sm.setBlocking();
}
/**
* Converts an array list to a string
*
* @param a array
* @return string with newline per array object
*/
private static String quickConvert(ArrayList<String> a) {
String s = "";
for (String r : a)
s += r + nl;
return s;
}
private static long last = System.currentTimeMillis();
/**
@ -1073,8 +1011,7 @@ public class BytecodeViewer {
* @param e
*/
public static void checkHotKey(KeyEvent e) {
if (System.currentTimeMillis() - last <= (4000))
return;
if (System.currentTimeMillis() - last <= (4000)) return;
if ((e.getKeyCode() == KeyEvent.VK_O) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
last = System.currentTimeMillis();
@ -1087,14 +1024,11 @@ public class BytecodeViewer {
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
if (f.isDirectory())
return true;
if (f.isDirectory()) return true;
String extension = MiscUtils.extension(f.getAbsolutePath());
if (extension != null)
if (extension.equals("jar") || extension.equals("zip")
|| extension.equals("class") || extension.equals("apk")
|| extension.equals("dex"))
if (extension.equals("jar") || extension.equals("zip") || extension.equals("class") || extension.equals("apk") || extension.equals("dex"))
return true;
return false;
@ -1147,8 +1081,7 @@ public class BytecodeViewer {
Thread t = new Thread() {
public void run() {
if (viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false))
return;
if (viewer.autoCompileSmali.isSelected() && !BytecodeViewer.compile(false)) return;
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new FileFilter() {
@Override
@ -1166,22 +1099,18 @@ public class BytecodeViewer {
int returnVal = fc.showSaveDialog(viewer);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
if (!file.getAbsolutePath().endsWith(".zip"))
file = new File(file.getAbsolutePath() + ".zip");
if (!file.getAbsolutePath().endsWith(".zip")) file = new File(file.getAbsolutePath() + ".zip");
if (file.exists()) {
JOptionPane pane = new JOptionPane(
"Are you sure you wish to overwrite this existing file?");
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");
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 (options[k].equals(obj)) result = k;
if (result == 0) {
file.delete();
@ -1196,8 +1125,7 @@ public class BytecodeViewer {
Thread t = new Thread() {
@Override
public void run() {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
file2.getAbsolutePath());
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), file2.getAbsolutePath());
BytecodeViewer.viewer.setIcon(false);
}
};

View file

@ -1,9 +1,14 @@
package the.bytecode.club.bytecodeviewer;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.cli.*;
import org.objectweb.asm.ClassWriter;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import java.io.File;
@ -27,16 +32,12 @@ import java.io.File;
***************************************************************************/
/**
*
* Used to allow BCV to be integrated as CLI instead of GUI.
*
* @author Konloch
*
*/
public class CommandLineInput {
private static final Options options = new Options();
private static final CommandLineParser parser = new DefaultParser();
@ -45,6 +46,12 @@ public class CommandLineInput {
public static int OPEN_FILE = 0;
public static int CLI = 1;
private CommandLine parsed;
public CommandLineInput(String[] args) throws ParseException {
parsed = parser.parse(options, args);
}
static {
options.addOption(new Option("help", null, false, "prints the help menu."));
options.addOption(new Option("list", null, false, "lists all the available decompilers for BCV " + BytecodeViewer.version + "."));
@ -55,36 +62,25 @@ public class CommandLineInput {
options.addOption(new Option("nowait", null, true, "won't wait the 5 seconds to allow the user to read the CLI."));
}
public static boolean containsCommand(String[] args) {
if (args == null || args.length == 0)
return false;
try {
CommandLine cmd = parser.parse(options, args);
if (
cmd.hasOption("help") ||
cmd.hasOption("list") ||
cmd.hasOption("decompiler") ||
cmd.hasOption("i") ||
cmd.hasOption("o") ||
cmd.hasOption("t") ||
cmd.hasOption("nowait")
) {
return true;
}
} catch (Exception e) {
e.printStackTrace();
public boolean containsCommand() {
if (parsed.hasOption("help") ||
parsed.hasOption("list") ||
parsed.hasOption("decompiler") ||
parsed.hasOption("i") ||
parsed.hasOption("o") ||
parsed.hasOption("t") ||
parsed.hasOption("nowait")) {
return true;
}
return false;
}
public static int parseCommandLine(String[] args) {
if (!containsCommand(args))
public int parseCommandLine() {
if (!containsCommand()) {
return OPEN_FILE;
}
try {
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("list")) {
if (parsed.hasOption("list")) {
System.out.println("Procyon");
System.out.println("CFR");
System.out.println("FernFlower");
@ -93,35 +89,27 @@ public class CommandLineInput {
System.out.println("JD-GUI");
System.out.println("Smali");
return STOP;
} else if (cmd.hasOption("help")) {
for (String s : new String[]{
"-help Displays the help menu",
"-list Displays the available decompilers",
"-decompiler <decompiler> Selects the decompiler, procyon by default",
"-i <input file> Selects the input file",
"-o <output file> Selects the output file",
"-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip",
"-nowait Doesn't wait for the user to read the CLI messages"
})
} else if (parsed.hasOption("help")) {
for (String s : new String[]{"-help Displays the help menu", "-list Displays the available decompilers", "-decompiler <decompiler> Selects the decompiler, procyon by default", "-i <input file> Selects the input file", "-o <output file> Selects the output file", "-t <target classname> Must either be the fully qualified classname or \"all\" to decompile all as zip", "-nowait Doesn't wait for the user to read the CLI messages"})
System.out.println(s);
return STOP;
} else {
if (cmd.getOptionValue("i") == null) {
if (parsed.getOptionValue("i") == null) {
System.err.println("Set the input with -i");
return STOP;
}
if (cmd.getOptionValue("o") == null) {
if (parsed.getOptionValue("o") == null) {
System.err.println("Set the output with -o");
return STOP;
}
if (cmd.getOptionValue("t") == null) {
if (parsed.getOptionValue("t") == null) {
System.err.println("Set the target with -t");
return STOP;
}
File input = new File(cmd.getOptionValue("i"));
File output = new File(cmd.getOptionValue("o"));
String decompiler = cmd.getOptionValue("decompiler");
File input = new File(parsed.getOptionValue("i"));
File output = new File(parsed.getOptionValue("o"));
String decompiler = parsed.getOptionValue("decompiler");
if (!input.exists()) {
System.err.println(input.getAbsolutePath() + " does not exist.");
@ -137,201 +125,64 @@ public class CommandLineInput {
//if its zip/jar/apk/dex attempt unzip as whole zip
//if its just class allow any
if (
decompiler != null &&
!decompiler.equalsIgnoreCase("procyon") &&
!decompiler.equalsIgnoreCase("cfr") &&
!decompiler.equalsIgnoreCase("fernflower") &&
!decompiler.equalsIgnoreCase("krakatau") &&
!decompiler.equalsIgnoreCase("krakatau-bytecode") &&
!decompiler.equalsIgnoreCase("jd-gui") &&
!decompiler.equalsIgnoreCase("smali")
) {
if (decompiler != null &&
!decompiler.equalsIgnoreCase("procyon") &&
!decompiler.equalsIgnoreCase("cfr") &&
!decompiler.equalsIgnoreCase("fernflower") &&
!decompiler.equalsIgnoreCase("krakatau") &&
!decompiler.equalsIgnoreCase("krakatau-bytecode") &&
!decompiler.equalsIgnoreCase("jd-gui") &&
!decompiler.equalsIgnoreCase("smali")) {
System.out.println("Error, no decompiler called '" + decompiler + "' found. Type -decompiler-list for the list");
}
if (!cmd.hasOption("nowait"))
Thread.sleep(5 * 1000);
if (!parsed.hasOption("nowait")) Thread.sleep(5 * 1000);
return CLI;
}
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
new ExceptionUI(e);
}
return OPEN_FILE;
}
public static void executeCommandLine(String[] args) {
public void executeCommandLine() {
try {
CommandLine cmd = parser.parse(options, args);
String decompiler = cmd.getOptionValue("decompiler");
File input = new File(cmd.getOptionValue("i"));
File output = new File(cmd.getOptionValue("o"));
String target = cmd.getOptionValue("t");
File input = new File(parsed.getOptionValue("i"));
File output = new File(parsed.getOptionValue("o"));
String target = parsed.getOptionValue("t");
if (cmd.getOptionValue("decompiler") == null) {
Decompiler use = null;
if (parsed.getOptionValue("decompiler") == null) {
System.out.println("You can define another decompiler by appending -decompiler \"name\", by default procyon has been set.");
decompiler = "procyon";
use = Decompiler.PROCYON;
} else if ((use = Decompiler.getByName(parsed.getOptionValue("decompiler"))) == null) {
System.out.println("Decompiler not found. By default Procyon has been set.");
use = Decompiler.PROCYON;
}
//check if zip, jar, apk, dex, or class
//if its zip/jar/apk/dex attempt unzip as whole zip
//if its just class allow any
if (decompiler.equalsIgnoreCase("procyon")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with Procyon");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
Decompiler.procyon.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.procyon.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("cfr")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with CFR");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
Decompiler.cfr.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.cfr.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("fernflower")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with FernFlower");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
Decompiler.fernflower.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.fernflower.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("krakatau")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with Krakatau");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
Decompiler.krakatau.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.krakatau.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("krakatau-bytecode")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with Krakatau-Bytecode");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
System.out.println("Coming soon.");
//Decompiler.krakatauDA.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.krakatauDA.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("jd-gui")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with JD-GUI");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
System.out.println("Coming soon.");
//Decompiler.jdgui.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.jdgui.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
} else if (decompiler.equalsIgnoreCase("smali")) {
System.out.println("Decompiling " + input.getAbsolutePath() + " with Smali");
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
System.out.println("Coming soon.");
//Decompiler.smali.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
final ClassWriter cw = accept(cn);
String contents = Decompiler.smali.decompileClassNode(cn, cw.toByteArray());
DiskWriter.replaceFile(output.getAbsolutePath(), contents, false);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
System.out.println("Decompiling " + input.getAbsolutePath() + " with " + use.getName());
BytecodeViewer.openFiles(new File[]{input}, false);
Thread.sleep(5 * 1000);
if (target.equalsIgnoreCase("all")) {
use.decompileToZip(output.getAbsolutePath());
} else {
try {
ClassNode cn = BytecodeViewer.getClassNode(target);
byte[] bytes = BytecodeViewer.getClassBytes(target);
String contents = use.decompileClassNode(cn, bytes);
FileUtils.write(output, contents, "UTF-8", false);
} catch (Exception e) {
new ExceptionUI(e);
}
}
System.out.println("Finished.");
System.out.println("Bytecode Viewer CLI v" + BytecodeViewer.version + " by @Konloch - http://bytecodeviewer.com");
System.exit(0);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
new ExceptionUI(e);
}
}
public static ClassWriter accept(ClassNode cn) {
ClassWriter cw = new ClassWriter(0);
try {
cn.accept(cw);
} catch (Exception e) {
e.printStackTrace();
try {
Thread.sleep(200);
cn.accept(cw);
} catch (InterruptedException e1) {
}
}
return cw;
}
}

View file

@ -0,0 +1,80 @@
package the.bytecode.club.bytecodeviewer;
import com.eclipsesource.json.JsonObject;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import javax.swing.JCheckBoxMenuItem;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DecompilerSettings {
private Decompiler decompiler;
public DecompilerSettings(Decompiler decompiler) {
this.decompiler = decompiler;
}
private Map<Setting, JCheckBoxMenuItem> menuItems = new HashMap<>();
private List<Setting> registrationOrder = new ArrayList<>();
public void registerSetting(Setting setting) {
if (!menuItems.containsKey(setting)) {
registrationOrder.add(setting);
JCheckBoxMenuItem item = new JCheckBoxMenuItem(setting.getText());
if (setting.isDefaultOn()) {
item.setSelected(true);
}
menuItems.put(setting, item);
}
}
public boolean isSelected(Setting setting) {
return menuItems.get(setting).isSelected();
}
public JCheckBoxMenuItem getMenuItem(Setting setting) {
return menuItems.get(setting);
}
public int size() {
return registrationOrder.size();
}
public void loadFrom(JsonObject rootSettings) {
if (rootSettings.get("decompilers") != null) {
JsonObject decompilerSection = rootSettings.get("decompilers").asObject();
if (decompilerSection.get(decompiler.getName()) != null) {
JsonObject thisDecompiler = decompilerSection.get(decompiler.getName()).asObject();
for (Map.Entry<Setting, JCheckBoxMenuItem> entry : menuItems.entrySet()) {
if (thisDecompiler.get(entry.getKey().getParam()) != null) {
entry.getValue().setSelected(thisDecompiler.get(entry.getKey().getParam()).asBoolean());
}
}
}
}
}
public void saveTo(JsonObject rootSettings) {
if (rootSettings.get("decompilers") == null) {
rootSettings.add("decompilers", new JsonObject());
}
JsonObject decompilerSection = rootSettings.get("decompilers").asObject();
if (decompilerSection.get(decompiler.getName()) == null) {
decompilerSection.add(decompiler.getName(), new JsonObject());
}
JsonObject thisDecompiler = decompilerSection.get(decompiler.getName()).asObject();
for (Map.Entry<Setting, JCheckBoxMenuItem> entry : menuItems.entrySet()) {
thisDecompiler.add(entry.getKey().getParam(), entry.getValue().isSelected());
}
}
public interface Setting {
String getText();
String getParam();
boolean isDefaultOn();
}
}

View file

@ -35,12 +35,12 @@ public class Enjarify {
* @param output the output .jar file
*/
public static synchronized void apk2Jar(File input, File output) {
if(BytecodeViewer.python3.equals("")) {
if(Settings.PYTHON3_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 3.x executable path.");
BytecodeViewer.viewer.pythonC3();
}
if(BytecodeViewer.python3.equals("")) {
if(Settings.PYTHON3_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set Python!");
return;
}
@ -48,7 +48,7 @@ public class Enjarify {
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python3,
Settings.PYTHON3_LOCATION.get(),
"-O",
"-m",
"enjarify.main",
@ -58,7 +58,7 @@ public class Enjarify {
"-f"
);
pb.directory(new File(BytecodeViewer.enjarifyWorkingDirectory));
pb.directory(BytecodeViewer.enjarifyDirectory);
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
process.waitFor();

View file

@ -28,6 +28,6 @@ import org.objectweb.asm.tree.ClassNode;
*/
public interface FileChangeNotifier {
public void openClassFile(String name, ClassNode cn);
public void openFile(String name, byte[] contents);
void openClassFile(String name, ClassNode cn);
void openFile(String name, byte[] contents);
}

View file

@ -1,14 +1,13 @@
package the.bytecode.club.bytecodeviewer;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -335,8 +335,7 @@ public class FileDrop {
// Get a useful list
final java.util.List fileList = (java.util.List) tr
.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor);
final java.util.Iterator iterator = fileList
.iterator();
final java.util.Iterator iterator = fileList.iterator();
// Convert list to array
final java.io.File[] filesTemp = new java.io.File[fileList
@ -466,7 +465,7 @@ public class FileDrop {
catch (final Exception e) {
support = false;
} // end catch
supportsDnD = new Boolean(support);
supportsDnD = support;
} // end if: first time through
return supportsDnD.booleanValue();
} // end supportsDnD

View file

@ -1,8 +1,15 @@
package the.bytecode.club.bytecodeviewer;
import javax.swing.*;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.text.html.HTMLEditorKit;
import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.io.IOException;
/***************************************************************************

View file

@ -1,5 +1,9 @@
package the.bytecode.club.bytecodeviewer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@ -14,12 +18,6 @@ import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import me.konloch.kontainer.io.DiskWriter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -282,71 +280,6 @@ public class JarUtils {
}
}
/**
* Saves a jar without the manifest
* @param nodeList The loaded ClassNodes
* @param path the exact jar output path
*/
public static void saveAsJarClassesOnlyToDir(ArrayList<ClassNode> nodeList, String dir) {
try {
for (ClassNode cn : nodeList) {
ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String name = dir + BytecodeViewer.fs + cn.name + ".class";
File f = new File(name);
f.mkdirs();
DiskWriter.replaceFile(name, cw.toByteArray(), false);
}
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
/**
* Saves a jar without the manifest
* @param nodeList The loaded ClassNodes
* @param path the exact jar output path
*/
public static void saveAsJar(ArrayList<ClassNode> nodeList, String path) {
try {
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
ArrayList<String> noDupe = new ArrayList<String>();
for (ClassNode cn : nodeList) {
ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String name = cn.name + ".class";
if(!noDupe.contains(name)) {
noDupe.add(name);
out.putNextEntry(new ZipEntry(name));
out.write(cw.toByteArray());
out.closeEntry();
}
}
for(FileContainer container : BytecodeViewer.files)
for (Entry<String, byte[]> entry : container.files.entrySet()) {
String filename = entry.getKey();
if (!filename.startsWith("META-INF")) {
if(!noDupe.contains(filename)) {
noDupe.add(filename);
out.putNextEntry(new ZipEntry(filename));
out.write(entry.getValue());
out.closeEntry();
}
}
}
noDupe.clear();
out.close();
} catch (IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
public static void saveAsJar(Map<String, byte[]> nodeList, String path) {
try {
JarOutputStream out = new JarOutputStream(new FileOutputStream(path));
@ -380,5 +313,4 @@ public class JarUtils {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}

View file

@ -1,15 +1,13 @@
package the.bytecode.club.bytecodeviewer;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.ArrayList;
import org.imgscalr.Scalr;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import org.apache.commons.codec.binary.Base64;
import org.imgscalr.Scalr;
import javax.xml.bind.DatatypeConverter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -37,7 +35,6 @@ import org.imgscalr.Scalr;
*/
public class Resources {
public static ArrayList<BufferedImage> iconList;
public static BufferedImage icon;
public static ImageIcon nextIcon;
@ -86,7 +83,7 @@ public class Resources {
decodedIcon = new ImageIcon(Resources.class.getClass().getResource("/decoded.png"));
javaIcon = new ImageIcon(Resources.class.getClass().getResource("/java.png"));
iconList = new ArrayList<BufferedImage>();
iconList = new ArrayList<>();
int size = 16;
for (int i = 0; i < 24; i++) {
iconList.add(resize(icon, size, size));
@ -106,24 +103,13 @@ public class Resources {
byte[] imageByte;
try {
imageByte = Base64.decodeBase64(imageString);
imageByte = DatatypeConverter.parseBase64Binary(imageString);
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return image;
}
public static String findLibrary(String nameContains) {
for(File f : new File(BytecodeViewer.libsDirectory).listFiles()) {
if(f.getName().contains(nameContains))
return f.getAbsolutePath();
}
return null;
}
}

View file

@ -1,420 +1,112 @@
package the.bytecode.club.bytecodeviewer;
import javax.swing.JFrame;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.ParseException;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import me.konloch.kontainer.io.DiskReader;
import me.konloch.kontainer.io.DiskWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Used to handle loading/saving the GUI (options).
*
* @author Konloch
*
* @author Konloch
*/
public class Settings<T> {
private static final Map<String, Settings> ALL_SETTINGS = new HashMap<>();
public class Settings {
public static final Settings<String> PYTHON2_LOCATION = new Settings<>("python2location");
public static final Settings<String> PYTHON3_LOCATION = new Settings<>("python3location");
public static final Settings<String> JAVAC_LOCATION = new Settings<>("javaclocation");
public static final Settings<String> JAVA_LOCATION = new Settings<>("javalocation");
public static final Settings<String> RT_LOCATION = new Settings<>("rtlocation");
public static final Settings<String> PATH = new Settings<>("path");
public static void saveGUI() {
try {
DiskWriter.replaceFile(BytecodeViewer.settingsName, "", false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rbr.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rsy.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.din.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dc4.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.das.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hes.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hdc.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dgs.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.ner.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.den.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rgn.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.bto.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.nns.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.uto.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.udv.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.rer.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.fdi.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.asc.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodeenumswitch.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodestringswitch.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.collectioniter.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removeboilerplate.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidebridgemethods.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.liftconstructorinit.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removedeadmethods.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.removebadgenerics.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.showversion.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.lenient.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.comments.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcetopsortaggress.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.silent.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recover.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.override.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.showinferrable.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forcecondpropagate.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidelongstrings.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.commentmonitor.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.allowcorrecting.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.labelledblocks.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.hidelangimports.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recoverytypeclash.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.recoverytypehints.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forceturningifs.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forloopaggcapture.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.forceexceptionprune.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmShowDebugLine.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.mnMergeVariables.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()), false);
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.panelGroup1.isSelected(BytecodeViewer.viewer.panel1None.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Proc.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1CFR.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Fern.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Bytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Hexcode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
else if(BytecodeViewer.viewer.panelGroup1.isSelected(BytecodeViewer.viewer.panel1JDGUI.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false);
if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2None.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Proc.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2CFR.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Fern.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Bytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Hexcode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
else if(BytecodeViewer.viewer.panelGroup2.isSelected(BytecodeViewer.viewer.panel2JDGUI.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false);
if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3None.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Proc.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3CFR.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "2", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Fern.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "3", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Bytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "4", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Hexcode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "5", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Smali.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "6", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3Krakatau.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "7", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "8", false);
else if(BytecodeViewer.viewer.panelGroup3.isSelected(BytecodeViewer.viewer.panel3JDGUI.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "9", false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.refreshOnChange.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.isMaximized), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileSmali.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.autoCompileOnRefresh.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.lastDirectory, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.rt, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Proc_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1CFR_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Fern_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Krakatau_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1Smali_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Proc_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2CFR_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Fern_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Krakatau_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2Smali_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Proc_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3CFR_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Fern_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Krakatau_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3Smali_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.decodeAPKResources.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.library, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.pingback), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel1JDGUI_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel2JDGUI_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.panel3JDGUI_E.isSelected()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.viewer.fontSpinner.getValue()), false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, String.valueOf(BytecodeViewer.deleteForiegnLibraries), false);
if(BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionDex.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "0", false);
else if(BytecodeViewer.viewer.apkConversionGroup.isSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel()))
DiskWriter.writeNewLine(BytecodeViewer.settingsName, "1", false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.python3, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.javac, false);
DiskWriter.writeNewLine(BytecodeViewer.settingsName, BytecodeViewer.java, false);
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
public static void loadGUI() { //utilizes the Disk Reader's caching system.
try {
BytecodeViewer.viewer.rbr.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 1, true)));
BytecodeViewer.viewer.rsy.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 2, false)));
BytecodeViewer.viewer.din.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 3, false)));
BytecodeViewer.viewer.dc4.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 4, false)));
BytecodeViewer.viewer.das.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 5, false)));
BytecodeViewer.viewer.hes.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 6, false)));
BytecodeViewer.viewer.hdc.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 7, false)));
BytecodeViewer.viewer.dgs.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 8, false)));
BytecodeViewer.viewer.ner.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 9, false)));
BytecodeViewer.viewer.den.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 10, false)));
BytecodeViewer.viewer.rgn.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 11, false)));
BytecodeViewer.viewer.bto.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 12, false)));
BytecodeViewer.viewer.nns.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 13, false)));
BytecodeViewer.viewer.uto.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 14, false)));
BytecodeViewer.viewer.udv.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 15, false)));
BytecodeViewer.viewer.rer.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 16, false)));
BytecodeViewer.viewer.fdi.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 17, false)));
BytecodeViewer.viewer.asc.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 18, false)));
BytecodeViewer.viewer.decodeenumswitch.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 19, false)));
BytecodeViewer.viewer.sugarenums.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 20, false)));
BytecodeViewer.viewer.decodestringswitch.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 21, false)));
BytecodeViewer.viewer.arrayiter.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 22, false)));
BytecodeViewer.viewer.collectioniter.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 23, false)));
BytecodeViewer.viewer.innerclasses.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 24, false)));
BytecodeViewer.viewer.removeboilerplate.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 25, false)));
BytecodeViewer.viewer.removeinnerclasssynthetics.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 26, false)));
BytecodeViewer.viewer.decodelambdas.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 27, false)));
BytecodeViewer.viewer.hidebridgemethods.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 28, false)));
BytecodeViewer.viewer.liftconstructorinit.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 29, false)));
BytecodeViewer.viewer.removedeadmethods.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 30, false)));
BytecodeViewer.viewer.removebadgenerics.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 31, false)));
BytecodeViewer.viewer.sugarasserts.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 32, false)));
BytecodeViewer.viewer.sugarboxing.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 33, false)));
BytecodeViewer.viewer.showversion.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 34, false)));
BytecodeViewer.viewer.decodefinally.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 35, false)));
BytecodeViewer.viewer.tidymonitors.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 36, false)));
BytecodeViewer.viewer.lenient.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 37, false)));
BytecodeViewer.viewer.dumpclasspath.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 38, false)));
BytecodeViewer.viewer.comments.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 39, false)));
BytecodeViewer.viewer.forcetopsort.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 40, false)));
BytecodeViewer.viewer.forcetopsortaggress.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 41, false)));
BytecodeViewer.viewer.stringbuffer.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 42, false)));
BytecodeViewer.viewer.stringbuilder.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 43, false)));
BytecodeViewer.viewer.silent.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 44, false)));
BytecodeViewer.viewer.recover.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 45, false)));
BytecodeViewer.viewer.eclipse.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 46, false)));
BytecodeViewer.viewer.override.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 47, false)));
BytecodeViewer.viewer.showinferrable.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 48, false)));
BytecodeViewer.viewer.aexagg.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 49, false)));
BytecodeViewer.viewer.forcecondpropagate.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 50, false)));
BytecodeViewer.viewer.hideutf.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 51, false)));
BytecodeViewer.viewer.hidelongstrings.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 52, false)));
BytecodeViewer.viewer.commentmonitor.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 53, false)));
BytecodeViewer.viewer.allowcorrecting.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 54, false)));
BytecodeViewer.viewer.labelledblocks.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 55, false)));
BytecodeViewer.viewer.j14classobj.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 56, false)));
BytecodeViewer.viewer.hidelangimports.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 57, false)));
BytecodeViewer.viewer.recoverytypeclash.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 58, false)));
BytecodeViewer.viewer.recoverytypehints.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 59, false)));
BytecodeViewer.viewer.forceturningifs.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 60, false)));
BytecodeViewer.viewer.forloopaggcapture.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 61, false)));
BytecodeViewer.viewer.forceexceptionprune.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 62, false)));
BytecodeViewer.viewer.chckbxmntmShowDebugLine.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 63, false)));
BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 64, false)));
BytecodeViewer.viewer.mnMergeVariables.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 65, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 66, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 67, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 68, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 69, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 70, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 71, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 72, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 73, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 74, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 75, false)));
BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 76, false)));
BytecodeViewer.viewer.chckbxmntmAppendBrackets.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 77, false)));
BytecodeViewer.viewer.debugHelpers.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 78, false)));
//79 is deprecated
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.panelGroup1.setSelected(BytecodeViewer.viewer.panel1None.getModel(), true);
else if(decompiler == 1)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Proc.getModel(), true);
else if(decompiler == 2)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1CFR.getModel(), true);
else if(decompiler == 3)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Fern.getModel(), true);
else if(decompiler == 4)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Bytecode.getModel(), true);
else if(decompiler == 5)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Hexcode.getModel(), true);
else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1KrakatauBytecode.getModel(), true);
else if(decompiler == 9)
BytecodeViewer.viewer.panelGroup1.setSelected(BytecodeViewer.viewer.panel1JDGUI.getModel(), true);
private String key;
private T value;
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 82, false));
if(decompiler == 0)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2None.getModel(), true);
else if(decompiler == 1)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Proc.getModel(), true);
else if(decompiler == 2)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2CFR.getModel(), true);
else if(decompiler == 3)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Fern.getModel(), true);
else if(decompiler == 4)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Bytecode.getModel(), true);
else if(decompiler == 5)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Hexcode.getModel(), true);
else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2KrakatauBytecode.getModel(), true);
else if(decompiler == 9)
BytecodeViewer.viewer.panelGroup2.setSelected(BytecodeViewer.viewer.panel2JDGUI.getModel(), true);
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 83, false));
if(decompiler == 0)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3None.getModel(), true);
else if(decompiler == 1)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Proc.getModel(), true);
else if(decompiler == 2)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3CFR.getModel(), true);
else if(decompiler == 3)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Fern.getModel(), true);
else if(decompiler == 4)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Bytecode.getModel(), true);
else if(decompiler == 5)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Hexcode.getModel(), true);
else if(decompiler == 6)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Smali.getModel(), true);
else if(decompiler == 7)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3Krakatau.getModel(), true);
else if(decompiler == 8)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3KrakatauBytecode.getModel(), true);
else if(decompiler == 9)
BytecodeViewer.viewer.panelGroup3.setSelected(BytecodeViewer.viewer.panel3JDGUI.getModel(), true);
BytecodeViewer.viewer.refreshOnChange.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 84, false)));
boolean bool = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 85, false));
if(bool) {
BytecodeViewer.viewer.setExtendedState(JFrame.MAXIMIZED_BOTH);
BytecodeViewer.viewer.isMaximized = true;
}
BytecodeViewer.viewer.autoCompileSmali.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 86, false)));
BytecodeViewer.viewer.autoCompileOnRefresh.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 87, false)));
BytecodeViewer.lastDirectory = DiskReader.loadString(BytecodeViewer.settingsName, 88, false);
BytecodeViewer.python = DiskReader.loadString(BytecodeViewer.settingsName, 89, false);
BytecodeViewer.rt = DiskReader.loadString(BytecodeViewer.settingsName, 90, false);
BytecodeViewer.viewer.panel1Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 91, false)));
BytecodeViewer.viewer.panel1CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 92, false)));
BytecodeViewer.viewer.panel1Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 93, false)));
BytecodeViewer.viewer.panel1Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 94, false)));
BytecodeViewer.viewer.panel1Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 95, false)));
BytecodeViewer.viewer.panel2Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 96, false)));
BytecodeViewer.viewer.panel2CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 97, false)));
BytecodeViewer.viewer.panel2Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 98, false)));
BytecodeViewer.viewer.panel2Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 99, false)));
BytecodeViewer.viewer.panel2Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 100, false)));
BytecodeViewer.viewer.panel3Proc_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 101, false)));
BytecodeViewer.viewer.panel3CFR_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 101, false)));
BytecodeViewer.viewer.panel3Fern_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 103, false)));
BytecodeViewer.viewer.panel3Krakatau_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 104, false)));
BytecodeViewer.viewer.panel3Smali_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 105, false)));
BytecodeViewer.viewer.decodeAPKResources.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 106, false)));
BytecodeViewer.library = DiskReader.loadString(BytecodeViewer.settingsName, 107, false);
BytecodeViewer.pingback = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 108, false));
BytecodeViewer.viewer.panel1JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 109, false)));
BytecodeViewer.viewer.panel2JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 110, false)));
BytecodeViewer.viewer.panel3JDGUI_E.setSelected(Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 111, false)));
BytecodeViewer.viewer.fontSpinner.setValue(Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 112, false)));
BytecodeViewer.deleteForiegnLibraries = Boolean.parseBoolean(DiskReader.loadString(BytecodeViewer.settingsName, 113, false));
decompiler = Integer.parseInt(DiskReader.loadString(BytecodeViewer.settingsName, 114, false));
if(decompiler == 0)
BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionDex.getModel(), true);
else if(decompiler == 1)
BytecodeViewer.viewer.apkConversionGroup.setSelected(BytecodeViewer.viewer.apkConversionEnjarify.getModel(), true);
BytecodeViewer.python3 = DiskReader.loadString(BytecodeViewer.settingsName, 115, false);
BytecodeViewer.javac = DiskReader.loadString(BytecodeViewer.settingsName, 116, false);
BytecodeViewer.java = DiskReader.loadString(BytecodeViewer.settingsName, 117, false);
} catch(Exception e) {
//ignore because errors are expected, first start up and outdated settings.
//e.printStackTrace();
}
}
public Settings(String key) {
this.key = key;
ALL_SETTINGS.put(this.key, this);
}
public T get() {
return this.value;
}
public void set(T value) {
this.value = value;
}
public boolean isEmpty() {
return this.value == null || (this.value instanceof String && ((String) this.value).isEmpty());
}
public static void saveGUI() {
try {
JsonObject settings = new JsonObject();
Decompiler.CFR.getSettings().saveTo(settings);
Decompiler.FERNFLOWER.getSettings().saveTo(settings);
Decompiler.PROCYON.getSettings().saveTo(settings);
Decompiler.BYTECODE.getSettings().saveTo(settings);
if (settings.get("settings") == null) {
settings.add("settings", new JsonObject());
}
JsonObject rootSettings = settings.get("settings").asObject();
for (Map.Entry<String, Settings> setting : Settings.ALL_SETTINGS.entrySet()) {
if (setting.getValue().get() != null) {
rootSettings.add(setting.getKey(), setting.getValue().get().toString());
}
}
FileOutputStream out = new FileOutputStream(BytecodeViewer.settingsFile);
out.write(settings.toString().getBytes("UTF-8"));
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void loadGUI() {
try {
JsonObject settings = new JsonObject();
try {
settings = JsonObject.readFrom(new FileReader(BytecodeViewer.settingsFile));
} catch (ParseException | UnsupportedOperationException e) {
}
Decompiler.CFR.getSettings().loadFrom(settings);
Decompiler.FERNFLOWER.getSettings().loadFrom(settings);
Decompiler.PROCYON.getSettings().loadFrom(settings);
Decompiler.BYTECODE.getSettings().loadFrom(settings);
if (settings.get("settings") != null) {
JsonObject rootSettings = settings.get("settings").asObject();
for (Map.Entry<String, Settings> setting : Settings.ALL_SETTINGS.entrySet()) {
if (rootSettings.get(setting.getKey()) != null) {
setting.getValue().set(rootSettings.get(setting.getKey()).asString());
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -1,157 +0,0 @@
package the.bytecode.club.bytecodeviewer;
import java.io.*;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Rudimentary utility class for Zip archives.
*/
public final class ZipUtils {
/**
* Unzip files to path.
*
* @param zipFileName the zip file name
* @param fileExtractPath the file extract path
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void unzipFilesToPath(String jarPath, String destinationDir) throws IOException {
File file = new File(jarPath);
JarFile jar = new JarFile(file);
// fist get all directories,
// then make those directory on the destination Path
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
JarEntry entry = (JarEntry) enums.nextElement();
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (fileName.endsWith("/")) {
f.mkdirs();
}
}
//now create all files
for (Enumeration<JarEntry> enums = jar.entries(); enums.hasMoreElements(); ) {
JarEntry entry = (JarEntry) enums.nextElement();
String fileName = destinationDir + File.separator + entry.getName();
File f = new File(fileName);
if (!fileName.endsWith("/")) {
InputStream is = jar.getInputStream(entry);
FileOutputStream fos = new FileOutputStream(f);
// write contents of 'is' to 'fos'
while (is.available() > 0) {
fos.write(is.read());
}
fos.close();
is.close();
}
}
try {
jar.close();
} catch (Exception e) {
}
}
public static void zipFile(File inputFile, File outputZip) {
byte[] buffer = new byte[1024];
try {
FileOutputStream fos = new FileOutputStream(outputZip);
ZipOutputStream zos = new ZipOutputStream(fos);
ZipEntry ze = new ZipEntry(inputFile.getName());
zos.putNextEntry(ze);
FileInputStream in = new FileInputStream(inputFile);
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void zipFolder(String srcFolder, String destZipFile, String ignore) throws Exception {
ZipOutputStream zip = null;
FileOutputStream fileWriter = null;
fileWriter = new FileOutputStream(destZipFile);
zip = new ZipOutputStream(fileWriter);
addFolderToZip("", srcFolder, zip, ignore);
zip.flush();
zip.close();
}
public static void addFileToZip(String path, String srcFile, ZipOutputStream zip, String ignore)
throws Exception {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(path, srcFile, zip, ignore);
} else {
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
ZipEntry entry = null;
if (ignore == null)
entry = new ZipEntry(path + "/" + folder.getName());
else
entry = new ZipEntry(path.replace(ignore, "BCV_Krakatau") + "/" + folder.getName());
zip.putNextEntry(entry);
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
in.close();
}
}
public static void addFolderToZip(String path, String srcFolder, ZipOutputStream zip, String ignore)
throws Exception {
File folder = new File(srcFolder);
for (String fileName : folder.list()) {
if (path.equals("")) {
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip, ignore);
} else {
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip, ignore);
}
}
}
}

View file

@ -1,7 +1,5 @@
package the.bytecode.club.bytecodeviewer.api;
import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
@ -11,9 +9,10 @@ import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,5 +1,10 @@
package the.bytecode.club.bytecodeviewer.api;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
import java.io.File;
import java.io.IOException;
import java.net.URL;
@ -10,276 +15,260 @@ import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* The official API for BCV, this was designed for plugin authors and
* people utilizing EZ-Injection.
*
*
* @author Konloch
*
*
*/
public class BytecodeViewer {
private static URLClassLoader cl;
/**
* Grab the loader instance
*
* @return
*/
public static ClassNodeLoader getClassNodeLoader() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader;
}
/**
* Returns the URLClassLoader instance
* @return the URLClassLoader instance
*/
public static URLClassLoader getClassLoaderInstance() {
return cl;
}
private static URLClassLoader cl;
/**
* Re-instances the URLClassLoader and loads a jar to it.
*
* @param nodeList
* The list of ClassNodes to be loaded
* @return The loaded classes into the new URLClassLoader instance
* @author Cafebabe
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("deprecation")
public static List<Class<?>> loadClassesIntoClassLoader(
ArrayList<ClassNode> nodeList) throws IOException,
ClassNotFoundException {
/**
* Grab the loader instance
*
* @return
*/
public static ClassNodeLoader getClassNodeLoader() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.loader;
}
File f = new File(
the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDirectory
+ the.bytecode.club.bytecodeviewer.BytecodeViewer.fs
+ "loaded_temp.jar");
JarUtils.saveAsJarClassesOnly(nodeList, f.getAbsolutePath());
JarFile jarFile = new JarFile("" + f.getAbsolutePath());
Enumeration<JarEntry> e = jarFile.entries();
cl = URLClassLoader.newInstance(new URL[]{ f.toURL() });
List<Class<?>> ret = new ArrayList<Class<?>>();
/**
* Returns the URLClassLoader instance
* @return the URLClassLoader instance
*/
public static URLClassLoader getClassLoaderInstance() {
return cl;
}
while (e.hasMoreElements()) {
JarEntry je = (JarEntry) e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class"))
continue;
String className = je.getName().replace("/", ".").replace(".class", "");
className = className.replace('/', '.');
ret.add(cl.loadClass(className));
}
jarFile.close();
/**
* Re-instances the URLClassLoader and loads a jar to it.
*
* @param nodeList
* The list of ClassNodes to be loaded
* @return The loaded classes into the new URLClassLoader instance
* @author Cafebabe
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("deprecation")
public static List<Class<?>> loadClassesIntoClassLoader(ArrayList<ClassNode> nodeList) throws IOException, ClassNotFoundException {
File f = new File(the.bytecode.club.bytecodeviewer.BytecodeViewer.tempDir, "loaded_temp.jar");
JarUtils.saveAsJarClassesOnly(nodeList, f.getAbsolutePath());
return ret;
JarFile jarFile = new JarFile("" + f.getAbsolutePath());
Enumeration<JarEntry> e = jarFile.entries();
cl = URLClassLoader.newInstance(new URL[]{f.toURL()});
List<Class<?>> ret = new ArrayList<Class<?>>();
}
/**
* Re-instances the URLClassLoader and loads a jar to it.
* @return The loaded classes into the new URLClassLoader instance
* @author Cafebabe
* @throws IOException
* @throws ClassNotFoundException
*/
public static List<Class<?>> loadAllClassesIntoClassLoader() throws ClassNotFoundException, IOException {
return loadClassesIntoClassLoader(getLoadedClasses());
}
while (e.hasMoreElements()) {
JarEntry je = (JarEntry) e.nextElement();
if (je.isDirectory() || !je.getName().endsWith(".class")) continue;
String className = je.getName().replace("/", ".").replace(".class", "");
className = className.replace('/', '.');
ret.add(cl.loadClass(className));
/**
* Creates a new instance of the ClassNode loader.
*/
public static void createNewClassNodeLoaderInstance() {
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear();
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader();
}
}
jarFile.close();
/**
* Used to start a plugin from file.
*
* @param plugin
* the file of the plugin
*/
public static void startPlugin(File plugin) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.startPlugin(plugin);
}
return ret;
/**
* Used to load classes/jars into BCV.
*
* @param files
* 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, boolean recentFiles) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files, recentFiles);
}
}
/**
* Returns the currently opened class node, if nothing is opened it'll return null.
* @return The opened class node or a null if nothing is opened
*/
public static ClassNode getCurrentlyOpenedClassNode() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getCurrentlyOpenedClassNode();
}
/**
* Used to load a ClassNode.
*
* @param name
* the full name of the ClassNode
* @return the ClassNode
*/
public static ClassNode getClassNode(String name) {
return the.bytecode.club.bytecodeviewer.BytecodeViewer
.getClassNode(name);
}
/**
* Used to grab the loaded ClassNodes.
*
* @return the loaded classes
*/
public static ArrayList<ClassNode> getLoadedClasses() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer
.getLoadedClasses();
}
/**
* Re-instances the URLClassLoader and loads a jar to it.
* @return The loaded classes into the new URLClassLoader instance
* @author Cafebabe
* @throws IOException
* @throws ClassNotFoundException
*/
public static List<Class<?>> loadAllClassesIntoClassLoader() throws ClassNotFoundException, IOException {
return loadClassesIntoClassLoader(getLoadedClasses());
}
/**
* Used to insert a Bytecode Hook using EZ-Injection.
*
* @param hook
*/
public static void insertHook(BytecodeHook hook) {
EZInjection.hookArray.add(hook);
}
/**
* Creates a new instance of the ClassNode loader.
*/
public static void createNewClassNodeLoaderInstance() {
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader.clear();
the.bytecode.club.bytecodeviewer.BytecodeViewer.loader = new ClassNodeLoader();
}
/**
* 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(boolean ask) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask);
}
/**
* Used to start a plugin from file.
*
* @param plugin
* the file of the plugin
*/
public static void startPlugin(File plugin) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.startPlugin(plugin);
}
/**
* If true, it will display the busy icon, if false it will remove it if
* it's displayed.
*
* @param busy
* if it should display the busy icon or not
*/
public static void setBusy(boolean busy) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.viewer.setIcon(busy);
}
/**
* Used to load classes/jars into BCV.
*
* @param files
* 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, boolean recentFiles) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.openFiles(files, recentFiles);
}
/**
* Sends a small window popup with the defined message.
*
* @param message
* the message you want to display
*/
public static void showMessage(String message) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.showMessage(message);
}
/**
* Returns the wrapped Krakatau Decompiler instance.
* @return The wrapped Krakatau Decompiler instance
*/
public static Decompiler getKrakatauDecompiler() {
return Decompiler.krakatau;
}
/**
* Returns the wrapped Procyon Decompiler instance.
* @return The wrapped Procyon Decompiler instance
*/
public static Decompiler getProcyonDecompiler() {
return Decompiler.procyon;
}
/**
* Returns the wrapped CFR Decompiler instance.
* @return The wrapped CFR Decompiler instance
*/
public static Decompiler getCFRDecompiler() {
return Decompiler.cfr;
}
/**
* Returns the wrapped FernFlower Decompiler instance.
* @return The wrapped FernFlower Decompiler instance
*/
public static Decompiler getFernFlowerDecompiler() {
return Decompiler.fernflower;
}
/**
* Returns the wrapped Krakatau Disassembler instance.
* @return The wrapped Krakatau Disassembler instance
*/
public static Decompiler getKrakatauDisassembler() {
return Decompiler.krakatauDA;
}
/**
* Returns the wrapped Krakatau Assembler instance.
* @return The wrapped Krakatau Assembler instance
*/
public static the.bytecode.club.bytecodeviewer.compilers.Compiler getKrakatauCompiler() {
return the.bytecode.club.bytecodeviewer.compilers.Compiler.krakatau;
}
/**
* Returns the wrapped Smali Assembler instance.
* @return The wrapped Smali Assembler instance
*/
public static the.bytecode.club.bytecodeviewer.compilers.Compiler getSmaliCompiler() {
return the.bytecode.club.bytecodeviewer.compilers.Compiler.smali;
}
/**
* Returns the wrapped JD-GUI Decompiler instance.
* @return The wrapped JD-GUI Decompiler instance
*/
public static the.bytecode.club.bytecodeviewer.decompilers.Decompiler getDJGUIDecompiler() {
return the.bytecode.club.bytecodeviewer.decompilers.Decompiler.jdgui;
}
/**
* Returns the currently opened class node, if nothing is opened it'll return null.
* @return The opened class node or a null if nothing is opened
*/
public static ClassNode getCurrentlyOpenedClassNode() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getCurrentlyOpenedClassNode();
}
/**
* Used to load a ClassNode.
*
* @param name
* the full name of the ClassNode
* @return the ClassNode
*/
public static ClassNode getClassNode(String name) {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getClassNode(name);
}
/**
* Used to grab the loaded ClassNodes.
*
* @return the loaded classes
*/
public static ArrayList<ClassNode> getLoadedClasses() {
return the.bytecode.club.bytecodeviewer.BytecodeViewer.getLoadedClasses();
}
/**
* Used to insert a Bytecode Hook using EZ-Injection.
*
* @param hook
*/
public static void insertHook(BytecodeHook hook) {
EZInjection.hookArray.add(hook);
}
/**
* 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(boolean ask) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.resetWorkSpace(ask);
}
/**
* If true, it will display the busy icon, if false it will remove it if
* it's displayed.
*
* @param busy
* if it should display the busy icon or not
*/
public static void setBusy(boolean busy) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.viewer.setIcon(busy);
}
/**
* Sends a small window popup with the defined message.
*
* @param message
* the message you want to display
*/
public static void showMessage(String message) {
the.bytecode.club.bytecodeviewer.BytecodeViewer.showMessage(message);
}
/**
* Returns the wrapped Krakatau Decompiler instance.
* @return The wrapped Krakatau Decompiler instance
*/
public static Decompiler getKrakatauDecompiler() {
return Decompiler.KRAKATAU;
}
/**
* Returns the wrapped Procyon Decompiler instance.
* @return The wrapped Procyon Decompiler instance
*/
public static Decompiler getProcyonDecompiler() {
return Decompiler.PROCYON;
}
/**
* Returns the wrapped CFR Decompiler instance.
* @return The wrapped CFR Decompiler instance
*/
public static Decompiler getCFRDecompiler() {
return Decompiler.CFR;
}
/**
* Returns the wrapped FernFlower Decompiler instance.
* @return The wrapped FernFlower Decompiler instance
*/
public static Decompiler getFernFlowerDecompiler() {
return Decompiler.FERNFLOWER;
}
/**
* Returns the wrapped Krakatau Disassembler instance.
* @return The wrapped Krakatau Disassembler instance
*/
public static Decompiler getKrakatauDisassembler() {
return Decompiler.KRAKATAU_DA;
}
/**
* Returns the wrapped Krakatau Assembler instance.
* @return The wrapped Krakatau Assembler instance
*/
public static the.bytecode.club.bytecodeviewer.compilers.Compiler getKrakatauCompiler() {
return the.bytecode.club.bytecodeviewer.compilers.Compiler.krakatau;
}
/**
* Returns the wrapped Smali Assembler instance.
* @return The wrapped Smali Assembler instance
*/
public static the.bytecode.club.bytecodeviewer.compilers.Compiler getSmaliCompiler() {
return the.bytecode.club.bytecodeviewer.compilers.Compiler.smali;
}
/**
* Returns the wrapped JD-GUI Decompiler instance.
* @return The wrapped JD-GUI Decompiler instance
*/
public static the.bytecode.club.bytecodeviewer.decompilers.Decompiler getDJGUIDecompiler() {
return the.bytecode.club.bytecodeviewer.decompilers.Decompiler.JDGUI;
}
}

View file

@ -1,5 +1,8 @@
package the.bytecode.club.bytecodeviewer.api;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
@ -9,9 +12,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -38,6 +38,10 @@ import org.objectweb.asm.tree.ClassNode;
public final class ClassNodeLoader extends ClassLoader {
public ClassNodeLoader() {
super(ClassLoader.getSystemClassLoader());
}
private HashMap<String, ClassNode> classes = new HashMap<String, ClassNode>();
/**

View file

@ -1,18 +1,17 @@
package the.bytecode.club.bytecodeviewer.api;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -79,7 +78,6 @@ public class ExceptionUI extends JFrame {
}
private void setup(Throwable e, String author) {
this.setIconImages(Resources.iconList);
setSize(new Dimension(600, 400));
setTitle("Bytecode Viewer " + BytecodeViewer.version

View file

@ -1,11 +1,10 @@
package the.bytecode.club.bytecodeviewer.api;
import java.util.ArrayList;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -37,11 +36,11 @@ public abstract class Plugin extends Thread {
public void run() {
BytecodeViewer.viewer.setIcon(true);
try {
if(BytecodeViewer.getLoadedClasses().isEmpty()) {
if(BytecodeViewer.getLoadedBytes().isEmpty()) {
BytecodeViewer.showMessage("First open a class, jar, zip, apk or dex file.");
return;
}
execute(BytecodeViewer.getLoadedClasses());
execute(BytecodeViewer.loadAllClasses());
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {

View file

@ -1,30 +1,25 @@
package the.bytecode.club.bytecodeviewer.api;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -255,10 +250,8 @@ public class PluginConsole extends JFrame {
* the string you want to append
*/
public void appendText(String t) {
textArea.setText((textArea.getText().isEmpty() ? "" : textArea
.getText() + "\r\n")
+ t);
textArea.setCaretPosition(0);
textArea.append(t + "\r\n");
textArea.setCaretPosition(textArea.getText().length());
}
/**

View file

@ -1,16 +1,17 @@
package the.bytecode.club.bytecodeviewer.compilers;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.Settings;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import me.konloch.kontainer.io.DiskWriter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -40,27 +41,31 @@ public class JavaCompiler extends Compiler {
@Override
public byte[] compile(String contents, String name) {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs;
String fileStart2 = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs;
String fileStart = BytecodeViewer.tempDir.getAbsolutePath() + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs;
String fileStart2 = BytecodeViewer.tempDir.getAbsolutePath() + BytecodeViewer.fs + "temp"+MiscUtils.randomString(12)+BytecodeViewer.fs;
File java = new File(fileStart + BytecodeViewer.fs + name + ".java");
File clazz = new File(fileStart2 + BytecodeViewer.fs + name + ".class");
File cp = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "cpath_"+MiscUtils.randomString(12)+".jar");
File cp = new File(BytecodeViewer.tempDir, "cpath_"+MiscUtils.randomString(12)+".jar");
File tempD = new File(fileStart + BytecodeViewer.fs + name.substring(0,name.length() - name.split("/")[name.split("/").length-1].length()));
tempD.mkdirs();
new File(fileStart2).mkdirs();
if(BytecodeViewer.javac.equals("")) {
if(Settings.JAVAC_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Javac path, this requires the JDK to be downloaded."+BytecodeViewer.nl+"(C:/programfiles/Java/JRE_xx/bin/javac.exe)");
BytecodeViewer.viewer.javac();
}
if(BytecodeViewer.javac.equals("")) {
if(Settings.JAVAC_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set Javac!");
return null;
}
DiskWriter.replaceFile(java.getAbsolutePath(), contents, false);
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), cp.getAbsolutePath());
try {
FileUtils.write(java, contents, "UTF-8", false);
} catch (IOException e) {
e.printStackTrace();
}
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), cp.getAbsolutePath());
boolean cont = true;
BytecodeViewer.sm.stopBlocking();
@ -68,18 +73,18 @@ public class JavaCompiler extends Compiler {
String log = "";
ProcessBuilder pb;
if(BytecodeViewer.library.isEmpty()) {
if(Settings.PATH.isEmpty()) {
pb = new ProcessBuilder(
BytecodeViewer.javac,
Settings.JAVAC_LOCATION.get(),
"-d", fileStart2,
"-classpath", cp.getAbsolutePath(),
java.getAbsolutePath()
);
} else {
pb = new ProcessBuilder(
BytecodeViewer.javac,
Settings.JAVAC_LOCATION.get(),
"-d", fileStart2,
"-classpath", cp.getAbsolutePath()+";"+BytecodeViewer.library,
"-classpath", cp.getAbsolutePath()+";"+Settings.PATH.get(),
java.getAbsolutePath()
);
}

View file

@ -1,14 +1,16 @@
package the.bytecode.club.bytecodeviewer.compilers;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.io.FileUtils;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.Settings;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -38,12 +40,12 @@ public class KrakatauAssembler extends Compiler {
@Override
public byte[] compile(String contents, String name) {
if(BytecodeViewer.python.equals("")) {
if(Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.python.equals("")) {
if(Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set Python!");
return null;
}
@ -51,24 +53,28 @@ public class KrakatauAssembler extends Compiler {
String origName = name;
name = MiscUtils.randomString(20);
File tempD = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
File tempD = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempD.mkdir();
File tempJ = new File(tempD.getAbsolutePath() + BytecodeViewer.fs+name+".j");
DiskWriter.replaceFile(tempJ.getAbsolutePath(), contents, true);
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
try {
FileUtils.write(tempJ, contents, "UTF-8", false);
} catch (IOException e) {
e.printStackTrace();
}
final File tempDirectory = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
final File tempJar = new File(BytecodeViewer.tempDir, BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
String log = "";
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
Settings.PYTHON2_LOCATION.get(),
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "assemble.py",
BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "assemble.py",
"-out",
tempDirectory.getAbsolutePath(),
tempJ.getAbsolutePath()

View file

@ -1,13 +1,13 @@
package the.bytecode.club.bytecodeviewer.compilers;
import java.io.File;
import me.konloch.kontainer.io.DiskWriter;
import org.apache.commons.io.FileUtils;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Dex2Jar;
import the.bytecode.club.bytecodeviewer.Enjarify;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
import java.io.File;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -38,7 +38,7 @@ public class SmaliAssembler extends Compiler {
@Override
public byte[] compile(String contents, String name) {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
String fileStart = BytecodeViewer.tempDir.getAbsoluteFile() + BytecodeViewer.fs + "temp";
int fileNumber = MiscUtils.getClassNumber(fileStart, ".dex");
final File tempSmaliFolder = new File(fileStart + fileNumber + "-smalifolder"+BytecodeViewer.fs);
@ -50,7 +50,7 @@ public class SmaliAssembler extends Compiler {
File tempJarFolder = new File(fileStart + fileNumber + "-jar"+BytecodeViewer.fs);
try {
DiskWriter.replaceFile(tempSmali.getAbsolutePath(), contents, false);
FileUtils.write(tempSmali, contents, "UTF-8", false);
} catch (final Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
@ -68,7 +68,7 @@ public class SmaliAssembler extends Compiler {
Enjarify.apk2Jar(tempDex, tempJar);
try {
ZipUtils.unzipFilesToPath(tempJar.getAbsolutePath(), tempJarFolder.getAbsolutePath());
ZipUtil.unpack(tempJar, tempJarFolder);
File outputClass = null;
boolean found = false;

View file

@ -16,15 +16,20 @@ import org.benf.cfr.reader.util.bytestream.BaseByteData;
import org.benf.cfr.reader.util.getopt.GetOptParser;
import org.benf.cfr.reader.util.getopt.Options;
import org.benf.cfr.reader.util.getopt.OptionsImpl;
import org.benf.cfr.reader.util.output.*;
import org.benf.cfr.reader.util.output.Dumper;
import org.benf.cfr.reader.util.output.FileDumper;
import org.benf.cfr.reader.util.output.IllegalIdentifierDump;
import org.benf.cfr.reader.util.output.NopSummaryDumper;
import org.benf.cfr.reader.util.output.SummaryDumper;
import org.benf.cfr.reader.util.output.ToStringDumper;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.DecompilerSettings;
import the.bytecode.club.bytecodeviewer.JarUtils;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
@ -54,6 +59,22 @@ import java.util.List;
*/
public class CFRDecompiler extends Decompiler {
public CFRDecompiler() {
for (Settings setting : Settings.values()) {
settings.registerSetting(setting);
}
}
@Override
public DecompilerSettings getSettings() {
return settings;
}
@Override
public String getName() {
return "CFR";
}
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
try {
@ -62,11 +83,7 @@ public class CFRDecompiler extends Decompiler {
DCCommonState dcCommonState = new DCCommonState(options, classFileSource);
return doClass(dcCommonState, b);
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception;
return parseException(e);
}
}
@ -76,129 +93,41 @@ public class CFRDecompiler extends Decompiler {
Path outputDir = Files.createTempDirectory("cfr_output");
Path tempJar = Files.createTempFile("cfr_input", ".jar");
File output = new File(zipName);
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.toAbsolutePath().toString());
Options options = new GetOptParser().parse(generateMainMethod(), OptionsImpl.getFactory());
ClassFileSourceImpl classFileSource = new ClassFileSourceImpl(options);
DCCommonState dcCommonState = new DCCommonState(options, classFileSource);
doJar(dcCommonState, tempJar.toAbsolutePath(), outputDir.toAbsolutePath());
ZipUtil.pack(outputDir.toFile(), output);
FileUtils.deleteDirectory(outputDir.toFile());
Files.delete(tempJar);
try {
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempJar.toAbsolutePath().toString());
Options options = new GetOptParser().parse(generateMainMethod(), OptionsImpl.getFactory());
ClassFileSourceImpl classFileSource = new ClassFileSourceImpl(options);
DCCommonState dcCommonState = new DCCommonState(options, classFileSource);
doJar(dcCommonState, tempJar.toAbsolutePath(), outputDir.toAbsolutePath());
ZipUtil.pack(outputDir.toFile(), output);
} catch (Exception e) {
handleException(e);
} finally {
try {
FileUtils.deleteDirectory(outputDir.toFile());
} catch (IOException e) {
handleException(e);
}
try {
Files.delete(tempJar);
} catch (IOException e) {
handleException(e);
}
}
} catch (Exception e) {
e.printStackTrace(); //TODO How to handle exceptions again?
handleException(e);
}
}
public String[] generateMainMethod() {
return new String[]{
"bytecodeviewer",
"--decodeenumswitch",
String.valueOf(BytecodeViewer.viewer.decodeenumswitch
.isSelected()),
"--sugarenums",
String.valueOf(BytecodeViewer.viewer.sugarenums.isSelected()),
"--decodestringswitch",
String.valueOf(BytecodeViewer.viewer.decodestringswitch
.isSelected()),
"--arrayiter",
String.valueOf(BytecodeViewer.viewer.arrayiter.isSelected()),
"--collectioniter",
String.valueOf(BytecodeViewer.viewer.collectioniter
.isSelected()),
"--innerclasses",
String.valueOf(BytecodeViewer.viewer.innerclasses.isSelected()),
"--removeboilerplate",
String.valueOf(BytecodeViewer.viewer.removeboilerplate
.isSelected()),
"--removeinnerclasssynthetics",
String.valueOf(BytecodeViewer.viewer.removeinnerclasssynthetics
.isSelected()),
"--decodelambdas",
String.valueOf(BytecodeViewer.viewer.decodelambdas.isSelected()),
"--hidebridgemethods",
String.valueOf(BytecodeViewer.viewer.hidebridgemethods
.isSelected()),
"--liftconstructorinit",
String.valueOf(BytecodeViewer.viewer.liftconstructorinit
.isSelected()),
"--removedeadmethods",
String.valueOf(BytecodeViewer.viewer.removedeadmethods
.isSelected()),
"--removebadgenerics",
String.valueOf(BytecodeViewer.viewer.removebadgenerics
.isSelected()),
"--sugarasserts",
String.valueOf(BytecodeViewer.viewer.sugarasserts.isSelected()),
"--sugarboxing",
String.valueOf(BytecodeViewer.viewer.sugarboxing.isSelected()),
"--showversion",
String.valueOf(BytecodeViewer.viewer.showversion.isSelected()),
"--decodefinally",
String.valueOf(BytecodeViewer.viewer.decodefinally.isSelected()),
"--tidymonitors",
String.valueOf(BytecodeViewer.viewer.tidymonitors.isSelected()),
"--lenient",
String.valueOf(BytecodeViewer.viewer.lenient.isSelected()),
"--dumpclasspath",
String.valueOf(BytecodeViewer.viewer.dumpclasspath.isSelected()),
"--comments",
String.valueOf(BytecodeViewer.viewer.comments.isSelected()),
"--forcetopsort",
String.valueOf(BytecodeViewer.viewer.forcetopsort.isSelected()),
"--forcetopsortaggress",
String.valueOf(BytecodeViewer.viewer.forcetopsortaggress
.isSelected()),
"--stringbuffer",
String.valueOf(BytecodeViewer.viewer.stringbuffer.isSelected()),
"--stringbuilder",
String.valueOf(BytecodeViewer.viewer.stringbuilder.isSelected()),
"--silent",
String.valueOf(BytecodeViewer.viewer.silent.isSelected()),
"--recover",
String.valueOf(BytecodeViewer.viewer.recover.isSelected()),
"--eclipse",
String.valueOf(BytecodeViewer.viewer.eclipse.isSelected()),
"--override",
String.valueOf(BytecodeViewer.viewer.override.isSelected()),
"--showinferrable",
String.valueOf(BytecodeViewer.viewer.showinferrable
.isSelected()),
"--aexagg",
String.valueOf(BytecodeViewer.viewer.aexagg.isSelected()),
"--forcecondpropagate",
String.valueOf(BytecodeViewer.viewer.forcecondpropagate
.isSelected()),
"--hideutf",
String.valueOf(BytecodeViewer.viewer.hideutf.isSelected()),
"--hidelongstrings",
String.valueOf(BytecodeViewer.viewer.hidelongstrings
.isSelected()),
"--commentmonitors",
String.valueOf(BytecodeViewer.viewer.commentmonitor
.isSelected()),
"--allowcorrecting",
String.valueOf(BytecodeViewer.viewer.allowcorrecting
.isSelected()),
"--labelledblocks",
String.valueOf(BytecodeViewer.viewer.labelledblocks
.isSelected()),
"--j14classobj",
String.valueOf(BytecodeViewer.viewer.j14classobj.isSelected()),
"--hidelangimports",
String.valueOf(BytecodeViewer.viewer.hidelangimports
.isSelected()),
"--recovertypeclash",
String.valueOf(BytecodeViewer.viewer.recoverytypeclash
.isSelected()),
"--recovertypehints",
String.valueOf(BytecodeViewer.viewer.recoverytypehints
.isSelected()),
"--forcereturningifs",
String.valueOf(BytecodeViewer.viewer.forceturningifs
.isSelected()),
"--forloopaggcapture",
String.valueOf(BytecodeViewer.viewer.forloopaggcapture
.isSelected()),};
String[] result = new String[getSettings().size() * 2 + 1];
result[0] = "bytecodeviewer";
int index = 1;
for (Settings setting : Settings.values()) {
result[index++] = "--" + setting.getParam();
result[index++] = String.valueOf(getSettings().isSelected(setting));
}
return result;
}
public static String doClass(DCCommonState dcCommonState, byte[] content1) throws Exception {
@ -287,4 +216,76 @@ public class CFRDecompiler extends Decompiler {
}
}
}
public enum Settings implements DecompilerSettings.Setting {
DECODE_ENUM_SWITCH("decodeenumswitch", "Decode Enum Switch", true),
SUGAR_ENUMS("sugarenums", "SugarEnums", true),
DECODE_STRING_SWITCH("decodestringswitch", "Decode String Switch", true),
ARRAYITER("arrayiter", "Arrayiter", true),
COLLECTIONITER("collectioniter", "Collectioniter", true),
INNER_CLASSES("innerclasses", "Inner Classes", true),
REMOVE_BOILER_PLATE("removeboilerplate", "Remove Boiler Plate", true),
REMOVE_INNER_CLASS_SYNTHETICS("removeinnerclasssynthetics", "Remove Inner Class Synthetics", true),
DECODE_LAMBDAS("decodelambdas", "Decode Lambdas", true),
HIDE_BRIDGE_METHODS("hidebridgemethods", "Hide Bridge Methods", true),
LIFT_CONSTRUCTOR_INIT("liftconstructorinit", "Lift Constructor Init", true),
REMOVE_DEAD_METHODS("removedeadmethods", "Remove Dead Methods", true),
REMOVE_BAD_GENERICS("removebadgenerics", "Remove Bad Generics", true),
SUGAR_ASSERTS("sugarasserts", "Sugar Asserts", true),
SUGAR_BOXING("sugarboxing", "Sugar Boxing", true),
SHOW_VERSION("showversion", "Show Version", true),
DECODE_FINALLY("decodefinally", "Decode Finally", true),
TIDY_MONITORS("tidymonitors", "Tidy Monitors", true),
LENIENT("lenient", "Lenient"),
DUMP_CLASS_PATH("dumpclasspath", "Dump Classpath"),
COMMENTS("comments", "Comments", true),
FORCE_TOP_SORT("forcetopsort", "Force Top Sort", true),
FORCE_TOP_SORT_AGGRESSIVE("forcetopsortaggress", "Force Top Sort Aggressive", true),
STRINGBUFFER("stringbuffer", "StringBuffer"),
STRINGBUILDER("stringbuilder", "StringBuilder", true),
SILENT("silent", "Silent", true),
RECOVER("recover", "Recover", true),
ECLIPSE("eclipse", "Eclipse", true),
OVERRIDE("override", "Override", true),
SHOW_INFERRABLE("showinferrable", "Show Inferrable", true),
FORCE_AGGRESSIVE_EXCEPTION_AGG("aexagg", "Force Aggressive Exception Aggregation", true),
FORCE_COND_PROPAGATE("forcecondpropagate", "Force Conditional Propogation", true),
HIDE_UTF("hideutf", "Hide UTF", true),
HIDE_LONG_STRINGS("hidelongstrings", "Hide Long Strings"),
COMMENT_MONITORS("commentmonitors", "Comment Monitors"),
ALLOW_CORRECTING("allowcorrecting", "Allow Correcting", true),
LABELLED_BLOCKS("labelledblocks", "Labelled Blocks", true),
J14_CLASS_OBJ("j14classobj", "Java 1.4 Class Objects"),
HIDE_LANG_IMPORTS("hidelangimports", "Hide Lang Imports", true),
RECOVER_TYPE_CLASH("recovertypeclash", "Recover Type Clash", true),
RECOVER_TYPE_HINTS("recovertypehints", "Recover Type Hints", true),
FORCE_RETURNING_IFS("forcereturningifs", "Force Returning Ifs", true),
FOR_LOOP_AGG_CAPTURE("forloopaggcapture", "For Loop Aggressive Capture", true);
private String name;
private String param;
private boolean on;
Settings(String param, String name) {
this(param, name, false);
}
Settings(String param, String name, boolean on) {
this.name = name;
this.param = param;
this.on = on;
}
public String getText() {
return name;
}
public boolean isDefaultOn() {
return on;
}
public String getParam() {
return param;
}
}
}

View file

@ -1,44 +1,128 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.DecompilerSettings;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Used to represent all of the decompilers/disassemblers BCV contains.
*
*
* @author Konloch
*
*
*/
public abstract class Decompiler {
public final static Decompiler bytecode = new ClassNodeDecompiler();
public final static Decompiler fernflower = new FernFlowerDecompiler();
public final static Decompiler procyon = new ProcyonDecompiler();
public final static Decompiler cfr = new CFRDecompiler();
public final static Decompiler krakatau = new KrakatauDecompiler();
public final static Decompiler krakatauDA = new KrakatauDisassembler();
public final static Decompiler smali = new SmaliDisassembler();
public final static Decompiler jdgui = new JDGUIDecompiler();
public abstract String decompileClassNode(ClassNode cn, byte[] b);
public abstract void decompileToZip(String zipName);
private static final Map<String, Decompiler> BY_NAME = new HashMap<>();
public final static Decompiler BYTECODE = new ClassNodeDecompiler();
public final static Decompiler FERNFLOWER = new FernFlowerDecompiler();
public final static Decompiler PROCYON = new ProcyonDecompiler();
public final static Decompiler CFR = new CFRDecompiler();
public final static Decompiler KRAKATAU = new KrakatauDecompiler();
public final static Decompiler JDGUI = new JDGUIDecompiler();
public final static Decompiler KRAKATAU_DA = new KrakatauDisassembler();
public final static Decompiler SMALI = new SmaliDisassembler();
public final static Decompiler HEXCODE = new Decompiler() {
@Override
public String decompileClassNode(ClassNode cn, byte[] b) {
throw new IllegalArgumentException();
}
@Override
public void decompileToZip(String zipName) {
throw new IllegalArgumentException();
}
@Override
public String getName() {
return "Hexcode";
}
@Override
public DecompilerSettings getSettings() {
throw new IllegalArgumentException();
}
};
public Decompiler() {
BY_NAME.put(getName().toLowerCase().replace(' ', '-'), this);
}
protected DecompilerSettings settings = new DecompilerSettings(this);
public abstract String decompileClassNode(ClassNode cn, byte[] b);
public abstract void decompileToZip(String zipName);
public abstract String getName();
public DecompilerSettings getSettings() {
return settings;
}
protected String parseException(Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
return getName() + " encountered a problem! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl +
BytecodeViewer.nl +
"Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl +
BytecodeViewer.nl +
exception;
}
protected void handleException(Exception e) {
new ExceptionUI(e);
}
protected byte[] fixBytes(byte[] in) {
ClassReader reader = new ClassReader(in);
ClassNode node = new ClassNode();
reader.accept(node, ClassReader.EXPAND_FRAMES);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
node.accept(writer);
return writer.toByteArray();
}
public static void ensureInitted() {
// Just to make sure the classes is loaded so all decompilers are loaded
}
public static Decompiler getByName(String name) {
return BY_NAME.get(name.toLowerCase().replace(' ', '-'));
}
public static Collection<Decompiler> getAllDecompilers() {
return Collections.unmodifiableCollection(BY_NAME.values());
}
}

View file

@ -7,15 +7,14 @@ import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger;
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.DecompilerSettings;
import the.bytecode.club.bytecodeviewer.JarUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@ -48,74 +47,89 @@ import java.util.jar.Manifest;
public class FernFlowerDecompiler extends Decompiler {
public FernFlowerDecompiler() {
for (Settings setting : Settings.values()) {
settings.registerSetting(setting);
}
}
@Override
public String decompileClassNode(final ClassNode cn, final byte[] b) {
Map<String, Object> options = main(generateMainMethod());
final AtomicReference<String> result = new AtomicReference<String>();
result.set(null);
BaseDecompiler baseDecompiler = new BaseDecompiler(new IBytecodeProvider() {
@Override
public byte[] getBytecode(String s, String s1) throws IOException {
byte[] clone = new byte[b.length];
System.arraycopy(b, 0, clone, 0, b.length);
return clone;
}
}, new IResultSaver() {
@Override
public void saveFolder(String s) {
}
@Override
public void copyFile(String s, String s1, String s2) {
}
@Override
public void saveClassFile(String s, String s1, String s2, String s3, int[] ints) {
result.set(s3);
}
@Override
public void createArchive(String s, String s1, Manifest manifest) {
}
@Override
public void saveDirEntry(String s, String s1, String s2) {
}
@Override
public void copyEntry(String s, String s1, String s2, String s3) {
}
@Override
public void saveClassEntry(String s, String s1, String s2, String s3, String s4) {
}
@Override
public void closeArchive(String s, String s1) {
}
}, options, new PrintStreamLogger(System.out));
public String getName() {
return "FernFlower";
}
@Override
public String decompileClassNode(final ClassNode cn, byte[] b) {
try {
baseDecompiler.addSpace(new File("fernflower.class"), true);
baseDecompiler.decompileContext();
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
if (result.get() != null) {
break;
if (cn.version < 49) {
b = fixBytes(b);
}
final byte[] bytesToUse = b;
Map<String, Object> options = main(generateMainMethod());
final AtomicReference<String> result = new AtomicReference<String>();
result.set(null);
BaseDecompiler baseDecompiler = new BaseDecompiler(new IBytecodeProvider() {
@Override
public byte[] getBytecode(String s, String s1) throws IOException {
byte[] clone = new byte[bytesToUse.length];
System.arraycopy(bytesToUse, 0, clone, 0, bytesToUse.length);
return clone;
}
}, new IResultSaver() {
@Override
public void saveFolder(String s) {
}
@Override
public void copyFile(String s, String s1, String s2) {
}
@Override
public void saveClassFile(String s, String s1, String s2, String s3, int[] ints) {
result.set(s3);
}
@Override
public void createArchive(String s, String s1, Manifest manifest) {
}
@Override
public void saveDirEntry(String s, String s1, String s2) {
}
@Override
public void copyEntry(String s, String s1, String s2, String s3) {
}
@Override
public void saveClassEntry(String s, String s1, String s2, String s3, String s4) {
}
@Override
public void closeArchive(String s, String s1) {
}
}, options, new PrintStreamLogger(System.out));
baseDecompiler.addSpace(new File(cn.name + ".class"), true);
baseDecompiler.decompileContext();
while (true) {
if (result.get() != null) {
break;
}
}
return result.get();
} catch (Exception e) {
return parseException(e);
}
return result.get();
}
@Override
@ -132,7 +146,7 @@ public class FernFlowerDecompiler extends Decompiler {
Files.delete(tempJar);
FileUtils.deleteDirectory(outputDir.toFile());
} catch (Exception e) {
e.printStackTrace();
handleException(e);
}
}
@ -160,29 +174,62 @@ public class FernFlowerDecompiler extends Decompiler {
}
private String[] generateMainMethod() {
return new String[]{
"-rbr=" + r(BytecodeViewer.viewer.rbr.isSelected()),
"-rsy=" + r(BytecodeViewer.viewer.rsy.isSelected()),
"-din=" + r(BytecodeViewer.viewer.din.isSelected()),
"-dc4=" + r(BytecodeViewer.viewer.dc4.isSelected()),
"-das=" + r(BytecodeViewer.viewer.das.isSelected()),
"-hes=" + r(BytecodeViewer.viewer.hes.isSelected()),
"-hdc=" + r(BytecodeViewer.viewer.hdc.isSelected()),
"-dgs=" + r(BytecodeViewer.viewer.dgs.isSelected()),
"-ner=" + r(BytecodeViewer.viewer.ner.isSelected()),
"-den=" + r(BytecodeViewer.viewer.den.isSelected()),
"-rgn=" + r(BytecodeViewer.viewer.rgn.isSelected()),
"-bto=" + r(BytecodeViewer.viewer.bto.isSelected()),
"-nns=" + r(BytecodeViewer.viewer.nns.isSelected()),
"-uto=" + r(BytecodeViewer.viewer.uto.isSelected()),
"-udv=" + r(BytecodeViewer.viewer.udv.isSelected()),
"-rer=" + r(BytecodeViewer.viewer.rer.isSelected()),
"-fdi=" + r(BytecodeViewer.viewer.fdi.isSelected()),
"-asc=" + r(BytecodeViewer.viewer.asc.isSelected())
};
String[] result = new String[getSettings().size()];
int index = 0;
for (Settings setting : Settings.values()) {
result[index++] = String.format("-%s=%s", setting.getParam(), getSettings().isSelected(setting) ? "1" : "0");
}
return result;
}
private String r(boolean b) {
return b ? "1" : "0";
public enum Settings implements DecompilerSettings.Setting {
HIDE_BRIDGE_METHODS("rbr", "Hide Bridge Methods", true),
HIDE_SYNTHETIC_CLASS_MEMBERS("rsy", "Hide Synthetic Class Members"),
DECOMPILE_INNER_CLASSES("din", "Decompile Inner Classes", true),
COLLAPSE_14_CLASS_REFERENCES("dc4", "Collapse 1.4 Class References", true),
DECOMPILE_ASSERTIONS("das", "Decompile Assertions", true),
HIDE_EMPTY_SUPER_INVOCATION("hes", "Hide Empty Super Invocation", true),
HIDE_EMPTY_DEFAULT_CONSTRUCTOR("hec", "Hide Empty Default Constructor", true),
DECOMPILE_GENERIC_SIGNATURES("dgs", "Decompile Generic Signatures"),
ASSUME_RETURN_NOT_THROWING_EXCEPTIONS("ner", "Assume return not throwing exceptions", true),
DECOMPILE_ENUMS("den", "Decompile enumerations", true),
REMOVE_GETCLASS("rgn", "Remove getClass()", true),
OUTPUT_NUMBERIC_LITERALS("lit", "Output numeric literals 'as-is'"),
ENCODE_UNICODE("asc", "Encode non-ASCII as unicode escapes"),
INT_1_AS_BOOLEAN_TRUE("bto", "Assume int 1 is boolean true", true),
ALLOW_NOT_SET_SYNTHETIC("nns", "Allow not set synthetic attribute", true),
NAMELESS_TYPES_AS_OBJECT("uto", "Consider nameless types as java.lang.Object", true),
RECOVER_VARIABLE_NAMES("udv", "Recover variable names", true),
REMOVE_EMPTY_EXCEPTIONS("rer", "Remove empty exceptions", true),
DEINLINE_FINALLY("fdi", "De-inline finally", true),
RENAME_AMBIGIOUS_MEMBERS("ren", "Rename ambigious members"),
REMOVE_INTELLIJ_NOTNULL("inn", "Remove IntelliJ @NotNull", true),
DECOMPILE_LAMBDA_TO_ANONYMOUS("lac", "Decompile lambdas to anonymous classes");
private String name;
private String param;
private boolean on;
Settings(String param, String name) {
this(param, name, false);
}
Settings(String param, String name, boolean on) {
this.name = name;
this.param = param;
this.on = on;
}
public String getText() {
return name;
}
public boolean isDefaultOn() {
return on;
}
public String getParam() {
return param;
}
}
}

View file

@ -4,21 +4,33 @@ import jd.cli.preferences.CommonPreferences;
import jd.cli.printer.text.PlainTextPrinter;
import jd.core.loader.Loader;
import jd.core.loader.LoaderException;
import jd.core.model.classfile.ClassFile;
import jd.core.model.classfile.ConstantPool;
import jd.core.model.classfile.attribute.AttributeInnerClasses;
import jd.core.model.classfile.attribute.InnerClass;
import jd.core.model.reference.ReferenceMap;
import jd.core.preferences.Preferences;
import jd.core.printer.Printer;
import jd.core.process.DecompilerImpl;
import org.apache.commons.io.FileUtils;
import org.benf.cfr.reader.state.ClassFileSourceImpl;
import org.benf.cfr.reader.state.DCCommonState;
import org.benf.cfr.reader.util.getopt.GetOptParser;
import org.benf.cfr.reader.util.getopt.Options;
import org.benf.cfr.reader.util.getopt.OptionsImpl;
import jd.core.process.analyzer.classfile.ClassFileAnalyzer;
import jd.core.process.analyzer.classfile.ReferenceAnalyzer;
import jd.core.process.deserializer.ClassFileDeserializer;
import jd.core.process.layouter.ClassFileLayouter;
import jd.core.process.writer.ClassFileWriter;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@ -46,23 +58,25 @@ import java.util.zip.ZipOutputStream;
*
* @author Konloch
* @author JD-Core developers
*
*/
public class JDGUIDecompiler extends Decompiler {
@Override
public String getName() {
return "JDGUI";
}
@Override
public String decompileClassNode(ClassNode cn, final byte[] b) {
public String decompileClassNode(ClassNode cn, byte[] b) {
try {
if (cn.version < 49) {
b = fixBytes(b);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
decompile(b, outputStream);
return outputStream.toString("UTF-8");
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
String exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception;
return parseException(e);
}
}
@ -92,7 +106,7 @@ public class JDGUIDecompiler extends Decompiler {
}
zipOutputStream.close();
} catch (Exception e) {
e.printStackTrace(); //TODO How to handle exceptions again?
handleException(e);
}
}
@ -119,6 +133,7 @@ public class JDGUIDecompiler extends Decompiler {
return true;
}
};
new DecompilerImpl().decompile(preferences, customLoader, new PlainTextPrinter(preferences, new PrintStream(to, false, "UTF-8")), "BytecodeViewer.class");
}
}

View file

@ -1,185 +1,179 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.Settings;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Krakatau Java Decompiler Wrapper, requires Python 2.7
*
* @author Konloch
*
* @author Konloch
*/
public class KrakatauDecompiler extends Decompiler {
@Override
public String getName() {
return "Krakatau";
}
public String quick() {
if(BytecodeViewer.library.isEmpty())
return "";
else
return ";"+BytecodeViewer.library;
}
public String decompileClassNode(ClassNode cn, byte[] b) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
public String quick() {
if (Settings.PATH.isEmpty()) return "";
else return ";" + Settings.PATH.get();
}
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set Python!");
return "Set your paths";
}
public String decompileClassNode(ClassNode cn, byte[] b) {
if (Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if (Settings.RT_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set RT.jar!");
return "Set your paths";
}
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-skip", //love you storyyeller <3
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath()+quick(),
"-out",
tempDirectory.getAbsolutePath(),
cn.name+".class"
);
if (Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set Python!");
return "Set your paths";
}
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String log = "Process:"+BytecodeViewer.nl+BytecodeViewer.nl;
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
if (Settings.RT_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set RT.jar!");
return "Set your paths";
}
log += BytecodeViewer.nl+BytecodeViewer.nl+"Error:"+BytecodeViewer.nl+BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
s = log;
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".java");
tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
s += BytecodeViewer.nl+"Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
} finally {
BytecodeViewer.sm.setBlocking();
}
return s;
}
public void decompileToZip(String zipName) {
if(BytecodeViewer.python.equals("")) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.rt.equals("")) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
String ran = MiscUtils.randomString(32);
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "decompile.py",
"-skip", //love you storyyeller <3
"-nauto",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
tempJar.getAbsolutePath()
);
try {
final Path outputJar = Files.createTempFile("kdeout", ".zip");
final Path inputJar = Files.createTempFile("kdein", ".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), inputJar.toAbsolutePath().toString());
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
process.waitFor();
MiscUtils.printProcess(process);
// ZipUtils.zipDirectory(tempDirectory, new File(zipName));
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
//tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.sm.setBlocking();
}
}
BytecodeViewer.sm.stopBlocking();
ProcessBuilder pb = new ProcessBuilder(Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3
BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Settings.RT_LOCATION.get() + ";" + inputJar.toAbsolutePath().toString() + quick(), "-out", outputJar.toAbsolutePath().toString(), cn.name + ".class");
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String log = "Process:" + BytecodeViewer.nl + BytecodeViewer.nl;
String line;
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
log += BytecodeViewer.nl + BytecodeViewer.nl + "Error:" + BytecodeViewer.nl + BytecodeViewer.nl;
is = process.getErrorStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
log += BytecodeViewer.nl + line;
}
br.close();
int exitValue = process.waitFor();
log += BytecodeViewer.nl + BytecodeViewer.nl + "Exit Value is " + exitValue;
s = log;
ZipFile zipFile= new ZipFile(outputJar.toFile());
Enumeration<? extends ZipEntry> entries = zipFile.entries();
byte[] data = null;
while (entries.hasMoreElements()) {
ZipEntry next = entries.nextElement();
if (next.getName().equals(cn.name + ".java")) {
data = IOUtils.toByteArray(zipFile.getInputStream(next));
}
}
zipFile.close();
Files.delete(inputJar);
Files.delete(outputJar);
return new String(data, "UTF-8");
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
s += BytecodeViewer.nl + "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
} finally {
BytecodeViewer.sm.setBlocking();
}
return s;
}
public void decompileToZip(String zipName) {
if (Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if (Settings.RT_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your JRE RT Library.\r\n(C:\\Program Files (x86)\\Java\\jre7\\lib\\rt.jar)");
BytecodeViewer.viewer.rtC();
}
try {
File tempDir = Files.createTempDirectory("krakatauoutput").toFile();
File tempJar = new File(tempDir, "temp.jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
ProcessBuilder pb = new ProcessBuilder(Settings.PYTHON2_LOCATION.get(), "-O", //love you storyyeller <3
BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "decompile.py", "-skip", //love you storyyeller <3
"-nauto", "-path", Settings.RT_LOCATION.get() + ";" + tempJar.getAbsolutePath(), "-out", tempDir.getAbsolutePath(), tempJar.getAbsolutePath());
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
MiscUtils.printProcess(process);
process.waitFor();
tempJar.delete();
ZipUtil.pack(tempDir, new File(zipName));
FileUtils.deleteDirectory(tempDir);
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
} finally {
BytecodeViewer.sm.setBlocking();
}
}
}

View file

@ -1,20 +1,25 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.Settings;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -36,47 +41,49 @@ import the.bytecode.club.bytecodeviewer.ZipUtils;
/**
* Krakatau Java Disassembler Wrapper, requires Python 2.7
*
*
* @author Konloch
*
*/
public class KrakatauDisassembler extends Decompiler {
@Override
public String getName() {
return "Krakatau Disassembler";
}
public String decompileClassNode(ClassNode cn, byte[] b) {
if(BytecodeViewer.python.equals("")) {
if(Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
if(BytecodeViewer.python.equals("")) {
if(Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set Python!");
return "Set your paths";
}
String s = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + "Please send this to konloch@gmail.com. " + BytecodeViewer.nl + BytecodeViewer.nl;
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + MiscUtils.randomString(32) + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"+MiscUtils.randomString(32)+".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
try {
final Path outputJar = Files.createTempFile("kdisout", ".zip");
final Path inputJar = Files.createTempFile("kdisin", ".jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), inputJar.toAbsolutePath().toString());
BytecodeViewer.sm.stopBlocking();
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
Settings.PYTHON2_LOCATION.get(),
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "disassemble.py",
BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "disassemble.py",
"-path",
tempJar.getAbsolutePath(),
inputJar.toAbsolutePath().toString(),
"-out",
tempDirectory.getAbsolutePath(),
outputJar.toAbsolutePath().toString(),
cn.name+".class"
);
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
//Read out dir output
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
@ -96,15 +103,24 @@ public class KrakatauDisassembler extends Decompiler {
log += BytecodeViewer.nl + line;
}
br.close();
int exitValue = process.waitFor();
log += BytecodeViewer.nl+BytecodeViewer.nl+"Exit Value is " + exitValue;
s = log;
//if the motherfucker failed this'll fail, aka wont set.
s = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + BytecodeViewer.fs + cn.name + ".j");
tempDirectory.delete();
tempJar.delete();
ZipFile zipFile= new ZipFile(outputJar.toFile());
Enumeration<? extends ZipEntry> entries = zipFile.entries();
byte[] data = null;
while (entries.hasMoreElements()) {
ZipEntry next = entries.nextElement();
if (next.getName().equals(cn.name + ".j")) {
data = IOUtils.toByteArray(zipFile.getInputStream(next));
}
}
zipFile.close();
Files.delete(inputJar);
Files.delete(outputJar);
return new String(data, "UTF-8");
} catch(Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
@ -117,25 +133,25 @@ public class KrakatauDisassembler extends Decompiler {
}
@Override public void decompileToZip(String zipName) {
if(BytecodeViewer.python.equals("")) {
if(Settings.PYTHON2_LOCATION.isEmpty()) {
BytecodeViewer.showMessage("You need to set your Python (or PyPy for speed) 2.7 executable path.");
BytecodeViewer.viewer.pythonC();
}
String ran = MiscUtils.randomString(32);
final File tempDirectory = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + ran + BytecodeViewer.fs);
final File tempDirectory = new File(BytecodeViewer.tempDir, ran + BytecodeViewer.fs);
tempDirectory.mkdir();
final File tempJar = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath());
final File tempJar = new File(BytecodeViewer.tempDir, "temp.jar");
JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedBytes(), tempJar.getAbsolutePath());
BytecodeViewer.sm.stopBlocking();
try {
ProcessBuilder pb = new ProcessBuilder(
BytecodeViewer.python,
Settings.PYTHON2_LOCATION.get(),
"-O", //love you storyyeller <3
BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.fs + "disassemble.py",
BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.fs + "disassemble.py",
"-path",
BytecodeViewer.rt+";"+tempJar.getAbsolutePath(),
Settings.RT_LOCATION.get()+";"+tempJar.getAbsolutePath(),
"-out",
tempDirectory.getAbsolutePath(),
tempJar.getAbsolutePath()
@ -144,10 +160,9 @@ public class KrakatauDisassembler extends Decompiler {
Process process = pb.start();
BytecodeViewer.createdProcesses.add(process);
process.waitFor();
// ZipUtils.zipDirectory(tempDirectory, new File(zipName));
ZipUtils.zipFolder(tempDirectory.getAbsolutePath(), zipName, ran);
ZipUtil.pack(tempDirectory, new File(zipName));
//tempDirectory.delete();
tempJar.delete();
} catch(Exception e) {

View file

@ -1,19 +1,34 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import com.beust.jcommander.JCommander;
import com.strobel.assembler.InputTypeLoader;
import com.strobel.assembler.metadata.*;
import com.strobel.assembler.metadata.Buffer;
import com.strobel.assembler.metadata.ITypeLoader;
import com.strobel.assembler.metadata.JarTypeLoader;
import com.strobel.assembler.metadata.MetadataSystem;
import com.strobel.assembler.metadata.TypeDefinition;
import com.strobel.assembler.metadata.TypeReference;
import com.strobel.core.StringUtilities;
import com.strobel.decompiler.CommandLineOptions;
import com.strobel.decompiler.DecompilationOptions;
import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput;
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
import com.strobel.decompiler.languages.Languages;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import java.io.*;
import java.util.*;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
@ -42,126 +57,127 @@ import java.util.zip.ZipOutputStream;
*
* @author Konloch
* @author DeathMarine
*
*/
public class ProcyonDecompiler extends Decompiler {
public ProcyonDecompiler() {
for (Settings setting : Settings.values()) {
settings.registerSetting(setting);
}
}
@Override
public String getName() {
return "Procyon";
}
public DecompilerSettings getDecompilerSettings() {
CommandLineOptions options = new CommandLineOptions();
JCommander jCommander = new JCommander(options);
String[] args = new String[Settings.values().length * 2];
int index = 0;
for (the.bytecode.club.bytecodeviewer.DecompilerSettings.Setting setting : Settings.values()) {
args[index++] = "--" + setting.getParam();
args[index++] = String.valueOf(getSettings().isSelected(setting));
}
jCommander.parse(args);
DecompilerSettings settings = new DecompilerSettings();
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6
.isSelected());
settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11
.isSelected());
settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine
.isSelected());
settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3
.isSelected());
settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4
.isSelected());
settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7
.isSelected());
settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences
.isSelected());
settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables
.isSelected());
settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8
.isSelected());
settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9
.isSelected());
settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10
.isSelected());
settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2
.isSelected());
settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5
.isSelected());
settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1
.isSelected());
settings.setFormattingOptions(JavaFormattingOptions.createDefault());
settings.setFlattenSwitchBlocks(options.getFlattenSwitchBlocks());
settings.setForceExplicitImports(!options.getCollapseImports());
settings.setForceExplicitTypeArguments(options.getForceExplicitTypeArguments());
settings.setRetainRedundantCasts(options.getRetainRedundantCasts());
settings.setShowSyntheticMembers(options.getShowSyntheticMembers());
settings.setExcludeNestedTypes(options.getExcludeNestedTypes());
settings.setOutputDirectory(options.getOutputDirectory());
settings.setIncludeLineNumbersInBytecode(options.getIncludeLineNumbers());
settings.setRetainPointlessSwitches(options.getRetainPointlessSwitches());
settings.setUnicodeOutputEnabled(options.isUnicodeOutputEnabled());
settings.setMergeVariables(options.getMergeVariables());
settings.setShowDebugLineNumbers(options.getShowDebugLineNumbers());
settings.setSimplifyMemberReferences(options.getSimplifyMemberReferences());
settings.setDisableForEachTransforms(options.getDisableForEachTransforms());
settings.setTypeLoader(new InputTypeLoader());
if (options.isRawBytecode()) {
settings.setLanguage(Languages.bytecode());
} else if (options.isBytecodeAst()) {
settings.setLanguage(options.isUnoptimized() ? Languages.bytecodeAstUnoptimized() : Languages.bytecodeAst());
}
return settings;
}
@Override
public String decompileClassNode(ClassNode cn, final byte[] b) {
String exception = "";
public String decompileClassNode(final ClassNode cn, byte[] b) {
try {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp";
final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class");
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
fos.write(b);
fos.close();
} catch (final IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
if (cn.version < 49) {
b = fixBytes(b);
}
final byte[] bytesToUse = b;
final Map<String, byte[]> loadedClasses = BytecodeViewer.getLoadedBytes();
DecompilerSettings settings = getDecompilerSettings();
MetadataSystem metadataSystem = new MetadataSystem(new InputTypeLoader());
TypeReference type = metadataSystem.lookupType(tempClass.getCanonicalPath());
MetadataSystem metadataSystem = new MetadataSystem(new ITypeLoader() {
private InputTypeLoader backLoader = new InputTypeLoader();
@Override
public boolean tryLoadType(String s, Buffer buffer) {
if (s.equals(cn.name)) {
buffer.putByteArray(bytesToUse, 0, bytesToUse.length);
buffer.position(0);
return true;
} else {
byte[] toUse = loadedClasses.get(s + ".class");
if (toUse != null) {
buffer.putByteArray(toUse, 0, toUse.length);
buffer.position(0);
return true;
} else {
return backLoader.tryLoadType(s, buffer);
}
}
}
});
TypeReference type = metadataSystem.lookupType(cn.name);
DecompilationOptions decompilationOptions = new DecompilationOptions();
decompilationOptions.setSettings(DecompilerSettings.javaDefaults());
decompilationOptions.setFullDecompilation(true);
TypeDefinition resolvedType = null;
if (type == null || ((resolvedType = type.resolve()) == null)) {
throw new Exception("Unable to resolve type.");
}
StringWriter stringwriter = new StringWriter();
settings.getLanguage().decompileType(resolvedType,
new PlainTextOutput(stringwriter), decompilationOptions);
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions);
String decompiledSource = stringwriter.toString();
return decompiledSource;
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
e.printStackTrace();
exception = "Bytecode Viewer Version: " + BytecodeViewer.version + BytecodeViewer.nl + BytecodeViewer.nl + sw.toString();
} catch (Throwable e) {
return parseException(e);
}
return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com" + BytecodeViewer.nl + BytecodeViewer.nl + "Suggested Fix: Click refresh class, if it fails again try another decompiler." + BytecodeViewer.nl + BytecodeViewer.nl + exception;
}
@Override
public void decompileToZip(String zipName) {
File tempZip = new File(BytecodeViewer.tempDirectory
+ BytecodeViewer.fs + "temp.jar");
if (tempZip.exists())
tempZip.delete();
File tempZip = new File(BytecodeViewer.tempDir, "temp.jar");
if (tempZip.exists()) tempZip.delete();
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(),
tempZip.getAbsolutePath());
JarUtils.saveAsJar(BytecodeViewer.getLoadedBytes(), tempZip.getAbsolutePath());
try {
doSaveJarDecompiled(tempZip, new File(zipName));
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
handleException(e);
}
}
/**
*
* @author DeathMarine
*
*/
private void doSaveJarDecompiled(File inFile, File outFile)
throws Exception {
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception {
try (JarFile jfile = new JarFile(inFile);
FileOutputStream dest = new FileOutputStream(outFile);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest);) {
byte data[] = new byte[1024];
DecompilerSettings settings = getDecompilerSettings();
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
ITypeLoader jarLoader = new JarTypeLoader(jfile);
typeLoader.getTypeLoaders().add(jarLoader);
MetadataSystem metadataSystem = new MetadataSystem(new JarTypeLoader(jfile));
DecompilationOptions decompilationOptions = new DecompilationOptions();
decompilationOptions.setSettings(settings);
@ -172,24 +188,18 @@ public class ProcyonDecompiler extends Decompiler {
while (ent.hasMoreElements()) {
JarEntry entry = ent.nextElement();
if (entry.getName().endsWith(".class")) {
JarEntry etn = new JarEntry(entry.getName().replace(
".class", ".java"));
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
if (history.add(etn)) {
out.putNextEntry(etn);
try {
String internalName = StringUtilities.removeRight(
entry.getName(), ".class");
TypeReference type = metadataSystem
.lookupType(internalName);
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
TypeReference type = metadataSystem.lookupType(internalName);
TypeDefinition resolvedType = null;
if ((type == null)
|| ((resolvedType = type.resolve()) == null)) {
if ((type == null) || ((resolvedType = type.resolve()) == null)) {
throw new Exception("Unable to resolve type.");
}
Writer writer = new OutputStreamWriter(out);
settings.getLanguage().decompileType(resolvedType,
new PlainTextOutput(writer),
decompilationOptions);
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
writer.flush();
} finally {
out.closeEntry();
@ -198,8 +208,7 @@ public class ProcyonDecompiler extends Decompiler {
} else {
try {
JarEntry etn = new JarEntry(entry.getName());
if (history.add(etn))
continue;
if (history.add(etn)) continue;
history.add(etn);
out.putNextEntry(etn);
try {
@ -229,36 +238,44 @@ public class ProcyonDecompiler extends Decompiler {
}
}
/**
*
* @author DeathMarine
*
*/
public final class LuytenTypeLoader implements ITypeLoader {
private final List<ITypeLoader> _typeLoaders;
public enum Settings implements the.bytecode.club.bytecodeviewer.DecompilerSettings.Setting {
SHOW_DEBUG_LINE_NUMBERS("debug-line-numbers", "Show Debug Line Numbers"),
SIMPLIFY_MEMBER_REFERENCES("simplify-member-references", "Simplify Member References"),
MERGE_VARIABLES("merge-variables", "Merge Variables"),
UNICODE_OUTPUT("unicode", "Allow Unicode Output"),
RETAIN_POINTLESS_SWITCHES("retain-pointless-switches", "Retain pointless switches"),
INCLUDE_LINE_NUMBERS_IN_BYTECODE("with-line-numbers", "Include line numbers in bytecode"),
RETAIN_REDUNDANT_CASTS("retain-explicit-casts", "Retain redundant casts"),
SHOW_SYNTHETIC_MEMBERS("show-synthetic", "Show synthetic members"),
FORCE_EXPLICIT_TYPE_ARGS("explicit-type-arguments", "Force explicit type arguments"),
FORCE_EXPLICIT_IMPORTS("explicit-imports", "Force explicit imports"),
FLATTEN_SWITCH_BLOCKS("flatten-switch-blocks", "Flatten switch blocks"),
EXCLUDE_NESTED_TYPES("exclude-nested", "Exclude nested types");
public LuytenTypeLoader() {
_typeLoaders = new ArrayList<ITypeLoader>();
_typeLoaders.add(new InputTypeLoader());
private String name;
private String param;
private boolean on;
Settings(String param, String name) {
this(param, name, false);
}
public final List<ITypeLoader> getTypeLoaders() {
return _typeLoaders;
Settings(String param, String name, boolean on) {
this.name = name;
this.param = param;
this.on = on;
}
@Override
public boolean tryLoadType(final String internalName,
final Buffer buffer) {
for (final ITypeLoader typeLoader : _typeLoaders) {
if (typeLoader.tryLoadType(internalName, buffer)) {
return true;
}
public String getText() {
return name;
}
buffer.reset();
}
public boolean isDefaultOn() {
return on;
}
return false;
public String getParam() {
return param;
}
}
}

View file

@ -1,100 +1,103 @@
package the.bytecode.club.bytecodeviewer.decompilers;
import org.apache.commons.io.FileUtils;
import org.objectweb.asm.tree.ClassNode;
import org.zeroturnaround.zip.ZipUtil;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Dex2Jar;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Dex2Jar;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.ZipUtils;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Smali Disassembler Wrapper
*
*
* @author Konloch
*
*/
public class SmaliDisassembler extends Decompiler {
public String decompileClassNode(ClassNode cn, byte[] b) {
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs
+ "temp";
String start = MiscUtils.getUniqueName(fileStart, ".class");
@Override
public String getName() {
return "Smali";
}
final File tempClass = new File(start + ".class");
final File tempZip = new File(start + ".jar");
final File tempDex = new File(start + ".dex");
final File tempSmali = new File(start + "-smali"); //output directory
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
public String decompileClassNode(ClassNode cn, byte[] b) {
String fileStart = BytecodeViewer.tempDir.getAbsolutePath()+ BytecodeViewer.fs
+ "temp";
fos.write(b);
String start = MiscUtils.getUniqueName(fileStart, ".class");
fos.close();
} catch (final IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
ZipUtils.zipFile(tempClass, tempZip);
final File tempClass = new File(start + ".class");
final File tempZip = new File(start + ".jar");
final File tempDex = new File(start + ".dex");
final File tempSmali = new File(start + "-smali"); //output directory
Dex2Jar.saveAsDex(tempZip, tempDex);
try {
org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()});
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
File outputSmali = null;
boolean found = false;
File current = tempSmali;
while(!found) {
File f = current.listFiles()[0];
if(f.isDirectory())
current = f;
else {
outputSmali = f;
found = true;
}
}
try {
return DiskReader.loadAsString(outputSmali.getAbsolutePath());
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;
}
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
@Override public void decompileToZip(String zipName) {
}
fos.write(b);
fos.close();
} catch (final IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
ZipUtil.packEntry(tempClass, tempZip);
Dex2Jar.saveAsDex(tempZip, tempDex);
try {
org.jf.baksmali.main.main(new String[]{"-o", tempSmali.getAbsolutePath(), "-x", tempDex.getAbsolutePath()});
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
File outputSmali = null;
boolean found = false;
File current = tempSmali;
while (!found) {
File f = current.listFiles()[0];
if (f.isDirectory())
current = f;
else {
outputSmali = f;
found = true;
}
}
try {
return FileUtils.readFileToString(outputSmali, "UTF-8");
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return null;
}
@Override
public void decompileToZip(String zipName) {
}
}

View file

@ -1,159 +1,188 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InnerClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.DecompilerSettings;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import java.util.ArrayList;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
*
*
* @author Konloch
* @author Bibl
*
*
*/
public class ClassNodeDecompiler extends Decompiler {
public String decompileClassNode(ClassNode cn, byte[] b) {
return decompile(new PrefixedStringBuilder(),
new ArrayList<String>(), cn).toString();
}
public ClassNodeDecompiler() {
for (Settings setting : Settings.values()) {
settings.registerSetting(setting);
}
}
protected static PrefixedStringBuilder decompile(
PrefixedStringBuilder sb, ArrayList<String> decompiledClasses,
ClassNode cn) {
ArrayList<String> unableToDecompile = new ArrayList<String>();
decompiledClasses.add(cn.name);
sb.append(getAccessString(cn.access));
sb.append(" ");
sb.append(cn.name);
if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
sb.append(" extends ");
sb.append(cn.superName);
}
@Override
public String getName() {
return "Bytecode";
}
int amountOfInterfaces = cn.interfaces.size();
if (amountOfInterfaces > 0) {
sb.append(" implements ");
sb.append(cn.interfaces.get(0));
if (amountOfInterfaces > 1) {
// sb.append(",");
}
for (int i = 1; i < amountOfInterfaces; i++) {
sb.append(", ");
sb.append(cn.interfaces.get(i));
}
}
sb.append(" {");
sb.append(BytecodeViewer.nl);
for (FieldNode fn : (List<FieldNode>) cn.fields) {
sb.append(BytecodeViewer.nl);
sb.append(" ");
FieldNodeDecompiler.decompile(sb, fn);
}
if (cn.fields.size() > 0) {
sb.append(BytecodeViewer.nl);
}
for (MethodNode mn : (List<MethodNode>) cn.methods) {
sb.append(BytecodeViewer.nl);
MethodNodeDecompiler.decompile(sb, mn, cn);
}
public String decompileClassNode(ClassNode cn, byte[] b) {
return decompile(new PrefixedStringBuilder(), new ArrayList<String>(), cn).toString();
}
for (Object o : cn.innerClasses) {
InnerClassNode innerClassNode = (InnerClassNode) o;
String innerClassName = innerClassNode.name;
if ((innerClassName != null)
&& !decompiledClasses.contains(innerClassName)) {
decompiledClasses.add(innerClassName);
ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName);
if (cn1 != null) {
sb.appendPrefix(" ");
sb.append(BytecodeViewer.nl + BytecodeViewer.nl);
sb = decompile(sb, decompiledClasses, cn1);
sb.trimPrefix(5);
sb.append(BytecodeViewer.nl);
} else {
unableToDecompile.add(innerClassName);
}
}
}
protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, ArrayList<String> decompiledClasses, ClassNode cn) {
ArrayList<String> unableToDecompile = new ArrayList<String>();
decompiledClasses.add(cn.name);
sb.append(getAccessString(cn.access));
sb.append(" ");
sb.append(cn.name);
if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
sb.append(" extends ");
sb.append(cn.superName);
}
if (!unableToDecompile.isEmpty()) {
sb.append("//the following inner classes couldn't be decompiled: ");
for (String s : unableToDecompile) {
sb.append(s);
sb.append(" ");
}
sb.append(BytecodeViewer.nl);
}
int amountOfInterfaces = cn.interfaces.size();
if (amountOfInterfaces > 0) {
sb.append(" implements ");
sb.append(cn.interfaces.get(0));
if (amountOfInterfaces > 1) {
// sb.append(",");
}
for (int i = 1; i < amountOfInterfaces; i++) {
sb.append(", ");
sb.append(cn.interfaces.get(i));
}
}
sb.append(" {");
sb.append(BytecodeViewer.nl);
for (FieldNode fn : (List<FieldNode>) cn.fields) {
sb.append(BytecodeViewer.nl);
sb.append(" ");
FieldNodeDecompiler.decompile(sb, fn);
}
if (cn.fields.size() > 0) {
sb.append(BytecodeViewer.nl);
}
for (MethodNode mn : (List<MethodNode>) cn.methods) {
sb.append(BytecodeViewer.nl);
MethodNodeDecompiler.decompile(sb, mn, cn);
}
sb.append("}");
// System.out.println("Wrote end for " + cn.name +
// " with prefix length: " + sb.prefix.length());
return sb;
}
for (Object o : cn.innerClasses) {
InnerClassNode innerClassNode = (InnerClassNode) o;
String innerClassName = innerClassNode.name;
if ((innerClassName != null) && !decompiledClasses.contains(innerClassName)) {
decompiledClasses.add(innerClassName);
ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName);
if (cn1 != null) {
sb.appendPrefix(" ");
sb.append(BytecodeViewer.nl + BytecodeViewer.nl);
sb = decompile(sb, decompiledClasses, cn1);
sb.trimPrefix(5);
sb.append(BytecodeViewer.nl);
} else {
unableToDecompile.add(innerClassName);
}
}
}
public static String getAccessString(int access) {
List<String> tokens = new ArrayList<String>();
if ((access & Opcodes.ACC_PUBLIC) != 0)
tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0)
tokens.add("private");
if ((access & Opcodes.ACC_PROTECTED) != 0)
tokens.add("protected");
if ((access & Opcodes.ACC_FINAL) != 0)
tokens.add("final");
if ((access & Opcodes.ACC_SYNTHETIC) != 0)
tokens.add("synthetic");
// if ((access & Opcodes.ACC_SUPER) != 0)
// tokens.add("super"); implied by invokespecial insn
if ((access & Opcodes.ACC_ABSTRACT) != 0)
tokens.add("abstract");
if ((access & Opcodes.ACC_INTERFACE) != 0)
tokens.add("interface");
if ((access & Opcodes.ACC_ENUM) != 0)
tokens.add("enum");
if ((access & Opcodes.ACC_ANNOTATION) != 0)
tokens.add("annotation");
if (!tokens.contains("interface") && !tokens.contains("enum")
&& !tokens.contains("annotation"))
tokens.add("class");
if (tokens.size() == 0)
return "[Error parsing]";
if (!unableToDecompile.isEmpty()) {
sb.append("//the following inner classes couldn't be decompiled: ");
for (String s : unableToDecompile) {
sb.append(s);
sb.append(" ");
}
sb.append(BytecodeViewer.nl);
}
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
sb.append(" ");
sb.append(tokens.get(i));
}
return sb.toString();
}
sb.append("}");
// System.out.println("Wrote end for " + cn.name +
// " with prefix length: " + sb.prefix.length());
return sb;
}
@Override public void decompileToZip(String zipName) { }
public static String getAccessString(int access) {
List<String> tokens = new ArrayList<String>();
if ((access & Opcodes.ACC_PUBLIC) != 0) tokens.add("public");
if ((access & Opcodes.ACC_PRIVATE) != 0) tokens.add("private");
if ((access & Opcodes.ACC_PROTECTED) != 0) tokens.add("protected");
if ((access & Opcodes.ACC_FINAL) != 0) tokens.add("final");
if ((access & Opcodes.ACC_SYNTHETIC) != 0) tokens.add("synthetic");
// if ((access & Opcodes.ACC_SUPER) != 0)
// tokens.add("super"); implied by invokespecial insn
if ((access & Opcodes.ACC_ABSTRACT) != 0) tokens.add("abstract");
if ((access & Opcodes.ACC_INTERFACE) != 0) tokens.add("interface");
if ((access & Opcodes.ACC_ENUM) != 0) tokens.add("enum");
if ((access & Opcodes.ACC_ANNOTATION) != 0) tokens.add("annotation");
if (!tokens.contains("interface") && !tokens.contains("enum") && !tokens.contains("annotation"))
tokens.add("class");
if (tokens.size() == 0) return "[Error parsing]";
// hackery delimeters
StringBuilder sb = new StringBuilder(tokens.get(0));
for (int i = 1; i < tokens.size(); i++) {
sb.append(" ");
sb.append(tokens.get(i));
}
return sb.toString();
}
@Override
public void decompileToZip(String zipName) {
}
public enum Settings implements DecompilerSettings.Setting {
DEBUG_HELPERS("debug-helpers", "Debug Helpers", true),
APPEND_BRACKETS_TO_LABELS("append-brackets-to-labels", "Append Brackets to Labels", true);
private String name;
private String param;
private boolean on;
Settings(String param, String name) {
this(param, name, false);
}
Settings(String param, String name, boolean on) {
this.name = name;
this.param = param;
this.on = on;
}
public String getText() {
return name;
}
public boolean isDefaultOn() {
return on;
}
public String getParam() {
return param;
}
}
}

View file

@ -1,12 +1,12 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.FieldNode;
import java.util.ArrayList;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,7 +1,16 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.Arrays;
import eu.bibl.banalysis.filter.InstructionFilter;
import eu.bibl.banalysis.filter.OpcodeFilter;
import eu.bibl.banalysis.filter.insn.FieldInstructionFilter;
import eu.bibl.banalysis.filter.insn.IincInstructionFilter;
import eu.bibl.banalysis.filter.insn.InsnInstructionFilter;
import eu.bibl.banalysis.filter.insn.JumpInstructionFilter;
import eu.bibl.banalysis.filter.insn.LdcInstructionFilter;
import eu.bibl.banalysis.filter.insn.MethodInstructionFilter;
import eu.bibl.banalysis.filter.insn.MultiANewArrayInstructionFilter;
import eu.bibl.banalysis.filter.insn.TypeInstructionFilter;
import eu.bibl.banalysis.filter.insn.VarInstructionFilter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
@ -15,17 +24,7 @@ import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import eu.bibl.banalysis.filter.InstructionFilter;
import eu.bibl.banalysis.filter.OpcodeFilter;
import eu.bibl.banalysis.filter.insn.FieldInstructionFilter;
import eu.bibl.banalysis.filter.insn.IincInstructionFilter;
import eu.bibl.banalysis.filter.insn.InsnInstructionFilter;
import eu.bibl.banalysis.filter.insn.JumpInstructionFilter;
import eu.bibl.banalysis.filter.insn.LdcInstructionFilter;
import eu.bibl.banalysis.filter.insn.MethodInstructionFilter;
import eu.bibl.banalysis.filter.insn.MultiANewArrayInstructionFilter;
import eu.bibl.banalysis.filter.insn.TypeInstructionFilter;
import eu.bibl.banalysis.filter.insn.VarInstructionFilter;
import java.util.Arrays;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,16 +1,6 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import org.apache.commons.lang3.StringEscapeUtils;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
@ -30,325 +20,306 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
*
*
* @author Konloch
* @author Bibl
*
*
*/
public class InstructionPrinter {
/** The MethodNode to print **/
protected MethodNode mNode;
private TypeAndName[] args;
/** The MethodNode to print **/
protected MethodNode mNode;
private TypeAndName[] args;
protected int[] pattern;
protected boolean match;
protected InstructionSearcher searcher;
protected int[] pattern;
protected boolean match;
protected InstructionSearcher searcher;
protected List<AbstractInsnNode> matchedInsns;
protected Map<LabelNode, Integer> labels;
protected List<AbstractInsnNode> matchedInsns;
protected Map<LabelNode, Integer> labels;
public InstructionPrinter(MethodNode m, TypeAndName[] args) {
this.args = args;
mNode = m;
labels = new HashMap<LabelNode, Integer>();
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because
// match = false
match = false;
}
public InstructionPrinter(MethodNode m, TypeAndName[] args) {
this.args = args;
mNode = m;
labels = new HashMap<LabelNode, Integer>();
// matchedInsns = new ArrayList<AbstractInsnNode>(); // ingnored because
// match = false
match = false;
}
public InstructionPrinter(MethodNode m, InstructionPattern pattern,
TypeAndName[] args) {
this.args = args;
mNode = m;
labels = new HashMap<LabelNode, Integer>();
searcher = new InstructionSearcher(m.instructions, pattern);
match = searcher.search();
if (match) {
for (AbstractInsnNode[] ains : searcher.getMatches()) {
for (AbstractInsnNode ain : ains) {
matchedInsns.add(ain);
}
}
}
}
public InstructionPrinter(MethodNode m, InstructionPattern pattern, TypeAndName[] args) {
this.args = args;
mNode = m;
labels = new HashMap<LabelNode, Integer>();
searcher = new InstructionSearcher(m.instructions, pattern);
match = searcher.search();
if (match) {
for (AbstractInsnNode[] ains : searcher.getMatches()) {
for (AbstractInsnNode ain : ains) {
matchedInsns.add(ain);
}
}
}
}
/**
* Creates the print
*
* @return The print as an ArrayList
*/
public ArrayList<String> createPrint() {
ArrayList<String> info = new ArrayList<String>();
ListIterator<?> it = mNode.instructions.iterator();
boolean firstLabel = false;
while (it.hasNext()) {
AbstractInsnNode ain = (AbstractInsnNode) it.next();
String line = "";
if (ain instanceof VarInsnNode) {
line = printVarInsnNode((VarInsnNode) ain, it);
} else if (ain instanceof IntInsnNode) {
line = printIntInsnNode((IntInsnNode) ain, it);
} else if (ain instanceof FieldInsnNode) {
line = printFieldInsnNode((FieldInsnNode) ain, it);
} else if (ain instanceof MethodInsnNode) {
line = printMethodInsnNode((MethodInsnNode) ain, it);
} else if (ain instanceof LdcInsnNode) {
line = printLdcInsnNode((LdcInsnNode) ain, it);
} else if (ain instanceof InsnNode) {
line = printInsnNode((InsnNode) ain, it);
} else if (ain instanceof JumpInsnNode) {
line = printJumpInsnNode((JumpInsnNode) ain, it);
} else if (ain instanceof LineNumberNode) {
line = printLineNumberNode((LineNumberNode) ain, it);
} else if (ain instanceof LabelNode) {
if (firstLabel
&& BytecodeViewer.viewer.chckbxmntmAppendBrackets
.isSelected())
info.add("}");
/**
* Creates the print
*
* @return The print as an ArrayList
*/
public ArrayList<String> createPrint() {
ArrayList<String> info = new ArrayList<String>();
ListIterator<?> it = mNode.instructions.iterator();
boolean firstLabel = false;
while (it.hasNext()) {
AbstractInsnNode ain = (AbstractInsnNode) it.next();
String line = "";
if (ain instanceof VarInsnNode) {
line = printVarInsnNode((VarInsnNode) ain, it);
} else if (ain instanceof IntInsnNode) {
line = printIntInsnNode((IntInsnNode) ain, it);
} else if (ain instanceof FieldInsnNode) {
line = printFieldInsnNode((FieldInsnNode) ain, it);
} else if (ain instanceof MethodInsnNode) {
line = printMethodInsnNode((MethodInsnNode) ain, it);
} else if (ain instanceof LdcInsnNode) {
line = printLdcInsnNode((LdcInsnNode) ain, it);
} else if (ain instanceof InsnNode) {
line = printInsnNode((InsnNode) ain, it);
} else if (ain instanceof JumpInsnNode) {
line = printJumpInsnNode((JumpInsnNode) ain, it);
} else if (ain instanceof LineNumberNode) {
line = printLineNumberNode((LineNumberNode) ain, it);
} else if (ain instanceof LabelNode) {
if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS))
info.add("}");
line = printLabelnode((LabelNode) ain);
line = printLabelnode((LabelNode) ain);
if (BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected()) {
if (!firstLabel)
firstLabel = true;
line += " {";
}
} else if (ain instanceof TypeInsnNode) {
line = printTypeInsnNode((TypeInsnNode) ain);
} else if (ain instanceof FrameNode) {
line = "";
} else if (ain instanceof IincInsnNode) {
line = printIincInsnNode((IincInsnNode) ain);
} else if (ain instanceof TableSwitchInsnNode) {
line = printTableSwitchInsnNode((TableSwitchInsnNode) ain);
} else if (ain instanceof LookupSwitchInsnNode) {
line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain);
} else if (ain instanceof InvokeDynamicInsnNode) {
line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain);
} else {
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " "
+ ain.toString();
}
if (!line.equals("")) {
if (match)
if (matchedInsns.contains(ain))
line = " -> " + line;
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS)) {
if (!firstLabel) firstLabel = true;
line += " {";
}
} else if (ain instanceof TypeInsnNode) {
line = printTypeInsnNode((TypeInsnNode) ain);
} else if (ain instanceof FrameNode) {
line = "";
} else if (ain instanceof IincInsnNode) {
line = printIincInsnNode((IincInsnNode) ain);
} else if (ain instanceof TableSwitchInsnNode) {
line = printTableSwitchInsnNode((TableSwitchInsnNode) ain);
} else if (ain instanceof LookupSwitchInsnNode) {
line = printLookupSwitchInsnNode((LookupSwitchInsnNode) ain);
} else if (ain instanceof InvokeDynamicInsnNode) {
line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain);
} else {
line += "UNADDED OPCODE: " + nameOpcode(ain.getOpcode()) + " " + ain.toString();
}
if (!line.equals("")) {
if (match) if (matchedInsns.contains(ain)) line = " -> " + line;
info.add(line);
}
}
if (firstLabel
&& BytecodeViewer.viewer.chckbxmntmAppendBrackets.isSelected())
info.add("}");
return info;
}
info.add(line);
}
}
if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS)) info.add("}");
return info;
}
protected String printVarInsnNode(VarInsnNode vin, ListIterator<?> it) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(vin.getOpcode()));
sb.append(vin.var);
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
if (vin.var == 0 && !Modifier.isStatic(mNode.access)) {
sb.append(" // reference to self");
} else {
final int refIndex = vin.var
- (Modifier.isStatic(mNode.access) ? 0 : 1);
if (refIndex >= 0 && refIndex < args.length - 1) {
sb.append(" // reference to " + args[refIndex].name);
}
}
}
protected String printVarInsnNode(VarInsnNode vin, ListIterator<?> it) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(vin.getOpcode()));
sb.append(vin.var);
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS)) {
if (vin.var == 0 && !Modifier.isStatic(mNode.access)) {
sb.append(" // reference to self");
} else {
final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1);
if (refIndex >= 0 && refIndex < args.length - 1) {
sb.append(" // reference to " + args[refIndex].name);
}
}
}
return sb.toString();
}
return sb.toString();
}
protected String printIntInsnNode(IntInsnNode iin, ListIterator<?> it) {
return nameOpcode(iin.getOpcode()) + " " + iin.operand;
}
protected String printIntInsnNode(IntInsnNode iin, ListIterator<?> it) {
return nameOpcode(iin.getOpcode()) + " " + iin.operand;
}
protected String printFieldInsnNode(FieldInsnNode fin, ListIterator<?> it) {
String desc = Type.getType(fin.desc).getClassName();
if (desc == null || desc.equals("null"))
desc = fin.desc;
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name
+ ":" + desc;
}
protected String printFieldInsnNode(FieldInsnNode fin, ListIterator<?> it) {
String desc = Type.getType(fin.desc).getClassName();
if (desc == null || desc.equals("null")) desc = fin.desc;
return nameOpcode(fin.getOpcode()) + " " + fin.owner + "." + fin.name + ":" + desc;
}
protected String printMethodInsnNode(MethodInsnNode min, ListIterator<?> it) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " "
+ min.name + "(");
protected String printMethodInsnNode(MethodInsnNode min, ListIterator<?> it) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(min.getOpcode()) + " " + min.owner + " " + min.name + "(");
String desc = min.desc;
try {
if(Type.getType(min.desc) != null)
desc = Type.getType(min.desc).getClassName();
String desc = min.desc;
try {
if (Type.getType(min.desc) != null) desc = Type.getType(min.desc).getClassName();
if (desc == null || desc.equals("null"))
desc = min.desc;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
}
sb.append(desc);
if (desc == null || desc.equals("null")) desc = min.desc;
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
sb.append(");");
}
return sb.toString();
}
sb.append(desc);
protected String printLdcInsnNode(LdcInsnNode ldc, ListIterator<?> it) {
if (ldc.cst instanceof String)
return nameOpcode(ldc.getOpcode()) + " \""
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" ("
+ ldc.cst.getClass().getCanonicalName() + ")";
sb.append(");");
return nameOpcode(ldc.getOpcode()) + " "
+ StringEscapeUtils.escapeJava(ldc.cst.toString()) + " ("
+ ldc.cst.getClass().getCanonicalName() + ")";
}
return sb.toString();
}
protected String printInsnNode(InsnNode in, ListIterator<?> it) {
return nameOpcode(in.getOpcode());
}
protected String printLdcInsnNode(LdcInsnNode ldc, ListIterator<?> it) {
if (ldc.cst instanceof String)
return nameOpcode(ldc.getOpcode()) + " \"" + StringEscapeUtils.escapeJava(ldc.cst.toString()) + "\" (" + ldc.cst.getClass().getCanonicalName() + ")";
protected String printJumpInsnNode(JumpInsnNode jin, ListIterator<?> it) {
String line = nameOpcode(jin.getOpcode()) + " L"
+ resolveLabel(jin.label);
return line;
}
return nameOpcode(ldc.getOpcode()) + " " + StringEscapeUtils.escapeJava(ldc.cst.toString()) + " (" + ldc.cst.getClass().getCanonicalName() + ")";
}
protected String printLineNumberNode(LineNumberNode lin, ListIterator<?> it) {
return "";
}
protected String printInsnNode(InsnNode in, ListIterator<?> it) {
return nameOpcode(in.getOpcode());
}
protected String printLabelnode(LabelNode label) {
return "L" + resolveLabel(label);
}
protected String printJumpInsnNode(JumpInsnNode jin, ListIterator<?> it) {
String line = nameOpcode(jin.getOpcode()) + " L" + resolveLabel(jin.label);
return line;
}
protected String printTypeInsnNode(TypeInsnNode tin) {
try {
String desc = tin.desc;
try {
if(Type.getType(tin.desc) != null)
desc = Type.getType(tin.desc).getClassName();
protected String printLineNumberNode(LineNumberNode lin, ListIterator<?> it) {
return "";
}
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);
}
return "//error";
}
protected String printLabelnode(LabelNode label) {
return "L" + resolveLabel(label);
}
protected String printIincInsnNode(IincInsnNode iin) {
return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr;
}
protected String printTypeInsnNode(TypeInsnNode tin) {
try {
String desc = tin.desc;
try {
if (Type.getType(tin.desc) != null) desc = Type.getType(tin.desc).getClassName();
protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) {
String line = nameOpcode(tin.getOpcode()) + " \n";
List<?> labels = tin.labels;
int count = 0;
for (int i = tin.min; i < tin.max+1; i++) {
line += " val: " + i + " -> " + "L"
+ resolveLabel((LabelNode) labels.get(count++)) + "\n";
}
line += " default" + " -> L" + resolveLabel(tin.dflt)
+ "";
return line;
}
if (desc == null || desc.equals("null")) desc = tin.desc;
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) {
String line = nameOpcode(lin.getOpcode()) + ": \n";
List<?> keys = lin.keys;
List<?> labels = lin.labels;
}
return nameOpcode(tin.getOpcode()) + " " + desc;
} catch (Exception e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
return "//error";
}
for (int i = 0; i < keys.size(); i++) {
int key = (Integer) keys.get(i);
LabelNode label = (LabelNode) labels.get(i);
line += " val: " + key + " -> " + "L"
+ resolveLabel(label) + "\n";
}
line += " default" + " -> L" + resolveLabel(lin.dflt)
+ "";
return line;
}
protected String printIincInsnNode(IincInsnNode iin) {
return nameOpcode(iin.getOpcode()) + " " + iin.var + " " + iin.incr;
}
protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(idin.getOpcode()) + " " + idin.bsm.getName() + "(");
protected String printTableSwitchInsnNode(TableSwitchInsnNode tin) {
String line = nameOpcode(tin.getOpcode()) + " \n";
List<?> labels = tin.labels;
int count = 0;
for (int i = tin.min; i < tin.max + 1; i++) {
line += " val: " + i + " -> " + "L" + resolveLabel((LabelNode) labels.get(count++)) + "\n";
}
line += " default" + " -> L" + resolveLabel(tin.dflt) + "";
return line;
}
String desc = idin.desc;
String partedDesc = idin.desc.substring(2);
try {
if(Type.getType(partedDesc) != null)
desc = Type.getType(partedDesc).getClassName();
protected String printLookupSwitchInsnNode(LookupSwitchInsnNode lin) {
String line = nameOpcode(lin.getOpcode()) + ": \n";
List<?> keys = lin.keys;
List<?> labels = lin.labels;
if (desc == null || desc.equals("null"))
desc = idin.desc;
} catch(java.lang.ArrayIndexOutOfBoundsException e) {
for (int i = 0; i < keys.size(); i++) {
int key = (Integer) keys.get(i);
LabelNode label = (LabelNode) labels.get(i);
line += " val: " + key + " -> " + "L" + resolveLabel(label) + "\n";
}
line += " default" + " -> L" + resolveLabel(lin.dflt) + "";
return line;
}
}
protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin) {
StringBuilder sb = new StringBuilder();
sb.append(nameOpcode(idin.getOpcode()) + " " + idin.bsm.getName() + "(");
sb.append(desc);
String desc = idin.desc;
String partedDesc = idin.desc.substring(2);
try {
if (Type.getType(partedDesc) != null) desc = Type.getType(partedDesc).getClassName();
sb.append(");");
if (desc == null || desc.equals("null")) desc = idin.desc;
} catch (java.lang.ArrayIndexOutOfBoundsException e) {
return sb.toString();
}
}
protected String nameOpcode(int opcode) {
return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();
}
sb.append(desc);
protected int resolveLabel(LabelNode label) {
if (labels.containsKey(label)) {
return labels.get(label);
} else {
int newLabelIndex = labels.size() + 1;
labels.put(label, newLabelIndex);
return newLabelIndex;
}
}
sb.append(");");
public static void saveTo(File file, InstructionPrinter printer) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
for (String s : printer.createPrint()) {
bw.write(s);
bw.newLine();
}
bw.close();
} catch (IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
return sb.toString();
}
protected String nameOpcode(int opcode) {
return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();
}
protected int resolveLabel(LabelNode label) {
if (labels.containsKey(label)) {
return labels.get(label);
} else {
int newLabelIndex = labels.size() + 1;
labels.put(label, newLabelIndex);
return newLabelIndex;
}
}
public static void saveTo(File file, InstructionPrinter printer) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
for (String s : printer.createPrint()) {
bw.write(s);
bw.newLine();
}
bw.close();
} catch (IOException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
}

View file

@ -1,14 +1,14 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LineNumberNode;
import java.util.ArrayList;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,9 +1,5 @@
package the.bytecode.club.bytecodeviewer.decompilers.bytecode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
@ -11,9 +7,12 @@ import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.LocalVariableNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.TypeAndName;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -112,7 +111,7 @@ public class MethodNodeDecompiler {
sb.append(" {");
if (BytecodeViewer.viewer.debugHelpers.isSelected()) {
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS)) {
if (m.name.equals("<clinit>"))
sb.append(" // <clinit>");
else if (m.name.equals("<init>"))

View file

@ -2,9 +2,15 @@ package the.bytecode.club.bytecodeviewer.gui;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.Settings;
import javax.swing.*;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
@ -28,11 +34,10 @@ import java.awt.*;
* The about frame.
*
* @author Konloch
*
*/
public class AboutWindow extends JFrame {
JTextArea textArea = new JTextArea();
private static final long serialVersionUID = -8230501978224923296L;
private JTextArea textArea = new JTextArea();
public AboutWindow() {
this.setIconImages(Resources.iconList);
@ -54,20 +59,21 @@ public class AboutWindow extends JFrame {
public void setVisible(boolean b) {
super.setVisible(b);
textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue()));
textArea.setText("Bytecode Viewer " + BytecodeViewer.version + " is an open source program developed and maintained by Konloch (konloch@gmail.com) 100% free and open sourced licensed under GPL v3 CopyLeft\r\n\r\n" +
textArea.setText("Bytecode Viewer " + BytecodeViewer.version + " is an open source program developed and maintained by Konloch (konloch@gmail.com) and samczsun 100% free and open sourced licensed under GPL v3 CopyLeft" + BytecodeViewer.nl +
BytecodeViewer.nl +
"Settings:" + BytecodeViewer.nl +
" Preview Copy: " + BytecodeViewer.previewCopy + BytecodeViewer.nl +
" Java: " + BytecodeViewer.java + BytecodeViewer.nl +
" Javac: " + BytecodeViewer.javac + BytecodeViewer.nl +
" Java: " + Settings.JAVA_LOCATION.get() + BytecodeViewer.nl +
" Javac: " + Settings.JAVAC_LOCATION.get() + BytecodeViewer.nl +
" BCV Dir: " + BytecodeViewer.getBCVDirectory() + BytecodeViewer.nl +
" Python 2.7 (or PyPy): " + BytecodeViewer.python + BytecodeViewer.nl +
" Python 3.X (or PyPy): " + BytecodeViewer.python3 + BytecodeViewer.nl +
" RT.jar:" + BytecodeViewer.rt + BytecodeViewer.nl +
" Optional Lib: " + BytecodeViewer.library + BytecodeViewer.nl +
" Python 2.7 (or PyPy): " + Settings.PYTHON2_LOCATION.get() + BytecodeViewer.nl +
" Python 3.X (or PyPy): " + Settings.PYTHON3_LOCATION.get() + BytecodeViewer.nl +
" RT.jar:" + Settings.RT_LOCATION.get() + BytecodeViewer.nl +
" Optional Lib: " + Settings.PATH.get() + BytecodeViewer.nl +
" BCV Krakatau: v" + BytecodeViewer.krakatauVersion + BytecodeViewer.nl +
" Krakatau Dir: " + BytecodeViewer.krakatauWorkingDirectory + BytecodeViewer.nl +
" Krakatau Dir: " + BytecodeViewer.krakatauDirectory.getAbsolutePath() + BytecodeViewer.nl +
" BCV Enjarify: v" + BytecodeViewer.enjarifyVersion + BytecodeViewer.nl +
" Enjarify Dir: " + BytecodeViewer.enjarifyWorkingDirectory + BytecodeViewer.nl + BytecodeViewer.nl +
" Enjarify Dir: " + BytecodeViewer.enjarifyDirectory.getAbsolutePath()+ BytecodeViewer.nl + BytecodeViewer.nl +
"Command Line Input:" + BytecodeViewer.nl +
" -help Displays the help menu" + BytecodeViewer.nl +
" -list Displays the available decompilers" + BytecodeViewer.nl +
@ -82,11 +88,24 @@ public class AboutWindow extends JFrame {
" CTRL + W: Closes the currently opened tab" + BytecodeViewer.nl +
" CTRL + T: Compile" + BytecodeViewer.nl +
" CTRL + S: Save classes as zip" + BytecodeViewer.nl +
" CTRL + R: Run (EZ-Inject) - dynamically load the classes and invoke a main class" +
"\r\n\r\nCode from various projects has been used, including but not limited to:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSynaxPane by Robert Futrell\r\n Commons IO by Apache\r\n ASM by OW2\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n CFIDE by Bibl\r\n Smali by JesusFreke\r\n Dex2Jar by pxb1..?\r\n Krakatau by Storyyeller\r\n JD-GUI + JD-Core by The Java-Decompiler Team\r\n Enjarify by Storyyeller\r\n\r\nIf you're interested in Java Reverse Engineering, join The Bytecode Club - https://the.bytecode.club");
" CTRL + R: Run (EZ-Inject) - dynamically load the classes and invoke a main class" + BytecodeViewer.nl +
BytecodeViewer.nl +
"Code from various projects has been used, including but not limited to:" + BytecodeViewer.nl +
" J-RET by WaterWolf" + BytecodeViewer.nl +
" JHexPane by Sam Koivu" + BytecodeViewer.nl +
" RSynaxPane by Robert Futrell" + BytecodeViewer.nl +
" Commons IO by Apache" + BytecodeViewer.nl +
" ASM by OW2" + BytecodeViewer.nl +
" FernFlower by Stiver" + BytecodeViewer.nl +
" Procyon by Mstrobel" + BytecodeViewer.nl +
" CFR by Lee Benfield" + BytecodeViewer.nl +
" CFIDE by Bibl" + BytecodeViewer.nl +
" Smali by JesusFreke" + BytecodeViewer.nl +
" Dex2Jar by pxb1..?" + BytecodeViewer.nl +
" Krakatau by Storyyeller" + BytecodeViewer.nl +
" JD-GUI + JD-Core by The Java-Decompiler Team" + BytecodeViewer.nl +
" Enjarify by Storyyeller" + BytecodeViewer.nl +
BytecodeViewer.nl +
"If you're interested in Java Reverse Engineering, join The Bytecode Club - https://the.bytecode.club");
}
private static final long serialVersionUID = -8230501978224923296L;
}

View file

@ -1,17 +1,16 @@
package the.bytecode.club.bytecodeviewer.gui;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.AllatoriStringDecrypter;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,19 +1,17 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JButton;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.BoxLayout;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -0,0 +1,50 @@
package the.bytecode.club.bytecodeviewer.gui;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Settings;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import java.io.File;
public class FileChooser {
private Settings<String> target;
private String message;
public FileChooser(Settings<String> target, String message) {
this.target = target;
this.message = message;
}
public void run() {
File currentFile = new File(target.get() == null || target.get().isEmpty() ? System.getProperty("user.home") : target.get());
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return true;
}
@Override
public String getDescription() {
return message;
}
});
if (currentFile.isDirectory()) {
fc.setCurrentDirectory(currentFile);
} else {
fc.setSelectedFile(currentFile);
}
fc.setFileHidingEnabled(false);
fc.setAcceptAllFileFilterUsed(false);
int returnVal = fc.showOpenDialog(BytecodeViewer.viewer);
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
target.set(fc.getSelectedFile().getAbsolutePath());
} catch (Exception e1) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e1);
}
}
}
}

View file

@ -1,18 +1,46 @@
package the.bytecode.club.bytecodeviewer.gui;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.*;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import the.bytecode.club.bytecodeviewer.FileContainer;
import the.bytecode.club.bytecodeviewer.FileDrop;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.*;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map.Entry;
/***************************************************************************
@ -53,7 +81,7 @@ public class FileNavigationPane extends VisibleComponent implements FileDrop.Lis
MyTreeNode treeRoot = new MyTreeNode("Loaded Files:");
MyTree tree = new MyTree(treeRoot);
final JTextField quickSearch = new JTextField(quickSearchText);
public KeyAdapter search = new KeyAdapter() {
public transient KeyAdapter search = new KeyAdapter() {
@Override
public void keyPressed(final KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_ENTER) {

View file

@ -1,5 +1,24 @@
package the.bytecode.club.bytecodeviewer.gui;
import com.jhe.hexed.JHexEditor;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.imgscalr.Scalr;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
@ -14,28 +33,6 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.imgscalr.Scalr;
import com.jhe.hexed.JHexEditor;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,12 +1,12 @@
package the.bytecode.club.bytecodeviewer.gui;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import the.bytecode.club.bytecodeviewer.Resources;
import java.awt.Dimension;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,18 +1,15 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JCheckBox;
import javax.swing.JButton;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.MaliciousCodeScanner;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -18,20 +18,98 @@ package the.bytecode.club.bytecodeviewer.gui;
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
import com.jhe.hexed.JHexEditor;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rtextarea.RTextScrollPane;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.decompilers.Decompiler;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
/**
* Allows us to run a background thread
* Updates a pane
*
* @author Konloch
*
*/
public class PaneUpdaterThread extends Thread {
public abstract class PaneUpdaterThread extends Thread {
private Decompiler decompiler;
private int paneId;
private JPanel target;
private ClassViewer viewer;
private JButton button;
public abstract void doShit();
@Override
public void run() {
doShit();
public PaneUpdaterThread(ClassViewer viewer, Decompiler decompiler, int paneId, JPanel target, JButton button) {
this.decompiler = decompiler;
this.paneId = paneId;
this.target = target;
this.viewer = viewer;
this.button = button;
}
public void run() {
try {
final byte[] b = BytecodeViewer.getClassBytes(viewer.cn.name + ".class");
if (decompiler != Decompiler.HEXCODE) {
RSyntaxTextArea panelArea = new RSyntaxTextArea();
panelArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
panelArea.setCodeFoldingEnabled(true);
panelArea.setAntiAliasingEnabled(true);
final RTextScrollPane scrollPane = new RTextScrollPane(panelArea);
panelArea.setText(decompiler.decompileClassNode(viewer.cn, b));
panelArea.setCaretPosition(0);
panelArea.setEditable(viewer.isPaneEditable(paneId));
panelArea.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_F) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
viewer.requestFocus(paneId);
}
BytecodeViewer.checkHotKey(e);
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
});
scrollPane.setColumnHeaderView(new JLabel(decompiler.getName() + " Decompiler - Editable: " + panelArea.isEditable()));
panelArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int) BytecodeViewer.viewer.fontSpinner.getValue()));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
target.add(scrollPane);
}
});
viewer.updatePane(paneId, panelArea, decompiler);
} else {
final JHexEditor hex = new JHexEditor(b);
hex.setFont(new Font(Font.MONOSPACED, Font.PLAIN, (int)BytecodeViewer.viewer.fontSpinner.getValue()));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
target.add(hex);
}
});
}
} catch(Exception e) {
new ExceptionUI(e);
} finally {
viewer.resetDivider();
BytecodeViewer.viewer.setIcon(false);
if(button != null)
button.setEnabled(true);
}
}
}

View file

@ -1,20 +1,17 @@
package the.bytecode.club.bytecodeviewer.gui;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.ReplaceStrings;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,26 +1,20 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JCheckBox;
import javax.swing.JButton;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.plugin.PluginManager;
import the.bytecode.club.bytecodeviewer.plugin.preinstalled.EZInjection;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -3,14 +3,29 @@ package the.bytecode.club.bytecodeviewer.gui;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import the.bytecode.club.bytecodeviewer.searching.*;
import the.bytecode.club.bytecodeviewer.searching.BackgroundSearchThread;
import the.bytecode.club.bytecodeviewer.searching.FieldCallSearch;
import the.bytecode.club.bytecodeviewer.searching.LDCSearch;
import the.bytecode.club.bytecodeviewer.searching.MethodCallSearch;
import the.bytecode.club.bytecodeviewer.searching.RegexInsnFinder;
import the.bytecode.club.bytecodeviewer.searching.RegexSearch;
import the.bytecode.club.bytecodeviewer.searching.SearchResultNotifier;
import the.bytecode.club.bytecodeviewer.searching.SearchTypeDetails;
import javax.swing.*;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
@ -59,7 +74,7 @@ public class SearchingPane extends VisibleComponent {
JComboBox searchRadiusBox;
public JButton search = new JButton("Search");
BackgroundSearchThread t = new BackgroundSearchThread(true) {
transient BackgroundSearchThread t = new BackgroundSearchThread(true) {
@Override
public void doSearch() {
// empty

View file

@ -1,16 +1,21 @@
package the.bytecode.club.bytecodeviewer.gui;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
@ -19,16 +24,6 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import javax.swing.JTextArea;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import javax.swing.JPanel;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,5 +1,14 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
@ -13,16 +22,6 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicButtonUI;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,8 +1,9 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JPanel;
import org.objectweb.asm.tree.ClassNode;
import javax.swing.JPanel;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,11 +1,10 @@
package the.bytecode.club.bytecodeviewer.gui;
import javax.swing.JInternalFrame;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import javax.swing.JInternalFrame;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,5 +1,14 @@
package the.bytecode.club.bytecodeviewer.gui;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
@ -9,17 +18,6 @@ import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.util.HashMap;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -156,7 +154,7 @@ public class WorkPane extends VisibleComponent implements ActionListener {
}
public java.awt.Component[] getLoadedViewers() {
return (java.awt.Component[])tabs.getComponents();
return tabs.getComponents();
}
@Override
@ -193,6 +191,9 @@ public class WorkPane extends VisibleComponent implements ActionListener {
}
public void resetWorkspace() {
for (Component component : tabs.getComponents()) {
((ClassViewer) component).reset();
}
tabs.removeAll();
tabs.updateUI();
}

View file

@ -1,10 +1,10 @@
package the.bytecode.club.bytecodeviewer.obfuscators;
import java.util.ArrayList;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,7 +1,6 @@
package the.bytecode.club.bytecodeviewer.obfuscators;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;

View file

@ -2,7 +2,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;

View file

@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ASMUtil_OLD;

View file

@ -1,12 +1,12 @@
package the.bytecode.club.bytecodeviewer.obfuscators.mapping;
import java.util.ArrayList;
import java.util.List;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData;
import java.util.ArrayList;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,16 +1,15 @@
package the.bytecode.club.bytecodeviewer.obfuscators.mapping;
import org.objectweb.asm.commons.Remapper;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.commons.Remapper;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MethodMappingData;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -72,7 +71,7 @@ public class RefactorMapper extends Remapper {
@Override
public String map(String type) {
if (sortedClasses.containsKey(type)) {
String map = new String(type + " --> " + sortedClasses.get(type).getRefactoredName() + "\n");
String map = type + " --> " + sortedClasses.get(type).getRefactoredName() + "\n";
if (!mappingList.contains(map))
mappingList.add(map);
@ -85,7 +84,7 @@ public class RefactorMapper extends Remapper {
public String mapFieldName(String owner, String name, String desc) {
String obfKey = owner + "$$$$" + name + "$$$$" + desc;
if (sortedFields.containsKey(obfKey)) {
String map = new String(owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n");
String map = owner + "." + name + " --> " + owner + sortedFields.get(obfKey).getName().getRefactoredName() + "\n";
if (!mappingList.contains(map))
mappingList.add(map);
name = sortedFields.get(obfKey).getName().getRefactoredName();
@ -97,7 +96,7 @@ public class RefactorMapper extends Remapper {
public String mapMethodName(String owner, String name, String desc) {
String obfKey = owner + "$$$$" + name + "$$$$" + desc;
if (sortedMethods.containsKey(obfKey)) {
String map = new String(owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n");
String map = owner + "." + name + " --> " + owner + sortedMethods.get(obfKey).getMethodName().getRefactoredName() + "\n";
if (!mappingList.contains(map))
mappingList.add(map);
name = sortedMethods.get(obfKey).getMethodName().getRefactoredName();

View file

@ -1,15 +1,14 @@
package the.bytecode.club.bytecodeviewer.obfuscators.mapping;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import java.util.HashMap;
import java.util.Map;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData;

View file

@ -2,7 +2,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.FieldMappingData;

View file

@ -3,7 +3,6 @@ package the.bytecode.club.bytecodeviewer.obfuscators.rename;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.obfuscators.JavaObfuscator;
import the.bytecode.club.bytecodeviewer.obfuscators.mapping.data.MappingData;

View file

@ -1,9 +1,9 @@
package the.bytecode.club.bytecodeviewer.plugin;
import java.io.File;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import java.io.File;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,12 +1,5 @@
package the.bytecode.club.bytecodeviewer.plugin;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.swing.filechooser.FileFilter;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.MiscUtils;
import the.bytecode.club.bytecodeviewer.api.Plugin;
@ -16,6 +9,12 @@ import the.bytecode.club.bytecodeviewer.plugin.strategies.JavaPluginLaunchStrate
import the.bytecode.club.bytecodeviewer.plugin.strategies.PythonPluginLaunchStrategy;
import the.bytecode.club.bytecodeviewer.plugin.strategies.RubyPluginLaunchStrategy;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,14 +1,5 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
@ -16,13 +7,20 @@ import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,26 +1,23 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.UIManager;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Resources;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.gui.ClassViewer;
import javax.swing.JFrame;
import javax.swing.UIManager;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,23 +1,22 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.BytecodeHook;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import the.bytecode.club.bytecodeviewer.gui.GraphicialReflectionKit;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,7 +1,5 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@ -11,11 +9,12 @@ import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,17 +1,16 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,111 +1,125 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* Simply shows all the non-empty strings in every single class
*
*
* @author Konloch
*
*/
public class ShowAllStrings extends Plugin {
@Override
public void execute(final ArrayList<ClassNode> classNodeList) {
final PluginConsole frame = new PluginConsole("Show All Strings");
final AtomicBoolean complete = new AtomicBoolean(false);
final Thread backgroundThread = new Thread() {
public void run() {
try {
for (ClassNode classNode : classNodeList) {
for (Object o : classNode.fields.toArray()) {
FieldNode f = (FieldNode) o;
Object v = f.value;
if (v instanceof String) {
String s = (String) v;
if (!s.isEmpty()) {
frame.appendText(String.format("%s.%s%s -> \"%s\"", classNode.name, f.name, f.desc, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r")));
}
}
if (v instanceof String[]) {
for (int i = 0; i < ((String[]) v).length; i++) {
String s = ((String[]) v)[i];
if (!s.isEmpty()) {
frame.appendText(String.format("%s.%s%s[%s] -> \"%s\"", classNode.name, f.name, f.desc, i, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r")));
}
}
}
}
for (Object o : classNode.methods.toArray()) {
MethodNode m = (MethodNode) o;
InsnList iList = m.instructions;
for (AbstractInsnNode a : iList.toArray()) {
if (a instanceof LdcInsnNode) {
if (((LdcInsnNode) a).cst instanceof String) {
final String s = (String) ((LdcInsnNode) a).cst;
if (!s.isEmpty()) {
frame.appendText(String.format("%s.%s%s -> \"%s\"", classNode.name, m.name, m.desc, s.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r")));
}
}
}
}
}
}
} catch (Exception e) {
new ExceptionUI(e, "konloch@gmail.com");
} finally {
complete.set(true);
}
}
};
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
@Override
public void windowClosing(WindowEvent e) {
backgroundThread.stop();
complete.set(true);
}
@Override
public void execute(ArrayList<ClassNode> classNodeList) {
PluginConsole frame = new PluginConsole("Show All Strings");
StringBuilder sb = new StringBuilder();
for (ClassNode classNode : classNodeList) {
for (Object o : classNode.fields.toArray()) {
FieldNode f = (FieldNode) o;
Object v = f.value;
if (v instanceof String) {
String s = (String) v;
if (!s.isEmpty())
sb.append(classNode.name
+ "."
+ f.name
+ ""
+ f.desc
+ " -> \""
+ s.replaceAll("\\n", "\\\\n").replaceAll(
"\\r", "\\\\r") + "\""
+ BytecodeViewer.nl);
}
if (v instanceof String[]) {
for (int i = 0; i < ((String[]) v).length; i++) {
String s = ((String[]) v)[i];
if (!s.isEmpty())
sb.append(classNode.name
+ "."
+ f.name
+ ""
+ f.desc
+ "["
+ i
+ "] -> \""
+ s.replaceAll("\\n", "\\\\n").replaceAll(
"\\r", "\\\\r") + "\""
+ BytecodeViewer.nl);
}
}
}
@Override
public void windowOpened(WindowEvent e) {
}
for (Object o : classNode.methods.toArray()) {
MethodNode m = (MethodNode) o;
@Override
public void windowClosed(WindowEvent e) {
}
InsnList iList = m.instructions;
for (AbstractInsnNode a : iList.toArray()) {
if (a instanceof LdcInsnNode) {
if (((LdcInsnNode) a).cst instanceof String) {
final String s = (String) ((LdcInsnNode) a).cst;
if (!s.isEmpty())
sb.append(classNode.name
+ "."
+ m.name
+ ""
+ m.desc
+ " -> \""
+ s.replaceAll("\\n", "\\\\n")
.replaceAll("\\r", "\\\\r")
+ "\"" + BytecodeViewer.nl);
}
}
}
}
}
@Override
public void windowIconified(WindowEvent e) {
}
frame.appendText(sb.toString());
frame.setVisible(true);
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
backgroundThread.start();
while (!complete.get()) ;
}
}

View file

@ -1,13 +1,12 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import java.util.ArrayList;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import java.util.ArrayList;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,7 +1,6 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.Plugin;

View file

@ -1,19 +1,17 @@
package the.bytecode.club.bytecodeviewer.plugin.preinstalled;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.api.PluginConsole;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,5 +1,11 @@
package the.bytecode.club.bytecodeviewer.plugin.strategies;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
@ -9,13 +15,6 @@ import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,15 +1,14 @@
package the.bytecode.club.bytecodeviewer.plugin.strategies;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,14 +1,12 @@
package the.bytecode.club.bytecodeviewer.plugin.strategies;
import java.io.File;
import me.konloch.kontainer.io.DiskReader;
import org.apache.commons.io.FileUtils;
import org.codehaus.janino.SimpleCompiler;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
import java.io.File;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
@ -38,7 +36,7 @@ public class JavaPluginLaunchStrategy implements PluginLaunchStrategy {
@Override
public Plugin run(File file) throws Throwable {
compiler.cook(DiskReader.loadAsString(file.getAbsolutePath()));
compiler.cook(FileUtils.readFileToString(file, "UTF-8"));
System.out.println(file.getName().substring(0,(int)(file.getName().length()-(".java".length()))));
Class<?> clazz = (Class<?>) Class.forName(

View file

@ -1,15 +1,14 @@
package the.bytecode.club.bytecodeviewer.plugin.strategies;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,15 +1,14 @@
package the.bytecode.club.bytecodeviewer.plugin.strategies;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import the.bytecode.club.bytecodeviewer.api.Plugin;
import the.bytecode.club.bytecodeviewer.plugin.PluginLaunchStrategy;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,13 +1,6 @@
package the.bytecode.club.bytecodeviewer.searching;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@ -15,7 +8,12 @@ import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodNode;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,13 +1,5 @@
package the.bytecode.club.bytecodeviewer.searching;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@ -16,6 +8,13 @@ import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,13 +1,6 @@
package the.bytecode.club.bytecodeviewer.searching;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@ -15,7 +8,12 @@ import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import eu.bibl.banalysis.asm.desc.OpcodeInfo;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.util.Iterator;
import java.util.ListIterator;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *

View file

@ -1,13 +1,5 @@
package the.bytecode.club.bytecodeviewer.searching;
import java.rmi.UnexpectedException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
@ -21,403 +13,413 @@ import org.objectweb.asm.tree.MultiANewArrayInsnNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import java.rmi.UnexpectedException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
* *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/**
* An instruction finder that finds regex patterns in a method's instruction
* list and returns an array with the found instructions.
*
*
* @author Frédéric Hannes
*
*
*/
public class RegexInsnFinder {
private static String[] opcodes = new String[] { "NOP", "ACONST_NULL",
"ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3",
"ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0",
"FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH",
"LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD",
"ALOAD", "ILOAD_0", "ILOAD_1", "ILOAD_2", "ILOAD_3", "LLOAD_0",
"LLOAD_1", "LLOAD_2", "LLOAD_3", "FLOAD_0", "FLOAD_1", "FLOAD_2",
"FLOAD_3", "DLOAD_0", "DLOAD_1", "DLOAD_2", "DLOAD_3", "ALOAD_0",
"ALOAD_1", "ALOAD_2", "ALOAD_3", "IALOAD", "LALOAD", "FALOAD",
"DALOAD", "AALOAD", "BALOAD", "CALOAD", "SALOAD", "ISTORE",
"LSTORE", "FSTORE", "DSTORE", "ASTORE", "ISTORE_0", "ISTORE_1",
"ISTORE_2", "ISTORE_3", "LSTORE_0", "LSTORE_1", "LSTORE_2",
"LSTORE_3", "FSTORE_0", "FSTORE_1", "FSTORE_2", "FSTORE_3",
"DSTORE_0", "DSTORE_1", "DSTORE_2", "DSTORE_3", "ASTORE_0",
"ASTORE_1", "ASTORE_2", "ASTORE_3", "IASTORE", "LASTORE",
"FASTORE", "DASTORE", "AASTORE", "BASTORE", "CASTORE", "SASTORE",
"POP", "POP2", "DUP", "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1",
"DUP2_X2", "SWAP", "IADD", "LADD", "FADD", "DADD", "ISUB", "LSUB",
"FSUB", "DSUB", "IMUL", "LMUL", "FMUL", "DMUL", "IDIV", "LDIV",
"FDIV", "DDIV", "IREM", "LREM", "FREM", "DREM", "INEG", "LNEG",
"FNEG", "DNEG", "ISHL", "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR",
"IAND", "LAND", "IOR", "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F",
"I2D", "L2I", "L2F", "L2D", "F2I", "F2L", "F2D", "D2I", "D2L",
"D2F", "I2B", "I2C", "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL",
"DCMPG", "IFEQ", "IFNE", "IFLT", "IFGE", "IFGT", "IFLE",
"IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT",
"IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE", "GOTO", "JSR", "RET",
"TABLESWITCH", "LOOKUPSWITCH", "IRETURN", "LRETURN", "FRETURN",
"DRETURN", "ARETURN", "RETURN", "GETSTATIC", "PUTSTATIC",
"GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", "INVOKESPECIAL",
"INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC", "NEW",
"NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", "ATHROW", "CHECKCAST",
"INSTANCEOF", "MONITORENTER", "MONITOREXIT", "WIDE",
"MULTIANEWARRAY", "IFNULL", "IFNONNULL", "GOTO_W", "JSR_W" };
private static String[] opcodes = new String[]{"NOP", "ACONST_NULL",
"ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3",
"ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0",
"FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH",
"LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD",
"ALOAD", "ILOAD_0", "ILOAD_1", "ILOAD_2", "ILOAD_3", "LLOAD_0",
"LLOAD_1", "LLOAD_2", "LLOAD_3", "FLOAD_0", "FLOAD_1", "FLOAD_2",
"FLOAD_3", "DLOAD_0", "DLOAD_1", "DLOAD_2", "DLOAD_3", "ALOAD_0",
"ALOAD_1", "ALOAD_2", "ALOAD_3", "IALOAD", "LALOAD", "FALOAD",
"DALOAD", "AALOAD", "BALOAD", "CALOAD", "SALOAD", "ISTORE",
"LSTORE", "FSTORE", "DSTORE", "ASTORE", "ISTORE_0", "ISTORE_1",
"ISTORE_2", "ISTORE_3", "LSTORE_0", "LSTORE_1", "LSTORE_2",
"LSTORE_3", "FSTORE_0", "FSTORE_1", "FSTORE_2", "FSTORE_3",
"DSTORE_0", "DSTORE_1", "DSTORE_2", "DSTORE_3", "ASTORE_0",
"ASTORE_1", "ASTORE_2", "ASTORE_3", "IASTORE", "LASTORE",
"FASTORE", "DASTORE", "AASTORE", "BASTORE", "CASTORE", "SASTORE",
"POP", "POP2", "DUP", "DUP_X1", "DUP_X2", "DUP2", "DUP2_X1",
"DUP2_X2", "SWAP", "IADD", "LADD", "FADD", "DADD", "ISUB", "LSUB",
"FSUB", "DSUB", "IMUL", "LMUL", "FMUL", "DMUL", "IDIV", "LDIV",
"FDIV", "DDIV", "IREM", "LREM", "FREM", "DREM", "INEG", "LNEG",
"FNEG", "DNEG", "ISHL", "LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR",
"IAND", "LAND", "IOR", "LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F",
"I2D", "L2I", "L2F", "L2D", "F2I", "F2L", "F2D", "D2I", "D2L",
"D2F", "I2B", "I2C", "I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL",
"DCMPG", "IFEQ", "IFNE", "IFLT", "IFGE", "IFGT", "IFLE",
"IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT",
"IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE", "GOTO", "JSR", "RET",
"TABLESWITCH", "LOOKUPSWITCH", "IRETURN", "LRETURN", "FRETURN",
"DRETURN", "ARETURN", "RETURN", "GETSTATIC", "PUTSTATIC",
"GETFIELD", "PUTFIELD", "INVOKEVIRTUAL", "INVOKESPECIAL",
"INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC", "NEW",
"NEWARRAY", "ANEWARRAY", "ARRAYLENGTH", "ATHROW", "CHECKCAST",
"INSTANCEOF", "MONITORENTER", "MONITOREXIT", "WIDE",
"MULTIANEWARRAY", "IFNULL", "IFNONNULL", "GOTO_W", "JSR_W"};
private static String[] opcodesVar = new String[] { "ILOAD", "LLOAD",
"FLOAD", "DLOAD", "ALOAD", "ISTORE", "LSTORE", "FSTORE", "DSTORE",
"ASTORE", "RET" };
private static String opcodeVars = buildRegexItems(opcodesVar);
private static String[] opcodesVar = new String[]{"ILOAD", "LLOAD",
"FLOAD", "DLOAD", "ALOAD", "ISTORE", "LSTORE", "FSTORE", "DSTORE",
"ASTORE", "RET"};
private static String opcodeVars = buildRegexItems(opcodesVar);
private static String[] opcodesInt = new String[] { "BIPUSH", "SIPUSH",
"NEWARRAY" };
private static String opcodesInts = buildRegexItems(opcodesInt);
private static String[] opcodesInt = new String[]{"BIPUSH", "SIPUSH",
"NEWARRAY"};
private static String opcodesInts = buildRegexItems(opcodesInt);
private static String[] opcodesField = new String[] { "GETSTATIC",
"PUTSTATIC", "GETFIELD", "PUTFIELD" };
private static String opcodesFields = buildRegexItems(opcodesField);
private static String[] opcodesField = new String[]{"GETSTATIC",
"PUTSTATIC", "GETFIELD", "PUTFIELD"};
private static String opcodesFields = buildRegexItems(opcodesField);
private static String[] opcodesMethod = new String[] { "INVOKEVIRTUAL",
"INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC" };
private static String opcodesMethods = buildRegexItems(opcodesMethod);
private static String[] opcodesMethod = new String[]{"INVOKEVIRTUAL",
"INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE", "INVOKEDYNAMIC"};
private static String opcodesMethods = buildRegexItems(opcodesMethod);
private static String[] opcodesType = new String[] { "NEW", "ANEWARRAY",
"ARRAYLENGTH", "CHECKCAST", "INSTANCEOF" };
private static String opcodesTypes = buildRegexItems(opcodesType);
private static String[] opcodesType = new String[]{"NEW", "ANEWARRAY",
"ARRAYLENGTH", "CHECKCAST", "INSTANCEOF"};
private static String opcodesTypes = buildRegexItems(opcodesType);
private static String[] opcodesIf = new String[] { "IFEQ", "IFNE", "IFLT",
"IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT",
"IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE" };
private static String opcodesIfs = buildRegexItems(opcodesIf, false, false);
private static String[] opcodesIf = new String[]{"IFEQ", "IFNE", "IFLT",
"IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE", "IF_ICMPLT",
"IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ", "IF_ACMPNE"};
private static String opcodesIfs = buildRegexItems(opcodesIf, false, false);
private static String[] opcodesAny = new String[] { "NOP", "ACONST_NULL",
"ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3",
"ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0",
"FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH",
"LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD",
"ALOAD", "IALOAD", "LALOAD", "FALOAD", "DALOAD", "AALOAD",
"BALOAD", "CALOAD", "SALOAD", "ISTORE", "LSTORE", "FSTORE",
"DSTORE", "ASTORE", "IASTORE", "LASTORE", "FASTORE", "DASTORE",
"AASTORE", "BASTORE", "CASTORE", "SASTORE", "POP", "POP2", "DUP",
"DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", "DUP2_X2", "SWAP", "IADD",
"LADD", "FADD", "DADD", "ISUB", "LSUB", "FSUB", "DSUB", "IMUL",
"LMUL", "FMUL", "DMUL", "IDIV", "LDIV", "FDIV", "DDIV", "IREM",
"LREM", "FREM", "DREM", "INEG", "LNEG", "FNEG", "DNEG", "ISHL",
"LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", "IAND", "LAND", "IOR",
"LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", "I2D", "L2I", "L2F",
"L2D", "F2I", "F2L", "F2D", "D2I", "D2L", "D2F", "I2B", "I2C",
"I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", "DCMPG", "IFEQ", "IFNE",
"IFLT", "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE",
"IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ",
"IF_ACMPNE", "GOTO", "JSR", "RET", "TABLESWITCH", "LOOKUPSWITCH",
"IRETURN", "LRETURN", "FRETURN", "DRETURN", "ARETURN", "RETURN",
"GETSTATIC", "PUTSTATIC", "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL",
"INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE",
"INVOKEDYNAMIC", "NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH",
"ATHROW", "CHECKCAST", "INSTANCEOF", "MONITORENTER", "MONITOREXIT",
"MULTIANEWARRAY", "IFNULL", "IFNONNULL" };
private static String opcodesAnys = buildRegexItems(opcodesAny, false,
false);
private static String[] opcodesAny = new String[]{"NOP", "ACONST_NULL",
"ICONST_M1", "ICONST_0", "ICONST_1", "ICONST_2", "ICONST_3",
"ICONST_4", "ICONST_5", "LCONST_0", "LCONST_1", "FCONST_0",
"FCONST_1", "FCONST_2", "DCONST_0", "DCONST_1", "BIPUSH", "SIPUSH",
"LDC", "LDC_W", "LDC2_W", "ILOAD", "LLOAD", "FLOAD", "DLOAD",
"ALOAD", "IALOAD", "LALOAD", "FALOAD", "DALOAD", "AALOAD",
"BALOAD", "CALOAD", "SALOAD", "ISTORE", "LSTORE", "FSTORE",
"DSTORE", "ASTORE", "IASTORE", "LASTORE", "FASTORE", "DASTORE",
"AASTORE", "BASTORE", "CASTORE", "SASTORE", "POP", "POP2", "DUP",
"DUP_X1", "DUP_X2", "DUP2", "DUP2_X1", "DUP2_X2", "SWAP", "IADD",
"LADD", "FADD", "DADD", "ISUB", "LSUB", "FSUB", "DSUB", "IMUL",
"LMUL", "FMUL", "DMUL", "IDIV", "LDIV", "FDIV", "DDIV", "IREM",
"LREM", "FREM", "DREM", "INEG", "LNEG", "FNEG", "DNEG", "ISHL",
"LSHL", "ISHR", "LSHR", "IUSHR", "LUSHR", "IAND", "LAND", "IOR",
"LOR", "IXOR", "LXOR", "IINC", "I2L", "I2F", "I2D", "L2I", "L2F",
"L2D", "F2I", "F2L", "F2D", "D2I", "D2L", "D2F", "I2B", "I2C",
"I2S", "LCMP", "FCMPL", "FCMPG", "DCMPL", "DCMPG", "IFEQ", "IFNE",
"IFLT", "IFGE", "IFGT", "IFLE", "IF_ICMPEQ", "IF_ICMPNE",
"IF_ICMPLT", "IF_ICMPGE", "IF_ICMPGT", "IF_ICMPLE", "IF_ACMPEQ",
"IF_ACMPNE", "GOTO", "JSR", "RET", "TABLESWITCH", "LOOKUPSWITCH",
"IRETURN", "LRETURN", "FRETURN", "DRETURN", "ARETURN", "RETURN",
"GETSTATIC", "PUTSTATIC", "GETFIELD", "PUTFIELD", "INVOKEVIRTUAL",
"INVOKESPECIAL", "INVOKESTATIC", "INVOKEINTERFACE",
"INVOKEDYNAMIC", "NEW", "NEWARRAY", "ANEWARRAY", "ARRAYLENGTH",
"ATHROW", "CHECKCAST", "INSTANCEOF", "MONITORENTER", "MONITOREXIT",
"MULTIANEWARRAY", "IFNULL", "IFNONNULL"};
private static String opcodesAnys = buildRegexItems(opcodesAny, false,
false);
private static String buildRegexItems(final String[] items,
final boolean capture, final boolean stdRepl) {
if (items.length == 0)
return "()";
String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:")
+ items[0];
for (int i = 1; i < items.length; i++) {
result += "|" + items[i];
}
result += ")";
return result;
}
private static String buildRegexItems(final String[] items,
final boolean capture, final boolean stdRepl) {
if (items.length == 0)
return "()";
String result = (stdRepl ? "\\b" : "") + "(" + (capture ? "" : "?:")
+ items[0];
for (int i = 1; i < items.length; i++) {
result += "|" + items[i];
}
result += ")";
return result;
}
private static String buildRegexItems(final String[] items) {
return buildRegexItems(items, true, true);
}
private static String buildRegexItems(final String[] items) {
return buildRegexItems(items, true, true);
}
public static String processRegex(final String regex) {
String result = regex.trim();
result = result.replaceAll("\\bANYINSN *", opcodesAnys);
result = result.replaceAll(opcodesInts
+ "\\\\\\{\\s*(\\d+)\\s*\\\\\\} *", "$1\\\\{$2\\\\} ");
result = result.replaceAll(opcodesInts + " *", "$1\\\\{\\\\d+\\\\} ");
result = result.replaceAll(
"\\bLDC\\\\\\{(.*?)\\\\\\}(?<!\\\\\\\\\\}) *",
"LDC\\\\{$1\\\\}(?<!\\\\\\\\\\\\}) ");
result = result.replaceAll("\\bLDC *",
"LDC\\\\{.*?\\\\}(?<!\\\\\\\\\\\\}) ");
result = result.replaceAll(opcodeVars + "(_\\d+) *", "$1$2 ");
result = result.replaceAll(opcodeVars + "(?!_) *", "$1_\\\\d+ ");
result = result.replaceAll(
"\\bIINC\\\\\\{\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\\\\\} *",
"IINC\\\\{$1,$2\\\\} ");
result = result.replaceAll("\\bIINC\\\\\\{\\s*(\\d+)\\s*\\\\\\} *",
"IINC\\\\{\\d+,$1\\\\} ");
result = result.replaceAll("\\bIINC *", "IINC\\\\{\\d+,\\d+\\\\} ");
result = result.replaceAll(opcodesFields
+ "\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"$1\\\\{$2,$3,$4\\\\} ");
result = result.replaceAll(opcodesFields
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesFields + " *", "$1\\\\{.*?\\\\} ");
result = result.replaceAll(opcodesMethods
+ "\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"$1\\\\{$2,$3,$4\\\\} ");
result = result.replaceAll(opcodesMethods
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesMethods + " *",
"$1\\\\{.*?,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesTypes
+ "\\\\\\{\\s*(.*?)\\s*\\\\\\} +", "$1\\\\{$2\\\\} ");
result = result.replaceAll(opcodesTypes + " +", "$1\\\\{\\\\.*?\\\\} ");
result = result
.replaceAll(
"\\bMULTIANEWARRAY\\\\\\{\\s*(\\d+)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"MULTIANEWARRAY\\\\{$1,$2\\\\} ");
result = result.replaceAll(
"\\bMULTIANEWARRAY\\\\\\{\\s*(.*?)\\s*\\\\\\} *",
"MULTIANEWARRAY\\\\{\\d+,$1\\\\} ");
result = result.replaceAll("\\bMULTIANEWARRAY *",
"MULTIANEWARRAY\\\\{\\\\\\d+,.*?\\\\} ");
result = result.replaceAll("\\bIFINSN *", opcodesIfs + " ");
return result;
}
public static String processRegex(final String regex) {
String result = regex.trim();
result = result.replaceAll("\\bANYINSN *", opcodesAnys);
result = result.replaceAll(opcodesInts
+ "\\\\\\{\\s*(\\d+)\\s*\\\\\\} *", "$1\\\\{$2\\\\} ");
result = result.replaceAll(opcodesInts + " *", "$1\\\\{\\\\d+\\\\} ");
result = result.replaceAll(
"\\bLDC\\\\\\{(.*?)\\\\\\}(?<!\\\\\\\\\\}) *",
"LDC\\\\{$1\\\\}(?<!\\\\\\\\\\\\}) ");
result = result.replaceAll("\\bLDC *",
"LDC\\\\{.*?\\\\}(?<!\\\\\\\\\\\\}) ");
result = result.replaceAll(opcodeVars + "(_\\d+) *", "$1$2 ");
result = result.replaceAll(opcodeVars + "(?!_) *", "$1_\\\\d+ ");
result = result.replaceAll(
"\\bIINC\\\\\\{\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\\\\\} *",
"IINC\\\\{$1,$2\\\\} ");
result = result.replaceAll("\\bIINC\\\\\\{\\s*(\\d+)\\s*\\\\\\} *",
"IINC\\\\{\\d+,$1\\\\} ");
result = result.replaceAll("\\bIINC *", "IINC\\\\{\\d+,\\d+\\\\} ");
result = result.replaceAll(opcodesFields
+ "\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"$1\\\\{$2,$3,$4\\\\} ");
result = result.replaceAll(opcodesFields
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesFields + " *", "$1\\\\{.*?\\\\} ");
result = result.replaceAll(opcodesMethods
+ "\\\\\\{\\s*(.*?)\\s*,\\s*(.*?)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"$1\\\\{$2,$3,$4\\\\} ");
result = result.replaceAll(opcodesMethods
+ "\\\\\\{((?:.(?!,))*)\\\\\\} *", "$1\\\\{$2,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesMethods + " *",
"$1\\\\{.*?,.*?,.*?\\\\} ");
result = result.replaceAll(opcodesTypes
+ "\\\\\\{\\s*(.*?)\\s*\\\\\\} +", "$1\\\\{$2\\\\} ");
result = result.replaceAll(opcodesTypes + " +", "$1\\\\{\\\\.*?\\\\} ");
result = result
.replaceAll(
"\\bMULTIANEWARRAY\\\\\\{\\s*(\\d+)\\s*,\\s*(.*?)\\s*\\\\\\} *",
"MULTIANEWARRAY\\\\{$1,$2\\\\} ");
result = result.replaceAll(
"\\bMULTIANEWARRAY\\\\\\{\\s*(.*?)\\s*\\\\\\} *",
"MULTIANEWARRAY\\\\{\\d+,$1\\\\} ");
result = result.replaceAll("\\bMULTIANEWARRAY *",
"MULTIANEWARRAY\\\\{\\\\\\d+,.*?\\\\} ");
result = result.replaceAll("\\bIFINSN *", opcodesIfs + " ");
return result;
}
private MethodNode mn;
private AbstractInsnNode[] origInstructions;
private AbstractInsnNode[] instructions;
private int[] offsets;
private String insnString;
private MethodNode mn;
private AbstractInsnNode[] origInstructions;
private AbstractInsnNode[] instructions;
private int[] offsets;
private String insnString;
public RegexInsnFinder(final ClassNode clazz, final MethodNode method) {
setMethod(clazz, method);
}
private AbstractInsnNode[] cleanInsn(final InsnList insnList) {
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
public RegexInsnFinder(final ClassNode clazz, final MethodNode method) {
setMethod(clazz, method);
}
final Iterator<AbstractInsnNode> iIt = insnList.iterator();
while (iIt.hasNext()) {
final AbstractInsnNode node = iIt.next();
if (node.getOpcode() >= 0) {
il.add(node);
}
}
return il.toArray(new AbstractInsnNode[il.size()]);
}
private AbstractInsnNode[] cleanInsn(final InsnList insnList) {
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
/**
* Refreshes the internal instruction list when you have made changes to the
* method.
*/
public void refresh() {
origInstructions = cleanInsn(mn.instructions);
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
for (final AbstractInsnNode ain : mn.instructions.toArray())
if (ain.getOpcode() >= 0) {
il.add(ain);
}
instructions = il.toArray(new AbstractInsnNode[il.size()]);
offsets = new int[instructions.length];
insnString = "";
for (int i = 0; i < instructions.length; i++) {
offsets[i] = -1;
final AbstractInsnNode ain = instructions[i];
if (ain.getOpcode() >= 0) {
if (ain.getOpcode() >= opcodes.length) {
try {
throw new UnexpectedException(
"Unknown opcode encountered: "
+ ain.getOpcode());
} catch (final UnexpectedException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
offsets[i] = insnString.length();
insnString += opcodes[ain.getOpcode()];
switch (ain.getType()) {
case AbstractInsnNode.INT_INSN:
final IntInsnNode iin = (IntInsnNode) ain;
insnString += "{" + iin.operand + "}";
break;
case AbstractInsnNode.LDC_INSN:
final LdcInsnNode lin = (LdcInsnNode) ain;
insnString += "{" + lin.cst.toString().replace("}", "\\}")
+ "}";
break;
case AbstractInsnNode.VAR_INSN:
final VarInsnNode vin = (VarInsnNode) ain;
insnString += "_" + vin.var;
break;
case AbstractInsnNode.IINC_INSN:
final IincInsnNode iiin = (IincInsnNode) ain;
insnString += "{" + iiin.var + "," + iiin.incr + "}";
break;
case AbstractInsnNode.FIELD_INSN:
final FieldInsnNode fin = (FieldInsnNode) ain;
insnString += "{" + fin.desc + "," + fin.owner + ","
+ fin.name + "}";
break;
case AbstractInsnNode.METHOD_INSN:
final MethodInsnNode min = (MethodInsnNode) ain;
insnString += "{" + min.desc + "," + min.owner + ","
+ min.name + "}";
break;
case AbstractInsnNode.TYPE_INSN:
final TypeInsnNode tin = (TypeInsnNode) ain;
insnString += "{" + tin.desc + "}";
break;
case AbstractInsnNode.MULTIANEWARRAY_INSN:
final MultiANewArrayInsnNode manain = (MultiANewArrayInsnNode) ain;
insnString += "{" + manain.dims + "," + manain.desc + "}";
break;
}
insnString += " ";
}
}
}
final Iterator<AbstractInsnNode> iIt = insnList.iterator();
while (iIt.hasNext()) {
final AbstractInsnNode node = iIt.next();
if (node.getOpcode() >= 0) {
il.add(node);
}
}
return il.toArray(new AbstractInsnNode[il.size()]);
}
public void setMethod(final ClassNode ci, final MethodNode mi) {
this.mn = mi;
refresh();
}
/**
* Refreshes the internal instruction list when you have made changes to the
* method.
*/
public void refresh() {
origInstructions = cleanInsn(mn.instructions);
final List<AbstractInsnNode> il = new ArrayList<AbstractInsnNode>();
for (final AbstractInsnNode ain : mn.instructions.toArray())
if (ain.getOpcode() >= 0) {
il.add(ain);
}
instructions = il.toArray(new AbstractInsnNode[il.size()]);
offsets = new int[instructions.length];
insnString = "";
for (int i = 0; i < instructions.length; i++) {
offsets[i] = -1;
final AbstractInsnNode ain = instructions[i];
if (ain.getOpcode() >= 0) {
if (ain.getOpcode() >= opcodes.length) {
try {
throw new UnexpectedException(
"Unknown opcode encountered: "
+ ain.getOpcode());
} catch (final UnexpectedException e) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(e);
}
}
offsets[i] = insnString.length();
insnString += opcodes[ain.getOpcode()];
switch (ain.getType()) {
case AbstractInsnNode.INT_INSN:
final IntInsnNode iin = (IntInsnNode) ain;
insnString += "{" + iin.operand + "}";
break;
case AbstractInsnNode.LDC_INSN:
final LdcInsnNode lin = (LdcInsnNode) ain;
insnString += "{" + lin.cst.toString().replace("}", "\\}")
+ "}";
break;
case AbstractInsnNode.VAR_INSN:
final VarInsnNode vin = (VarInsnNode) ain;
insnString += "_" + vin.var;
break;
case AbstractInsnNode.IINC_INSN:
final IincInsnNode iiin = (IincInsnNode) ain;
insnString += "{" + iiin.var + "," + iiin.incr + "}";
break;
case AbstractInsnNode.FIELD_INSN:
final FieldInsnNode fin = (FieldInsnNode) ain;
insnString += "{" + fin.desc + "," + fin.owner + ","
+ fin.name + "}";
break;
case AbstractInsnNode.METHOD_INSN:
final MethodInsnNode min = (MethodInsnNode) ain;
insnString += "{" + min.desc + "," + min.owner + ","
+ min.name + "}";
break;
case AbstractInsnNode.TYPE_INSN:
final TypeInsnNode tin = (TypeInsnNode) ain;
insnString += "{" + tin.desc + "}";
break;
case AbstractInsnNode.MULTIANEWARRAY_INSN:
final MultiANewArrayInsnNode manain = (MultiANewArrayInsnNode) ain;
insnString += "{" + manain.dims + "," + manain.desc + "}";
break;
default:
throw new IllegalArgumentException(String.valueOf(ain.getType()));
}
insnString += " ";
}
}
}
private AbstractInsnNode[] makeResult(final int start, final int end) {
int startIndex = 0;
int endIndex = -1;
for (int i = 0; i < offsets.length - 1; i++) {
final int offset = offsets[i];
if (offset == start) {
startIndex = i;
}
if ((offset < end) && (offsets[i + 1] >= end)) {
endIndex = i;
break;
}
}
if (endIndex == -1) {
endIndex = offsets.length - 1;
}
final int length = endIndex - startIndex + 1;
final AbstractInsnNode[] result = new AbstractInsnNode[length];
System.arraycopy(origInstructions, startIndex, result, 0, length);
return result;
}
public void setMethod(final ClassNode ci, final MethodNode mi) {
this.mn = mi;
refresh();
}
/**
* Searches for a regex in the instruction list and returns the first match.
*
* @param regex
* the regular expression
* @return the matching instructions
*/
public AbstractInsnNode[] find(final String regex) {
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find())
return makeResult(regexMatcher.start(), regexMatcher.end());
} catch (final PatternSyntaxException ex) {
//ignore, they fucked up regex
}
return new AbstractInsnNode[0];
}
private AbstractInsnNode[] makeResult(final int start, final int end) {
int startIndex = 0;
int endIndex = -1;
for (int i = 0; i < offsets.length - 1; i++) {
final int offset = offsets[i];
if (offset == start) {
startIndex = i;
}
if ((offset < end) && (offsets[i + 1] >= end)) {
endIndex = i;
break;
}
}
if (endIndex == -1) {
endIndex = offsets.length - 1;
}
final int length = endIndex - startIndex + 1;
final AbstractInsnNode[] result = new AbstractInsnNode[length];
System.arraycopy(origInstructions, startIndex, result, 0, length);
return result;
}
/**
* Searches a regex in an instruction list and returns all matches.
*
* @param regex
* the regular expression
* @return a list with all sets of matching instructions
*/
public List<AbstractInsnNode[]> findAll(final String regex) {
final List<AbstractInsnNode[]> results = new ArrayList<AbstractInsnNode[]>();
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
while (regexMatcher.find()) {
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return results;
}
/**
* Searches for a regex in the instruction list and returns the first match.
*
* @param regex
* the regular expression
* @return the matching instructions
*/
public AbstractInsnNode[] find(final String regex) {
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find())
return makeResult(regexMatcher.start(), regexMatcher.end());
} catch (final PatternSyntaxException ex) {
//ignore, they fucked up regex
}
return new AbstractInsnNode[0];
}
/**
* Searches for a regex in the instruction list and returns all groups for
* the first match.
*
* @param regex
* the regular expression
* @return the groups with matching instructions
*/
public AbstractInsnNode[][] findGroups(final String regex) {
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find()) {
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
.groupCount() + 1][0];
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
result[i] = makeResult(regexMatcher.start(i),
regexMatcher.end(i));
}
return result;
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return new AbstractInsnNode[0][0];
}
/**
* Searches a regex in an instruction list and returns all matches.
*
* @param regex
* the regular expression
* @return a list with all sets of matching instructions
*/
public List<AbstractInsnNode[]> findAll(final String regex) {
final List<AbstractInsnNode[]> results = new ArrayList<AbstractInsnNode[]>();
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
while (regexMatcher.find()) {
results.add(makeResult(regexMatcher.start(), regexMatcher.end()));
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return results;
}
/**
* Searches for a regex in the instruction list and returns all groups for
* all matches.
*
* @param regex
* the regular expression
* @return a list with all sets of groups with matching instructions
*/
public List<AbstractInsnNode[][]> findAllGroups(final String regex) {
final List<AbstractInsnNode[][]> results = new ArrayList<AbstractInsnNode[][]>();
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find()) {
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
.groupCount() + 1][0];
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
result[i] = makeResult(regexMatcher.start(i),
regexMatcher.end(i));
}
results.add(result);
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return results;
}
/**
* Searches for a regex in the instruction list and returns all groups for
* the first match.
*
* @param regex
* the regular expression
* @return the groups with matching instructions
*/
public AbstractInsnNode[][] findGroups(final String regex) {
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find()) {
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
.groupCount() + 1][0];
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
result[i] = makeResult(regexMatcher.start(i),
regexMatcher.end(i));
}
return result;
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return new AbstractInsnNode[0][0];
}
/**
* Searches for a regex in the instruction list and returns all groups for
* all matches.
*
* @param regex
* the regular expression
* @return a list with all sets of groups with matching instructions
*/
public List<AbstractInsnNode[][]> findAllGroups(final String regex) {
final List<AbstractInsnNode[][]> results = new ArrayList<AbstractInsnNode[][]>();
try {
final Matcher regexMatcher = Pattern.compile(processRegex(regex),
Pattern.MULTILINE).matcher(insnString);
if (regexMatcher.find()) {
final AbstractInsnNode[][] result = new AbstractInsnNode[regexMatcher
.groupCount() + 1][0];
for (int i = 0; i <= regexMatcher.groupCount(); i++) {
result[i] = makeResult(regexMatcher.start(i),
regexMatcher.end(i));
}
results.add(result);
}
} catch (final PatternSyntaxException ex) {
new the.bytecode.club.bytecodeviewer.api.ExceptionUI(ex);
}
return results;
}
}

View file

@ -1,16 +1,15 @@
package the.bytecode.club.bytecodeviewer.searching;
import java.awt.GridLayout;
import java.util.Iterator;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.GridLayout;
import java.util.Iterator;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *

View file

@ -1,9 +1,9 @@
package the.bytecode.club.bytecodeviewer.searching;
import javax.swing.JPanel;
import org.objectweb.asm.tree.ClassNode;
import javax.swing.JPanel;
/***************************************************************************
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *