Procyon Decompiler Update
This commit is contained in:
parent
edd09c0409
commit
1ac293c7b8
|
@ -27,6 +27,7 @@ import com.strobel.decompiler.PlainTextOutput;
|
||||||
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
|
import com.strobel.decompiler.languages.java.JavaFormattingOptions;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
||||||
|
import the.bytecode.club.bytecodeviewer.Constants;
|
||||||
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
import the.bytecode.club.bytecodeviewer.api.ExceptionUI;
|
||||||
import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler;
|
import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
@ -42,8 +43,7 @@ import java.util.zip.ZipException;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
import static the.bytecode.club.bytecodeviewer.Constants.*;
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
|
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*;
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PROCYON;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Procyon Java Decompiler Wrapper
|
* Procyon Java Decompiler Wrapper
|
||||||
|
@ -51,12 +51,13 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PRO
|
||||||
* @author Konloch
|
* @author Konloch
|
||||||
* @author DeathMarine
|
* @author DeathMarine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ProcyonDecompiler extends AbstractDecompiler
|
public class ProcyonDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
|
|
||||||
public ProcyonDecompiler()
|
public ProcyonDecompiler()
|
||||||
{
|
{
|
||||||
super("Procyon Decompiler", "proycon");
|
super("Procyon Decompiler", "procyon");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,34 +70,43 @@ public class ProcyonDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
//create the temporary files
|
//create the temporary files
|
||||||
tempFile = TempFile.createTemporaryFile(false, ".class");
|
tempFile = TempFile.createTemporaryFile(false, ".class");
|
||||||
File tempClassFile = tempFile.getFile();
|
File tempInputClassFile = tempFile.getFile();
|
||||||
|
|
||||||
//write the ClassNode bytes to the temp file
|
//write the ClassNode bytes to the temp file
|
||||||
try (FileOutputStream fos = new FileOutputStream(tempClassFile))
|
try (FileOutputStream fos = new FileOutputStream(tempInputClassFile))
|
||||||
{
|
{
|
||||||
fos.write(bytes);
|
fos.write(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//setup proycon decompiler settings
|
//initialize procyon
|
||||||
DecompilerSettings settings = getDecompilerSettings();
|
DecompilerSettings settings = getDecompilerSettings();
|
||||||
|
|
||||||
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
|
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
|
||||||
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
|
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
|
||||||
TypeReference type = metadataSystem.lookupType(tempClassFile.getCanonicalPath());
|
|
||||||
|
|
||||||
DecompilationOptions decompilationOptions = new DecompilationOptions();
|
DecompilationOptions decompilationOptions = new DecompilationOptions();
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
|
||||||
|
//lookup the class-file
|
||||||
|
TypeReference type = metadataSystem.lookupType(tempInputClassFile.getCanonicalPath());
|
||||||
|
|
||||||
|
//configure procyon
|
||||||
decompilationOptions.setSettings(settings);
|
decompilationOptions.setSettings(settings);
|
||||||
decompilationOptions.setFullDecompilation(true);
|
decompilationOptions.setFullDecompilation(true);
|
||||||
|
|
||||||
|
//parse class-file
|
||||||
TypeDefinition resolvedType;
|
TypeDefinition resolvedType;
|
||||||
|
|
||||||
if (type == null || ((resolvedType = type.resolve()) == null))
|
if (type == null || ((resolvedType = type.resolve()) == null))
|
||||||
throw new Exception("Unable to resolve type.");
|
throw new Exception("Unable to resolve class-filetype.");
|
||||||
|
|
||||||
StringWriter stringwriter = new StringWriter();
|
//decompile the class-file
|
||||||
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions);
|
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
|
||||||
|
|
||||||
return EncodeUtils.unicodeToString(stringwriter.toString());
|
//handle simulated errors
|
||||||
|
if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS)
|
||||||
|
throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString());
|
||||||
|
|
||||||
|
//return the writer contents
|
||||||
|
return EncodeUtils.unicodeToString(writer.toString());
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
|
@ -106,7 +116,7 @@ public class ProcyonDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
//delete all temporary files
|
//delete all temporary files
|
||||||
if(tempFile != null)
|
if(tempFile != null)
|
||||||
tempFile.delete();
|
tempFile.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL
|
return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL
|
||||||
|
@ -118,7 +128,100 @@ public class ProcyonDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
doSaveJarDecompiled(new File(sourceJar), new File(zipName));
|
try (JarFile jarFile = new JarFile(sourceJar);
|
||||||
|
FileOutputStream destination = new FileOutputStream(zipName);
|
||||||
|
BufferedOutputStream buffer = new BufferedOutputStream(destination);
|
||||||
|
ZipOutputStream zip = new ZipOutputStream(buffer))
|
||||||
|
{
|
||||||
|
byte[] data = new byte[1024];
|
||||||
|
|
||||||
|
//initialize procyon
|
||||||
|
DecompilerSettings settings = getDecompilerSettings();
|
||||||
|
LuytenTypeLoader typeLoader = new LuytenTypeLoader();
|
||||||
|
MetadataSystem metadataSystem = new MetadataSystem(typeLoader);
|
||||||
|
ITypeLoader jarLoader = new JarTypeLoader(jarFile);
|
||||||
|
|
||||||
|
//lookup the jar-file
|
||||||
|
typeLoader.getTypeLoaders().add(jarLoader);
|
||||||
|
|
||||||
|
//configure procyon
|
||||||
|
DecompilationOptions decompilationOptions = new DecompilationOptions();
|
||||||
|
decompilationOptions.setSettings(settings);
|
||||||
|
decompilationOptions.setFullDecompilation(true);
|
||||||
|
|
||||||
|
//setup jar output
|
||||||
|
Enumeration<JarEntry> ent = jarFile.entries();
|
||||||
|
Set<JarEntry> history = new HashSet<>();
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
zip.putNextEntry(etn);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String internalName = StringUtilities.removeRight(entry.getName(), ".class");
|
||||||
|
TypeReference type = metadataSystem.lookupType(internalName);
|
||||||
|
TypeDefinition resolvedType;
|
||||||
|
|
||||||
|
if ((type == null) || ((resolvedType = type.resolve()) == null))
|
||||||
|
throw new Exception("Unable to resolve type.");
|
||||||
|
|
||||||
|
Writer writer = new OutputStreamWriter(zip);
|
||||||
|
settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(writer), decompilationOptions);
|
||||||
|
writer.flush();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
zip.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
JarEntry etn = new JarEntry(entry.getName());
|
||||||
|
|
||||||
|
if (history.add(etn))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
history.add(etn);
|
||||||
|
zip.putNextEntry(etn);
|
||||||
|
|
||||||
|
try (InputStream in = jarFile.getInputStream(entry))
|
||||||
|
{
|
||||||
|
if (in != null)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
while ((count = in.read(data, 0, 1024)) != -1)
|
||||||
|
{
|
||||||
|
zip.write(data, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
zip.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ZipException ze)
|
||||||
|
{
|
||||||
|
// some jars contain duplicate pom.xml entries: ignore it
|
||||||
|
if (!ze.getMessage().contains("duplicate"))
|
||||||
|
throw ze;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (StackOverflowError | Exception e)
|
catch (StackOverflowError | Exception e)
|
||||||
{
|
{
|
||||||
|
@ -126,102 +229,6 @@ public class ProcyonDecompiler extends AbstractDecompiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @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<>();
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
while ((count = in.read(data, 0, 1024)) != -1)
|
|
||||||
{
|
|
||||||
out.write(data, 0, count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
out.closeEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ZipException ze)
|
|
||||||
{
|
|
||||||
// some jars contain duplicate pom.xml entries: ignore it
|
|
||||||
if (!ze.getMessage().contains("duplicate"))
|
|
||||||
throw ze;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public DecompilerSettings getDecompilerSettings()
|
public DecompilerSettings getDecompilerSettings()
|
||||||
{
|
{
|
||||||
DecompilerSettings settings = new DecompilerSettings();
|
DecompilerSettings settings = new DecompilerSettings();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user