Beta 1.2, adds Procyon and CFR Decompilers

Beta 1.2, adds Procyon and CFR Decompilers
This commit is contained in:
Kalen Kinloch 2014-10-19 20:51:59 -07:00
parent f5ad6e449d
commit ac65fbf226

AI 샘플 코드 생성 중입니다

Loading...
12 changed files with 561 additions and 86 deletions

BIN
BytecodeViewer Beta 1.2.jar Normal file

Binary file not shown.

BIN
libs/cfr_0_88.jar Normal file

Binary file not shown.

Binary file not shown.

View File

@ -49,6 +49,23 @@ public class DiskReader {
} }
/**
* Used to load from file
*/
public synchronized static String loadAsString(String fileName) throws Exception {
String s = "";
BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));
String add;
while((add = reader.readLine()) != null)
s += add + System.getProperty("line.separator");
reader.close();
return s;
}
/** /**
* Used to load a string via line number * Used to load a string via line number
* lineNumber = -1 means random. * lineNumber = -1 means random.

View File

@ -114,6 +114,7 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
* 10/16/2014 - Now if you try search with an empty string, it won't search. * 10/16/2014 - Now if you try search with an empty string, it won't search.
* 10/16/2014 - Added Replace Strings plugin. * 10/16/2014 - Added Replace Strings plugin.
* 10/16/2014 - Added a loading icon that displays whenever a background task is being executed. * 10/16/2014 - Added a loading icon that displays whenever a background task is being executed.
* 10/19/2014 - Fixed harcoded \\.
* *
* @author Konloch * @author Konloch
* *
@ -130,6 +131,8 @@ public class BytecodeViewer {
private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false); private static ArrayList<String> recentPlugins = DiskReader.loadArrayList(pluginsName, false);
private static int maxRecentFiles = 25; private static int maxRecentFiles = 25;
public static String tempDirectory = "bcv_temp"; public static String tempDirectory = "bcv_temp";
public static String fs = System.getProperty("file.separator");
public static String nl = System.getProperty("line.separator");
public static void main(String[] args) { public static void main(String[] args) {
cleanup(); cleanup();
@ -313,11 +316,19 @@ public class BytecodeViewer {
public static void cleanup() { public static void cleanup() {
tempF = new File(tempDirectory); tempF = new File(tempDirectory);
try { try {
Thread.sleep(100);
FileUtils.deleteDirectory(tempF); FileUtils.deleteDirectory(tempF);
} catch (IOException e) { Thread.sleep(100);
e.printStackTrace(); } catch (Exception e) {
}
while(!tempF.exists()) { //keep making dirs
try {
tempF.mkdir();
Thread.sleep(100);
} catch (Exception e) {
}
} }
tempF.mkdir();
} }
private static String quickConvert(ArrayList<String> a) { private static String quickConvert(ArrayList<String> a) {

View File

@ -0,0 +1,188 @@
package the.bytecode.club.bytecodeviewer;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.swing.filechooser.FileFilter;
/**
* Rudimentary utility class for Zip archives creation.
*/
public final class ZipUtils {
private static final String ZIP_FILE_EXTENSION = ".zip";
private static final FileFilter ZIP_FILE_FILTER = new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(ZIP_FILE_EXTENSION);
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return null;
}
};
private ZipUtils() {
// Utility class, cannot be instantiated.
}
/**
* Compress the given root and all its underlying folders and files to the target file, preserving files hierarchy.
*
* @param root
* The root of the Zip archive
* @param target
* The target archive file (must be a valid Zip file name)
* @throws IOException
* If an error occurs during the process
*/
public static void zipDirectory(final File root, final File target) throws IOException {
if (!ZIP_FILE_FILTER.accept(target)) {
throw new IllegalArgumentException("Target file " + target.getName() + " is not a valid Zip file name");
}
byte[] buffer = new byte[1024];
FileOutputStream fileOutputStream = null;
ZipOutputStream zipOutputStream = null;
try {
fileOutputStream = new FileOutputStream(target);
zipOutputStream = new ZipOutputStream(fileOutputStream);
FileInputStream fileInputStream = null;
for (File file : ZipUtils.listFilesRecursive(root)) {
ZipEntry entry = new ZipEntry(ZipUtils.stripRootInclusive(file, root).getPath());
zipOutputStream.putNextEntry(entry);
try {
fileInputStream = new FileInputStream(file);
int length;
while ((length = fileInputStream.read(buffer)) > 0) {
zipOutputStream.write(buffer, 0, length);
}
} finally {
fileInputStream.close();
}
zipOutputStream.closeEntry();
}
} finally {
zipOutputStream.close();
}
}
/**
* Unzip the given archive Zip file to the target location. If target location is a file, the extraction will be
* performed in the same directory of this target file.
*
* @param zipFile
* The Zip archive file
* @param target
* The target location
* @throws IOException
* If an error occurs during the process
*/
public static void unzip(final File zipFile, File target) throws IOException {
if (zipFile == null) {
throw new IllegalArgumentException("Cannot unzip a null file!");
} else if (!ZIP_FILE_FILTER.accept(zipFile)) {
throw new IllegalArgumentException("Given archive is not a valid Zip file!");
}
if (target == null) {
throw new IllegalArgumentException("Cannot unzip to a null target!");
}
byte[] buffer = new byte[1024];
if (!target.exists()) {
target.mkdir();
} else if (target.isFile()) {
// Target is a file, will try to unzip in the same folder.
target = target.getParentFile();
if (target == null) {
throw new IllegalArgumentException("Target is a file and has no parent!");
}
}
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
try {
for (ZipEntry entry = zipInputStream.getNextEntry(); entry != null; entry = zipInputStream.getNextEntry()) {
File file = new File(target, entry.getName());
// Create parent folders (folders are not in the Zip entries).
new File(file.getParent()).mkdirs();
FileOutputStream fileOutputStream = new FileOutputStream(file);
try {
int length;
while ((length = zipInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, length);
}
} finally {
fileOutputStream.close();
}
zipInputStream.closeEntry();
}
} finally {
zipInputStream.close();
}
}
/**
* List all files and folders from the given root.
*
* @param root
* The root of the listing
* @return A list of the files under the given root
*/
public static List<File> listFilesRecursive(final File root) {
List<File> packedFiles = new ArrayList<File>();
File[] subFiles = root.listFiles();
if (subFiles == null) {
return packedFiles;
}
for (File file : subFiles) {
if (file.isFile()) {
File packedFile = new File(root, file.getName());
packedFiles.add(packedFile);
} else if (file.isDirectory()) {
packedFiles.addAll(ZipUtils.listFilesRecursive(file));
}
}
return packedFiles;
}
/**
* Strip the given file from any parent path, preserving the root as the absolute parent.
* <p>
* Ex. with 'Folder' as the root: /home/johnj/Test/Folder/File.txt => /Folder/File.txt
* </p>
*
* @param file
* The file to strip
* @param root
* The root of the stripping
* @return The stripped file
*/
private static File stripRootInclusive(final File file, final File root) {
String parentPath = root.getParent();
if (parentPath == null) {
// Assuming no existing parent.
return file;
}
return new File(file.getAbsolutePath().substring(parentPath.length()));
}
}

