CFR Decompiler Updates
Error Log Update / Syntax
This commit is contained in:
parent
45bf02e81e
commit
1d5d0bc0fa
|
@ -29,10 +29,12 @@ import org.benf.cfr.reader.util.getopt.Options;
|
||||||
import org.benf.cfr.reader.util.getopt.OptionsImpl;
|
import org.benf.cfr.reader.util.getopt.OptionsImpl;
|
||||||
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.resources.ResourceContainer;
|
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
|
||||||
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
||||||
|
import the.bytecode.club.bytecodeviewer.util.ExceptionUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -44,15 +46,14 @@ import java.util.zip.ZipException;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
import static the.bytecode.club.bytecodeviewer.Constants.NL;
|
import static the.bytecode.club.bytecodeviewer.Constants.NL;
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.CFR;
|
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*;
|
||||||
import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CFR Java Wrapper
|
* CFR Java Wrapper
|
||||||
*
|
*
|
||||||
* @author GraxCode
|
* @author GraxCode (Taken mostly out of Threadtear)
|
||||||
* Taken mostly out of Threadtear.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class CFRDecompiler extends AbstractDecompiler
|
public class CFRDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -71,59 +72,69 @@ public class CFRDecompiler extends AbstractDecompiler
|
||||||
|
|
||||||
private String decompile(ClassNode cn, String name, byte[] content)
|
private String decompile(ClassNode cn, String name, byte[] content)
|
||||||
{
|
{
|
||||||
|
String exception;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String classPath = name + (name.endsWith(CLASS_SUFFIX) ? "" : CLASS_SUFFIX);
|
String classPath = name + (name.endsWith(CLASS_SUFFIX) ? "" : CLASS_SUFFIX);
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
Consumer<SinkReturns.Decompiled> dumpDecompiled = d -> builder.append(d.getJava());
|
Consumer<SinkReturns.Decompiled> dumpDecompiled = d -> builder.append(d.getJava());
|
||||||
|
|
||||||
|
//initialize CFR
|
||||||
Options options = generateOptions();
|
Options options = generateOptions();
|
||||||
ClassFileSource source = new BCVDataSource(options, cn, classPath, content);
|
ClassFileSource source = new BCVDataSource(options, cn, classPath, content);
|
||||||
CfrDriver driver = new CfrDriver.Builder().withClassFileSource(source).withBuiltOptions(options).withOutputSink(new BCVOutputSinkFactory(dumpDecompiled)).build();
|
CfrDriver driver = new CfrDriver.Builder().withClassFileSource(source).withBuiltOptions(options).withOutputSink(new BCVOutputSinkFactory(dumpDecompiled)).build();
|
||||||
|
|
||||||
|
//decompile the class-file
|
||||||
driver.analyse(Collections.singletonList(name));
|
driver.analyse(Collections.singletonList(name));
|
||||||
|
|
||||||
|
//handle simulated errors
|
||||||
|
if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS)
|
||||||
|
throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString());
|
||||||
|
|
||||||
|
//return the builder contents
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
t.printStackTrace();
|
exception = ExceptionUtils.exceptionToString(e);
|
||||||
StringWriter sw = new StringWriter();
|
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
|
||||||
t.printStackTrace(pw);
|
|
||||||
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + sw;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL
|
||||||
|
+ TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decompileToZip(String sourceJar, String outJar)
|
public void decompileToZip(String sourceJar, String outJar)
|
||||||
{
|
{
|
||||||
try (JarFile jfile = new JarFile(new File(sourceJar));
|
try (JarFile jarFile = new JarFile(new File(sourceJar));
|
||||||
FileOutputStream dest = new FileOutputStream(outJar);
|
FileOutputStream destination = new FileOutputStream(outJar);
|
||||||
BufferedOutputStream buffDest = new BufferedOutputStream(dest);
|
BufferedOutputStream buffer = new BufferedOutputStream(destination);
|
||||||
ZipOutputStream out = new ZipOutputStream(buffDest))
|
ZipOutputStream zip = new ZipOutputStream(buffer))
|
||||||
{
|
{
|
||||||
byte[] data = new byte[1024];
|
byte[] data = new byte[1024];
|
||||||
|
Enumeration<JarEntry> ent = jarFile.entries();
|
||||||
Enumeration<JarEntry> ent = jfile.entries();
|
|
||||||
Set<JarEntry> history = new HashSet<>();
|
Set<JarEntry> history = new HashSet<>();
|
||||||
|
|
||||||
while (ent.hasMoreElements())
|
while (ent.hasMoreElements())
|
||||||
{
|
{
|
||||||
JarEntry entry = ent.nextElement();
|
JarEntry entry = ent.nextElement();
|
||||||
|
|
||||||
if (entry.getName().endsWith(CLASS_SUFFIX))
|
if (entry.getName().endsWith(CLASS_SUFFIX))
|
||||||
{
|
{
|
||||||
JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java"));
|
JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java"));
|
||||||
|
|
||||||
if (history.add(etn))
|
if (history.add(etn))
|
||||||
{
|
{
|
||||||
out.putNextEntry(etn);
|
zip.putNextEntry(etn);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IOUtils.write(decompile(null, entry.getName(), IOUtils.toByteArray(jfile.getInputStream(entry))), out, StandardCharsets.UTF_8);
|
IOUtils.write(decompile(null, entry.getName(), IOUtils.toByteArray(jarFile.getInputStream(entry))), zip, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
out.closeEntry();
|
zip.closeEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,34 +142,36 @@ public class CFRDecompiler extends AbstractDecompiler
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
JarEntry etn = new JarEntry(entry.getName());
|
JarEntry jarEntry = new JarEntry(entry.getName());
|
||||||
if (history.add(etn))
|
|
||||||
|
if (history.add(jarEntry))
|
||||||
continue;
|
continue;
|
||||||
history.add(etn);
|
|
||||||
out.putNextEntry(etn);
|
history.add(jarEntry);
|
||||||
try (InputStream in = jfile.getInputStream(entry))
|
zip.putNextEntry(jarEntry);
|
||||||
|
|
||||||
|
try (InputStream input = jarFile.getInputStream(entry))
|
||||||
{
|
{
|
||||||
if (in != null)
|
if (input != null)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
while ((count = in.read(data, 0, 1024)) != -1)
|
|
||||||
|
while ((count = input.read(data, 0, 1024)) != -1)
|
||||||
{
|
{
|
||||||
out.write(data, 0, count);
|
zip.write(data, 0, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
out.closeEntry();
|
zip.closeEntry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ZipException ze)
|
catch (ZipException e)
|
||||||
{
|
{
|
||||||
// some jars contain duplicate pom.xml entries: ignore it
|
// some jars contain duplicate pom.xml entries: ignore it
|
||||||
if (!ze.getMessage().contains("duplicate"))
|
if (!e.getMessage().contains("duplicate"))
|
||||||
{
|
throw e;
|
||||||
throw ze;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,7 +239,8 @@ public class CFRDecompiler extends AbstractDecompiler
|
||||||
private BCVDataSource(Options options, ClassNode cn, String classFilePath, byte[] content)
|
private BCVDataSource(Options options, ClassNode cn, String classFilePath, byte[] content)
|
||||||
{
|
{
|
||||||
super(options);
|
super(options);
|
||||||
this.container = BytecodeViewer.getResourceContainers().stream().filter(rc -> rc.resourceClasses.containsValue(cn)).findFirst().orElse(null);
|
this.container = BytecodeViewer.getResourceContainers()
|
||||||
|
.stream().filter(rc -> rc.resourceClasses.containsValue(cn)).findFirst().orElse(null);
|
||||||
this.classFilePath = classFilePath;
|
this.classFilePath = classFilePath;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
@ -247,7 +261,6 @@ public class CFRDecompiler extends AbstractDecompiler
|
||||||
|
|
||||||
return Pair.make(data, classFilePath);
|
return Pair.make(data, classFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BCVOutputSinkFactory implements OutputSinkFactory
|
private static class BCVOutputSinkFactory implements OutputSinkFactory
|
||||||
|
@ -274,9 +287,7 @@ public class CFRDecompiler extends AbstractDecompiler
|
||||||
return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x);
|
return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ignore ->
|
return ignore -> {};
|
||||||
{
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user