1.4 Released

11/1/2014 - Fixed FernFlower save Java files on Unix.
11/1/2014 - FernFlower now uses the settings for save Java files.
11/1/2014 - Added Procyon save Java files (It uses the settings).
11/1/2014 - Updated CFR to cfr_0_89.
11/1/2014 - Added CFR save Java files (It uses the settings), however it
relies on the file system, because of this if there is heavy name
obfuscation, it could mess up for windows.
This commit is contained in:
Kalen Kinloch 2014-11-01 17:16:16 -07:00
parent 21754375b0
commit 9e2bfbc002
11 changed files with 214 additions and 68 deletions

BIN
BytecodeViewer Beta 1.4.jar Normal file

Binary file not shown.

View File

@ -109,6 +109,12 @@ Changelog:
10/29/2014 - Tried to fix the issue with JSyntaxPane by making it create the object in a background thread, it still freezes the UI. Changes kept for later implementation of another syntax highlighter.
10/29/2014 - Sped up start up time
--- Beta 1.3.1 ---:
10/29/2014 - Replaced JSyntaxPane with RSyntaxArea, this sadly removes the search feature inside of source/bytecode files, I'll implement a search function soon.
10/29/2014 - Replaced JSyntaxPane with RSyntaxArea, this sadly removes the search feature inside of source/bytecode files, I'll implement a search function soon. (This also fixes the JRE 1.8 issue)
10/29/2014 - Added a new decompiler option to append brackets to labels.
10/31/2014 - Fixed an issue with the decompiler still running when the source code pane isn't toggled.
10/31/2014 - Fixed an issue with the decompiler still running when the source code pane isn't toggled.
--- Beta 1.4 ---:
11/1/2014 - Fixed FernFlower save Java files on Unix.
11/1/2014 - FernFlower now uses the settings for save Java files.
11/1/2014 - Added Procyon save Java files (It uses the settings).
11/1/2014 - Updated CFR to cfr_0_89.
11/1/2014 - Added CFR save Java files (It uses the settings), however it relies on the file system, because of this if there is heavy name obfuscation, it could mess up for windows.

View File

@ -1 +1 @@
Beta 1.3.1
Beta 1.4

Binary file not shown.

BIN
libs/rsyntaxtextarea.jar Normal file

Binary file not shown.

View File