View File

@ -0,0 +1,105 @@
package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
public class CFRDecompiler extends JavaDecompiler {
@Override
public String decompileClassNode(ClassNode cn) {
final ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
int fileNumber = getClassNumber(fileStart, ".class");
final File tempClass = new File(fileStart+fileNumber+".class");
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
fos.write(cw.toByteArray());
fos.close();
} catch (final IOException e) {
e.printStackTrace();
}
String fuckery = fuckery(fileStart);
org.benf.cfr.reader.Main.main(generateMainMethod(tempClass.getAbsolutePath(), fuckery));
tempClass.delete();
for(File outputJava : new File(fuckery).listFiles()) {
String s;
try {
s = DiskReader.loadAsString(outputJava.getAbsolutePath());
outputJava.delete();
return s;
} catch (Exception e) {
e.printStackTrace();
}
}
return "CFR error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
}
Random r = new Random();
File f;
public String fuckery(String start) {
boolean b = false;
while(!b) {
f = new File(start+r.nextInt(Integer.MAX_VALUE));
if(!f.exists())
return f.toString();
}
return null;
}
public String[] generateMainMethod(String filePath, String outputPath) {
return new String[] {
filePath,
"--outputdir",
outputPath
};
}
@Override
public void decompileToZip(String zipName) {
/*
File tempZip = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
if(tempZip.exists())
tempZip.delete();
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
String fuckery = fuckery(fileStart);
org.benf.cfr.reader.Main.main(generateMainMethod(tempZip.getAbsolutePath(), fuckery));
tempZip.delete();
for(File f : new File(fuckery).listFiles()) {
//put contents into a zipfile
}*/
BytecodeViewer.showMessage("CFRDecompiler currently doesn't decompile as zip, please wait till 1.3 of Bytecode Viewer.");
}
}

