diff --git a/BytecodeViewer Beta 1.2.jar b/BytecodeViewer Beta 1.2.jar new file mode 100644 index 00000000..c9737be1 Binary files /dev/null and b/BytecodeViewer Beta 1.2.jar differ diff --git a/libs/cfr_0_88.jar b/libs/cfr_0_88.jar new file mode 100644 index 00000000..a4694d34 Binary files /dev/null and b/libs/cfr_0_88.jar differ diff --git a/libs/procyon-decompiler-0.5.26.jar b/libs/procyon-decompiler-0.5.26.jar new file mode 100644 index 00000000..af340304 Binary files /dev/null and b/libs/procyon-decompiler-0.5.26.jar differ diff --git a/src/me/konloch/kontainer/io/DiskReader.java b/src/me/konloch/kontainer/io/DiskReader.java index d330f863..f4d6dfc5 100644 --- a/src/me/konloch/kontainer/io/DiskReader.java +++ b/src/me/konloch/kontainer/io/DiskReader.java @@ -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 * lineNumber = -1 means random. diff --git a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index 6fdec9c4..679116c1 100644 --- a/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -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 - Added Replace Strings plugin. * 10/16/2014 - Added a loading icon that displays whenever a background task is being executed. + * 10/19/2014 - Fixed harcoded \\. * * @author Konloch * @@ -130,6 +131,8 @@ public class BytecodeViewer { private static ArrayList recentPlugins = DiskReader.loadArrayList(pluginsName, false); private static int maxRecentFiles = 25; 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) { cleanup(); @@ -313,11 +316,19 @@ public class BytecodeViewer { public static void cleanup() { tempF = new File(tempDirectory); try { + Thread.sleep(100); FileUtils.deleteDirectory(tempF); - } catch (IOException e) { - e.printStackTrace(); + Thread.sleep(100); + } 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 a) { diff --git a/src/the/bytecode/club/bytecodeviewer/ZipUtils.java b/src/the/bytecode/club/bytecodeviewer/ZipUtils.java new file mode 100644 index 00000000..a593817f --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/ZipUtils.java @@ -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 listFilesRecursive(final File root) { + List packedFiles = new ArrayList(); + + 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. + *

+ * Ex. with 'Folder' as the root: /home/johnj/Test/Folder/File.txt => /Folder/File.txt + *

+ * + * @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())); + } +} \ No newline at end of file diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java new file mode 100644 index 00000000..3294042b --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/CFRDecompiler.java @@ -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."); + + } + +} diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java index 04771491..d2e06d67 100644 --- a/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/FernFlowerDecompiler.java @@ -1,11 +1,11 @@ package the.bytecode.club.bytecodeviewer.decompilers.java; -import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; -import java.io.FileReader; import java.io.IOException; +import me.konloch.kontainer.io.DiskReader; + import org.objectweb.asm.ClassWriter; 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) { File tempZip = new File(BytecodeViewer.tempDirectory + "temp.zip"); if(tempZip.exists()) @@ -30,19 +31,20 @@ public class FernFlowerDecompiler { JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath()); 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()) tempZip2.renameTo(new File(zipName)); 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) { final ClassWriter cw = new ClassWriter(0); cn.accept(cw); - String fileStart = BytecodeViewer.tempDirectory + System.getProperty("file.separator") + "temp"; + String fileStart = BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp"; int fileNumber = getClassNumber(fileStart, ".class"); final File tempClass = new File(fileStart+fileNumber+".class"); @@ -63,80 +65,40 @@ public class FernFlowerDecompiler { final File outputJava = new File("temp"+fileNumber+".java"); if (outputJava.exists()) { - - final String nl = System.getProperty("line.separator"); - final StringBuffer javaSrc = new StringBuffer(); - - try { - final BufferedReader br = new BufferedReader(new FileReader(outputJava)); - String line; - while ((line = br.readLine()) != null) { - javaSrc.append(line + nl); - } - br.close(); - } catch (final IOException e) { - e.printStackTrace(); - } - - outputJava.delete(); - - return javaSrc.toString(); + String s; + try { + s = DiskReader.loadAsString(outputJava.getAbsolutePath()); + + outputJava.delete(); + + return s; + } catch (Exception e) { + e.printStackTrace(); + } } 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) { - 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[] { - "-rbr="+r(rbr), - "-rsy="+r(rsy), - "-din="+r(din), - "-dc4="+r(dc4), - "-das="+r(das), - "-hes="+r(hes), - "-hdc="+r(hdc), - "-dgs="+r(dgs), - "-ner="+r(ner), - "-den="+r(den), - "-rgn="+r(rgn), - "-bto="+r(bto), - "-nns="+r(nns), - "-uto="+r(uto), - "-udv="+r(udv), - "-rer="+r(rer), - "-fdi="+r(fdi), - "-asc="+r(asc), + "-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()), className, folder}; } diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/JavaDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/JavaDecompiler.java new file mode 100644 index 00000000..c8123a6c --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/JavaDecompiler.java @@ -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; + } +} diff --git a/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java b/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java new file mode 100644 index 00000000..23971a56 --- /dev/null +++ b/src/the/bytecode/club/bytecodeviewer/decompilers/java/ProcyonDecompiler.java @@ -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."); + + } + +} diff --git a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java index 4703fa67..f563c469 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/ClassViewer.java @@ -35,7 +35,9 @@ import com.jhe.hexed.JHexEditor; import the.bytecode.club.bytecodeviewer.BytecodeViewer; 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.ProcyonDecompiler; /** * This represents the opened classfile. @@ -173,17 +175,26 @@ public class ClassViewer extends JPanel { 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; public void startPaneUpdater() { t = new PaneUpdaterThread(bytecode, decomp) { + String s = ""; @Override public void doShit() { - final BytecodeDecompiler bc_dc = new BytecodeDecompiler(); - final FernFlowerDecompiler ff_dc = new FernFlowerDecompiler(); 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() { public void run() { diff --git a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java index ced5664a..cbd6a156 100644 --- a/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java +++ b/src/the/bytecode/club/bytecodeviewer/gui/MainViewerGUI.java @@ -1,6 +1,7 @@ package the.bytecode.club.bytecodeviewer.gui; import javax.imageio.ImageIO; +import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JFileChooser; 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.FileChangeNotifier; 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.ProcyonDecompiler; import the.bytecode.club.bytecodeviewer.plugins.AllatoriStringDecrypter; import the.bytecode.club.bytecodeviewer.plugins.PluginManager; import the.bytecode.club.bytecodeviewer.plugins.ShowAllStrings; @@ -40,6 +44,8 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.util.ArrayList; +import javax.swing.JRadioButtonMenuItem; + 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"); private final JMenuItem mntmReplaceStrings = new JMenuItem("Replace Strings"); 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) { if(busy) { this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); @@ -165,8 +176,16 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { 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() { + decompilerGroup.add(fernflowerDec); + decompilerGroup.add(procyonDec); + decompilerGroup.add(cfrDec); + decompilerGroup.setSelected(procyonDec.getModel(), true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); rbr.setSelected(true); rsy.setSelected(false); @@ -271,8 +290,12 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { if (returnVal == JFileChooser.APPROVE_OPTION) { File file = fc.getSelectedFile(); BytecodeViewer.viewer.setC(true); - FernFlowerDecompiler d = new FernFlowerDecompiler(); - d.decompileToZip(file.getAbsolutePath()); + if(BytecodeViewer.viewer.decompilerGroup.isSelected(BytecodeViewer.viewer.fernflowerDec.getModel())) + 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); } } @@ -311,7 +334,15 @@ public class MainViewerGUI extends JFrame implements FileChangeNotifier { 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); mnDecompilerSettings.add(rbr); mnDecompilerSettings.add(rsy);