@ -138,9 +138,15 @@ import the.bytecode.club.bytecodeviewer.plugins.PluginManager;
* 10/29/2014 - Tried to fix the issue with JSyntaxPane by making it create the object in a background thread, it still freezes the UI. Changes kept for later implementation of another syntax highlighter.
* 10/29/2014 - Sped up start up time.
* ----Beta 1.3.1-----:
* 10/29/2014 - Replaced JSyntaxPane with RSyntaxArea, this sadly removes the search feature inside of source/bytecode files, I'll implement a search function soon.
* 10/29/2014 - Replaced JSyntaxPane with RSyntaxArea, this sadly removes the search feature inside of source/bytecode files, I'll implement a search function soon. (This also fixes the JRE 1.8 issue)
* 10/29/2014 - Added a new decompiler option to append brackets to labels.
* 10/31/2014 - Fixed an issue with the decompiler still running when the source code pane isn't toggled.
* ----Beta 1.4-----:
* 11/1/2014 - Fixed FernFlower save Java files on Unix.
* 11/1/2014 - FernFlower now uses the settings for save Java files.
* 11/1/2014 - Added Procyon save Java files (It uses the settings).
* 11/1/2014 - Updated CFR to cfr_0_89.
* 11/1/2014 - Added CFR save Java files (It uses the settings), however it relies on the file system, because of this if there is heavy name obfuscation, it could mess up for windows.
*
* @author Konloch
*
@ -156,10 +162,10 @@ public class BytecodeViewer {
private static ArrayList<String> recentFiles = DiskReader.loadArrayList(filesName, false);
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 String version = "Beta 1.3.1";
public static String tempDirectory = "bcv_temp";
public static String version = "Beta 1.4";
public static void main(String[] args) {
cleanup();

View File

@ -1,9 +1,17 @@
package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import me.konloch.kontainer.io.DiskReader;
@ -11,6 +19,7 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
/**
*
@ -168,29 +177,82 @@ public class CFRDecompiler extends JavaDecompiler {
};
}
byte[] buffer = new byte[1024];
@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 Beta 1.4 of Bytecode Viewer.");
File fuck = new File(fuckery);
try {
zip(fuck, new File(zipName));
} catch (IOException e) {
e.printStackTrace();
}
fuck.delete();
}
@SuppressWarnings("resource")
public void zip(File directory, File zipfile) throws IOException {
java.net.URI base = directory.toURI();
Deque<File> queue = new LinkedList<File>();
queue.push(directory);
OutputStream out = new FileOutputStream(zipfile);
Closeable res = out;
try {
ZipOutputStream zout = new ZipOutputStream(out);
res = zout;
while (!queue.isEmpty()) {
directory = queue.pop();
for (File kid : directory.listFiles()) {
String name = base.relativize(kid.toURI()).getPath();
if (kid.isDirectory()) {
queue.push(kid);
name = name.endsWith("/") ? name : name + "/";
zout.putNextEntry(new ZipEntry(name));
} else {
zout.putNextEntry(new ZipEntry(name));
copy(kid, zout);
zout.closeEntry();
}
}
}
} finally {
res.close();
out.close();
}
}
private static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
while (true) {
int readCount = in.read(buffer);
if (readCount < 0) {
break;
}
out.write(buffer, 0, readCount);
}
}
private static void copy(File file, OutputStream out) throws IOException {
InputStream in = new FileInputStream(file);
try {
copy(in, out);
} finally {
in.close();
}
}
}

View File

@ -28,12 +28,12 @@ public class FernFlowerDecompiler extends JavaDecompiler {
if(tempZip.exists())
tempZip.delete();
File f = new File(BytecodeViewer.tempDirectory + "./temp/");
File f = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs +"temp" + BytecodeViewer.fs);
f.mkdir();
JarUtils.saveAsJar(BytecodeViewer.getLoadedClasses(), tempZip.getAbsolutePath());
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(new String[] {tempZip.getAbsolutePath(), BytecodeViewer.tempDirectory + "./temp/"});
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempZip.getAbsolutePath(), BytecodeViewer.tempDirectory + "./temp/"));
File tempZip2 = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp" + BytecodeViewer.fs +tempZip.getName());
if(tempZip2.exists())
tempZip2.renameTo(new File(zipName));

View File

@ -1,15 +1,27 @@
package the.bytecode.club.bytecodeviewer.decompilers.java;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.tree.ClassNode;
import com.strobel.core.StringUtilities;
import com.strobel.decompiler.DecompilationOptions;
import com.strobel.decompiler.DecompilerSettings;
import com.strobel.decompiler.PlainTextOutput;
@ -17,11 +29,13 @@ import com.strobel.decompiler.languages.java.JavaFormattingOptions;
import com.strobel.assembler.InputTypeLoader;
import com.strobel.assembler.metadata.Buffer;
import com.strobel.assembler.metadata.ITypeLoader;
import com.strobel.assembler.metadata.JarTypeLoader;
import com.strobel.assembler.metadata.MetadataSystem;
import com.strobel.assembler.metadata.TypeDefinition;
import com.strobel.assembler.metadata.TypeReference;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.JarUtils;
/**
*
@ -32,6 +46,26 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer;
public class ProcyonDecompiler extends JavaDecompiler {
public DecompilerSettings getDecompilerSettings() {
DecompilerSettings settings = new DecompilerSettings();
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.isSelected());
settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.isSelected());
settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine.isSelected());
settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.isSelected());
settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.isSelected());
settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.isSelected());
settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.isSelected());
settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables.isSelected());
settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.isSelected());
settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.isSelected());
settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.isSelected());
settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.isSelected());
settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.isSelected());
settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.isSelected());
settings.setFormattingOptions(JavaFormattingOptions.createDefault());
return settings;
}
@Override
public String decompileClassNode(ClassNode cn) {
try {
@ -54,22 +88,7 @@ public class ProcyonDecompiler extends JavaDecompiler {
}
DecompilerSettings settings = new DecompilerSettings();
settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_6.isSelected());
settings.setExcludeNestedTypes(BytecodeViewer.viewer.chckbxmntmNewCheckItem_11.isSelected());
settings.setShowDebugLineNumbers(BytecodeViewer.viewer.chckbxmntmShowDebugLine.isSelected());
settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.chckbxmntmNewCheckItem_3.isSelected());
settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.chckbxmntmNewCheckItem_4.isSelected());
settings.setShowSyntheticMembers(BytecodeViewer.viewer.chckbxmntmNewCheckItem_7.isSelected());
settings.setSimplifyMemberReferences(BytecodeViewer.viewer.chckbxmntmSimplifyMemberReferences.isSelected());
settings.setMergeVariables(BytecodeViewer.viewer.mnMergeVariables.isSelected());
settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.chckbxmntmNewCheckItem_8.isSelected());
settings.setForceExplicitImports(BytecodeViewer.viewer.chckbxmntmNewCheckItem_9.isSelected());
settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.chckbxmntmNewCheckItem_10.isSelected());
settings.setRetainPointlessSwitches(BytecodeViewer.viewer.chckbxmntmNewCheckItem_2.isSelected());
settings.setRetainRedundantCasts(BytecodeViewer.viewer.chckbxmntmNewCheckItem_5.isSelected());
settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.chckbxmntmNewCheckItem_1.isSelected());
settings.setFormattingOptions(JavaFormattingOptions.createDefault());
DecompilerSettings settings = getDecompilerSettings();
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
@ -98,48 +117,101 @@ public class ProcyonDecompiler extends JavaDecompiler {
@Override
public void decompileToZip(String zipName) {
/*File tempZip = new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp.jar");
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 {
doSaveJarDecompiled(tempZip, new File(zipName));
} catch (Exception e) {
e.printStackTrace();
}
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();
}
//tempZip.delete();
//new File(BytecodeViewer.tempDirectory + BytecodeViewer.fs + "temp").delete();
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 Beta 1.4 of Bytecode Viewer.");
//BytecodeViewer.showMessage("ProcyonDecompiler currently doesn't decompile as zip, please wait till Beta 1.4 of Bytecode Viewer.");
}
/**
*
* @author DeathMarine
*
*/
private void doSaveJarDecompiled(File inFile, File outFile) throws Exception {
try (JarFile jfile = new JarFile(inFile);
FileOutputStream dest = new FileOutputStream(outFile);
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
ZipOutputStream out = new ZipOutputStream(buffDest);) {
byte data[] = new byte[1024];
DecompilerSettings settings = getDecompilerSettings();
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
ITypeLoader jarLoader = new JarTypeLoader(jfile);
typeLoader.getTypeLoaders().add(jarLoader);
DecompilationOptions decompilationOptions = new DecompilationOptions();
decompilationOptions.setSettings(settings);
decompilationOptions.setFullDecompilation(true);
Enumeration<JarEntry> ent = jfile.entries();
Set<JarEntry> history = new HashSet<JarEntry>();
while (ent.hasMoreElements()) {
JarEntry entry = ent.nextElement();
if (entry.getName().endsWith(".class")) {
JarEntry etn = new JarEntry(entry.getName().replace(".class", ".java"));
if(history.add(etn)){
out.putNextEntry(etn);
try {
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
TypeReference type = metadataSystem.lookupType(internalName);
TypeDefinition resolvedType = null;
if ((type == null) || ((resolvedType = type.resolve()) == null)) {
throw new Exception("Unable to resolve type.");
}
Writer writer = new OutputStreamWriter(out);
settings.getLanguage().decompileType(resolvedType,
new PlainTextOutput(writer), decompilationOptions);
writer.flush();
} finally {
out.closeEntry();
}
}
} else {
try {
JarEntry etn = new JarEntry(entry.getName());
if(history.add(etn))
continue;
history.add(etn);
out.putNextEntry(etn);
try {
InputStream in = jfile.getInputStream(entry);
if (in != null) {
try {
int count;
while ((count = in.read(data, 0, 1024)) != -1) {
out.write(data, 0, count);
}
} finally {
in.close();
}
}
} finally {
out.closeEntry();
}
} catch (ZipException ze) {
// some jar-s contain duplicate pom.xml entries: ignore it
if (!ze.getMessage().contains("duplicate")) {
throw ze;
}
}
}
}
}
}
/**

View File

@ -17,7 +17,7 @@ public class AboutWindow extends JFrame {
txtrBytecodeViewerIs.setDisabledTextColor(Color.BLACK);
txtrBytecodeViewerIs.setWrapStyleWord(true);
getContentPane().add(txtrBytecodeViewerIs, "name_140466526081695");
txtrBytecodeViewerIs.setText("Bytecode Viewer is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n JSyntaxPane by Ayman Al\r\n Commons IO by Apache\r\n ASM by OW2\r\n CFIDE by Bibl\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttp://the.bytecode.club");
txtrBytecodeViewerIs.setText("Bytecode Viewer is an open source program\r\ndeveloped by Konloch (konloch@gmail.com)\r\n\r\nIt uses code from the following:\r\n J-RET by WaterWolf\r\n JHexPane by Sam Koivu\r\n RSyntaxTextArea by Bobbylight\r\n Commons IO by Apache\r\n ASM by OW2\r\n CFIDE by Bibl\r\n FernFlower by Stiver\r\n Procyon by Mstrobel\r\n CFR by Lee Benfield\r\n\r\nIf you're interested in Java Reverse\r\nEngineering, join The Bytecode Club\r\nhttp://the.bytecode.club");
txtrBytecodeViewerIs.setEnabled(false);
this.setResizable(false);
this.setLocationRelativeTo(null);