View File

@ -1,11 +1,11 @@
package the.bytecode.club.bytecodeviewer.decompilers.java; package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
@ -20,8 +20,9 @@ import the.bytecode.club.bytecodeviewer.JarUtils;
* *
*/ */
public class FernFlowerDecompiler { public class FernFlowerDecompiler extends JavaDecompiler {
@Override
public void decompileToZip(String zipName) { public void decompileToZip(String zipName) {
File tempZip = new File(BytecodeViewer.tempDirectory + "temp.zip"); File tempZip = new File(BytecodeViewer.tempDirectory + "temp.zip");
if(tempZip.exists()) if(tempZip.exists())
@ -30,19 +31,20 @@ public class FernFlowerDecompiler {
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath()); JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
de.fernflower.main.decompiler.ConsoleDecompiler.main(new String[] {tempZip.getAbsolutePath(), BytecodeViewer.tempDirectory + "./temp/"}); de.fernflower.main.decompiler.ConsoleDecompiler.main(new String[] {tempZip.getAbsolutePath(), BytecodeViewer.tempDirectory + "./temp/"});
File tempZip2 = new File(BytecodeViewer.tempDirectory + System.getProperty("file.separator") + "temp" + System.getProperty("file.separator") +tempZip.getName()); File tempZip2 = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp" + BytecodeViewer.fs +tempZip.getName());
if(tempZip2.exists()) if(tempZip2.exists())
tempZip2.renameTo(new File(zipName)); tempZip2.renameTo(new File(zipName));
tempZip.delete(); tempZip.delete();
new File(BytecodeViewer.tempDirectory + System.getProperty("file.separator") + "temp").delete(); new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp").delete();
} }
@Override
public String decompileClassNode(final ClassNode cn) { public String decompileClassNode(final ClassNode cn) {
final ClassWriter cw = new ClassWriter(0); final ClassWriter cw = new ClassWriter(0);
cn.accept(cw); cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + System.getProperty("file.separator") + "temp"; String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
int fileNumber = getClassNumber(fileStart, ".class"); int fileNumber = getClassNumber(fileStart, ".class");
final File tempClass = new File(fileStart+fileNumber+".class"); final File tempClass = new File(fileStart+fileNumber+".class");
@ -63,80 +65,40 @@ public class FernFlowerDecompiler {
final File outputJava = new File("temp"+fileNumber+".java"); final File outputJava = new File("temp"+fileNumber+".java");
if (outputJava.exists()) { if (outputJava.exists()) {
String s;
final String nl = System.getProperty("line.separator"); try {
final StringBuffer javaSrc = new StringBuffer(); s = DiskReader.loadAsString(outputJava.getAbsolutePath());
try { outputJava.delete();
final BufferedReader br = new BufferedReader(new FileReader(outputJava));
String line; return s;
while ((line = br.readLine()) != null) { } catch (Exception e) {
javaSrc.append(line + nl); e.printStackTrace();
} }
br.close();
} catch (final IOException e) {
e.printStackTrace();
}
outputJava.delete();
return javaSrc.toString();
} }
return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com"; return "FernFlower error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
} }
File tempF = null;
public int getClassNumber(String start, String ext) {
boolean b = true;
int i = 0;
while(b) {
tempF = new File(start + i + ext);
if(!tempF.exists())
b = false;
else
i++;
}
return i;
}
private String[] generateMainMethod(String className, String folder) { private String[] generateMainMethod(String className, String folder) {
boolean rbr = BytecodeViewer.viewer.rbr.isSelected();
boolean rsy = BytecodeViewer.viewer.rsy.isSelected();
boolean din = BytecodeViewer.viewer.din.isSelected();
boolean dc4 = BytecodeViewer.viewer.dc4.isSelected();
boolean das = BytecodeViewer.viewer.das.isSelected();
boolean hes = BytecodeViewer.viewer.hes.isSelected();
boolean hdc = BytecodeViewer.viewer.hdc.isSelected();
boolean dgs = BytecodeViewer.viewer.dgs.isSelected();
boolean ner = BytecodeViewer.viewer.ner.isSelected();
boolean den = BytecodeViewer.viewer.den.isSelected();
boolean rgn = BytecodeViewer.viewer.rgn.isSelected();
boolean bto = BytecodeViewer.viewer.bto.isSelected();
boolean nns = BytecodeViewer.viewer.nns.isSelected();
boolean uto = BytecodeViewer.viewer.uto.isSelected();
boolean udv = BytecodeViewer.viewer.udv.isSelected();
boolean rer = BytecodeViewer.viewer.rer.isSelected();
boolean fdi = BytecodeViewer.viewer.fdi.isSelected();
boolean asc = BytecodeViewer.viewer.asc.isSelected();
return new String[] { return new String[] {
"-rbr="+r(rbr), "-rbr="+r(BytecodeViewer.viewer.rbr.isSelected()),
"-rsy="+r(rsy), "-rsy="+r(BytecodeViewer.viewer.rsy.isSelected()),
"-din="+r(din), "-din="+r(BytecodeViewer.viewer.din.isSelected()),
"-dc4="+r(dc4), "-dc4="+r(BytecodeViewer.viewer.dc4.isSelected()),
"-das="+r(das), "-das="+r(BytecodeViewer.viewer.das.isSelected()),
"-hes="+r(hes), "-hes="+r(BytecodeViewer.viewer.hes.isSelected()),
"-hdc="+r(hdc), "-hdc="+r(BytecodeViewer.viewer.hdc.isSelected()),
"-dgs="+r(dgs), "-dgs="+r(BytecodeViewer.viewer.dgs.isSelected()),
"-ner="+r(ner), "-ner="+r(BytecodeViewer.viewer.ner.isSelected()),
"-den="+r(den), "-den="+r(BytecodeViewer.viewer.den.isSelected()),
"-rgn="+r(rgn), "-rgn="+r(BytecodeViewer.viewer.rgn.isSelected()),
"-bto="+r(bto), "-bto="+r(BytecodeViewer.viewer.bto.isSelected()),
"-nns="+r(nns), "-nns="+r(BytecodeViewer.viewer.nns.isSelected()),
"-uto="+r(uto), "-uto="+r(BytecodeViewer.viewer.uto.isSelected()),
"-udv="+r(udv), "-udv="+r(BytecodeViewer.viewer.udv.isSelected()),
"-rer="+r(rer), "-rer="+r(BytecodeViewer.viewer.rer.isSelected()),
"-fdi="+r(fdi), "-fdi="+r(BytecodeViewer.viewer.fdi.isSelected()),
"-asc="+r(asc), "-asc="+r(BytecodeViewer.viewer.asc.isSelected()),
className, className,
folder}; folder};
} }

View File

@ -0,0 +1,25 @@
package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.File;
import org.objectweb.asm.tree.ClassNode;
public abstract class JavaDecompiler {
public abstract String decompileClassNode(ClassNode cn);
public abstract void decompileToZip(String zipName);
File tempF = null;
public int getClassNumber(String start, String ext) {
boolean b = true;
int i = 0;
while(b) {
tempF = new File(start + i + ext);
if(!tempF.exists())
b = false;
else
i++;
}
return i;
}
}

View File

@ -0,0 +1,125 @@
package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import me.konloch.kontainer.io.DiskReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import com.strobel.decompiler.Decompiler;
import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
public class ProcyonDecompiler extends JavaDecompiler {
@Override
public String decompileClassNode(ClassNode cn) {
try {
final ClassWriter cw = new ClassWriter(0);
cn.accept(cw);
String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp";
int fileNumber = getClassNumber(fileStart, ".class");
final File tempClass = new File(fileStart+fileNumber+".class");
try {
final FileOutputStream fos = new FileOutputStream(tempClass);
fos.write(cw.toByteArray());
fos.close();
} catch (final IOException e) {
e.printStackTrace();
}
File tempJava = new File(fileStart + getClassNumber(fileStart, ".java") + ".java");
final FileOutputStream stream = new FileOutputStream(tempJava);
try {
final OutputStreamWriter writer = new OutputStreamWriter(stream);
final PlainTextOutput p = new PlainTextOutput(writer);
try {
Decompiler.decompile(
cn.getClass().getCanonicalName(),
p,
DecompilerSettings.javaDefaults()
);
} finally {
writer.close();
}
}
finally {
stream.close();
}
String s = DiskReader.loadAsString(tempJava.getAbsolutePath());
tempJava.delete();
tempClass.delete();
return s;
}
catch (final Exception e) {
e.printStackTrace();
}
return "Procyon error! Send the stacktrace to Konloch at http://the.bytecode.club or konloch@gmail.com";
}
@Override
public void decompileToZip(String zipName) {
/*File tempZip = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
if(tempZip.exists())
tempZip.delete();
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
File zip = new File(zipName);
try {
final FileOutputStream stream = new FileOutputStream(zip);
try {
final OutputStreamWriter writer = new OutputStreamWriter(stream);
final PlainTextOutput p = new PlainTextOutput(writer);
try {
Decompiler.decompile(
tempZip.getAbsolutePath(),
p,
DecompilerSettings.javaDefaults()
);
} finally {
writer.close();
}
}
finally {
stream.close();
}
} catch(Exception e) {
e.printStackTrace();
}
File tempZip2 = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp" + BytecodeViewer.fs +tempZip.getName());
if(tempZip2.exists())
tempZip2.renameTo(new File(zipName));
tempZip.delete();
new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp").delete();*/
BytecodeViewer.showMessage("ProcyonDecompiler currently doesn't decompile as zip, please wait till 1.3 of Bytecode Viewer.");
}
}

View File

@ -35,7 +35,9 @@ import com.jhe.hexed.JHexEditor;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.BytecodeDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.bytecode.BytecodeDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.CFRDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.java.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.ProcyonDecompiler;
/** /**
* This represents the opened classfile. * This represents the opened classfile.
@ -173,17 +175,26 @@ public class ClassViewer extends JPanel {
sp2 = setDividerLocation(sp2, 1); sp2 = setDividerLocation(sp2, 1);
} }
} }
final BytecodeDecompiler bc_dc = new BytecodeDecompiler();
final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler();
final ProcyonDecompiler proc_dc = new ProcyonDecompiler();
final CFRDecompiler cfr_dc = new CFRDecompiler();
PaneUpdaterThread t; PaneUpdaterThread t;
public void startPaneUpdater() { public void startPaneUpdater() {
t = new PaneUpdaterThread(bytecode, decomp) { t = new PaneUpdaterThread(bytecode, decomp) {
String s = "";
@Override @Override
public void doShit() { public void doShit() {
final BytecodeDecompiler bc_dc = new BytecodeDecompiler();
final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler();
final String b = bc_dc.decompileClassNode(cn); final String b = bc_dc.decompileClassNode(cn);
final String s = ff_dc.decompileClassNode(cn);
if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.fernflowerDec.getModel()))
s = ff_dc.decompileClassNode(cn);
else if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.procyonDec.getModel()))
s = proc_dc.decompileClassNode(cn);
else if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.cfrDec.getModel()))
s = cfr_dc.decompileClassNode(cn);
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {

View File

@ -1,6 +1,7 @@
package the.bytecode.club.bytecodeviewer.gui; package the.bytecode.club.bytecodeviewer.gui;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JFrame; import javax.swing.JFrame;
@ -26,7 +27,10 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.FileChangeNotifier; import the.bytecode.club.bytecodeviewer.FileChangeNotifier;
import the.bytecode.club.bytecodeviewer.JarUtils; import the.bytecode.club.bytecodeviewer.JarUtils;
import the.bytecode.club.bytecodeviewer.decompilers.bytecode.BytecodeDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.CFRDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.FernFlowerDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.java.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.decompilers.java.ProcyonDecompiler;
import the.bytecode.club.bytecodeviewer.plugins.AllatoriStringDecrypter; import the.bytecode.club.bytecodeviewer.plugins.AllatoriStringDecrypter;
import the.bytecode.club.bytecodeviewer.plugins.PluginManager; import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
import the.bytecode.club.bytecodeviewer.plugins.ShowAllStrings; import the.bytecode.club.bytecodeviewer.plugins.ShowAllStrings;
@ -40,6 +44,8 @@ import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.JRadioButtonMenuItem;
public class MainViewerGUI extends JFrame implements FileChangeNotifier { public class MainViewerGUI extends JFrame implements FileChangeNotifier {
@ -94,7 +100,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
public JCheckBoxMenuItem chckbxmntmNewCheckItem = new JCheckBoxMenuItem("Allow only ASCII characters in strings"); public JCheckBoxMenuItem chckbxmntmNewCheckItem = new JCheckBoxMenuItem("Allow only ASCII characters in strings");
private final JMenuItem mntmReplaceStrings = new JMenuItem("Replace Strings"); private final JMenuItem mntmReplaceStrings = new JMenuItem("Replace Strings");
private final JMenuItem mntmNewMenuItem_4 = new JMenuItem(""); private final JMenuItem mntmNewMenuItem_4 = new JMenuItem("");
private final JMenu mnNewMenu_2 = new JMenu("Java Decompiler");
public final JRadioButtonMenuItem fernflowerDec = new JRadioButtonMenuItem("FernFlower");
public final JRadioButtonMenuItem procyonDec = new JRadioButtonMenuItem("Procyon");
public final JRadioButtonMenuItem cfrDec = new JRadioButtonMenuItem("CFR");
public final ButtonGroup decompilerGroup = new ButtonGroup();
public void setC(boolean busy) { public void setC(boolean busy) {
if(busy) { if(busy) {
this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
@ -165,8 +176,16 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
return image; return image;
} }
final BytecodeDecompiler bc_dc = new BytecodeDecompiler();
final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler();
final ProcyonDecompiler proc_dc = new ProcyonDecompiler();
final CFRDecompiler cfr_dc = new CFRDecompiler();
public MainViewerGUI() { public MainViewerGUI() {
decompilerGroup.add(fernflowerDec);
decompilerGroup.add(procyonDec);
decompilerGroup.add(cfrDec);
decompilerGroup.setSelected(procyonDec.getModel(), true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
rbr.setSelected(true); rbr.setSelected(true);
rsy.setSelected(false); rsy.setSelected(false);
@ -271,8 +290,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
if (returnVal == JFileChooser.APPROVE_OPTION) { if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile(); File file = fc.getSelectedFile();
BytecodeViewer.viewer.setC(true); BytecodeViewer.viewer.setC(true);
FernFlowerDecompiler d = new FernFlowerDecompiler(); if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.fernflowerDec.getModel()))
d.decompileToZip(file.getAbsolutePath()); ff_dc.decompileToZip(file.getAbsolutePath());
else if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.procyonDec.getModel()))
proc_dc.decompileToZip(file.getAbsolutePath());
else if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.cfrDec.getModel()))
cfr_dc.decompileToZip(file.getAbsolutePath());
BytecodeViewer.viewer.setC(false); BytecodeViewer.viewer.setC(false);
} }
} }
@ -311,7 +334,15 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier {
mnView.add(bycSyntax); mnView.add(bycSyntax);
JMenu mnDecompilerSettings = new JMenu("Java Decompiler"); menuBar.add(mnNewMenu_2);
mnNewMenu_2.add(procyonDec);
mnNewMenu_2.add(cfrDec);
mnNewMenu_2.add(fernflowerDec);
JMenu mnDecompilerSettings = new JMenu("FernFlower");
menuBar.add(mnDecompilerSettings); menuBar.add(mnDecompilerSettings);
mnDecompilerSettings.add(rbr); mnDecompilerSettings.add(rbr);
mnDecompilerSettings.add(rsy); mnDecompilerSettings.add(rsy);