Beta 1.2, adds Procyon and CFR Decompilers
Beta 1.2, adds Procyon and CFR Decompilers
This commit is contained in:
parent
f5ad6e449d
commit
ac65fbf226
12 changed files with 561 additions and 86 deletions
BIN
BytecodeViewer Beta 1.2.jar
Normal file
BIN
BytecodeViewer Beta 1.2.jar
Normal file
Binary file not shown.
BIN
libs/cfr_0_88.jar
Normal file
BIN
libs/cfr_0_88.jar
Normal file
Binary file not shown.
BIN
libs/procyon-decompiler-0.5.26.jar
Normal file
BIN
libs/procyon-decompiler-0.5.26.jar
Normal file
Binary file not shown.
|
@ -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.
|
||||
|
|
|
@ -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<String> 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<String> a) {
|
||||
|
|
188
src/the/bytecode/club/bytecodeviewer/ZipUtils.java
Normal file
188
src/the/bytecode/club/bytecodeviewer/ZipUtils.java
Normal 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()));
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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.");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue