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
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
|
* Used to load a string via line number
|
||||||
* lineNumber = -1 means random.
|
* 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 - 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) {
|
||||||
|
|
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;
|
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};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user