From d4a528ee232802b57bc02eda2a88784c1ced2bc2 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 10:14:35 -0600 Subject: [PATCH 01/82] CLI Cleanup --- .../the/bytecode/club/bytecodeviewer/BytecodeViewer.java | 5 ++++- .../bytecode/club/bytecodeviewer/cli/BCVCommandLine.java | 7 ++----- .../bytecodeviewer/cli/actions/commands/HelpCommand.java | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java index d9269b62..d258498f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/BytecodeViewer.java @@ -693,7 +693,10 @@ public class BytecodeViewer */ public static void handleException(Throwable t, String author) { - new ExceptionUI(t, author); + if(CLI.isCLI()) + t.printStackTrace(); + else + new ExceptionUI(t, author); } /** diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/BCVCommandLine.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/BCVCommandLine.java index 29adcfe3..9f0d30f5 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/BCVCommandLine.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/BCVCommandLine.java @@ -69,18 +69,13 @@ public class BCVCommandLine { CommandLine cmd = PARSER.parse(OPTIONS, args); - if(cmd.hasOption("language")) - System.out.println("OK: " + cmd.getOptionValue("language")); - //TODO this is a backwards way of searching and will cause collisions // I'm sure the Apache CLI has a better way of navigating this for(CLICommand command : COMMANDS) { - System.out.println("OK: " + command.name); if(cmd.hasOption(command.name)) { - System.out.println("ON: " + command.name); command.runCommand(cmd); return; } @@ -115,9 +110,11 @@ public class BCVCommandLine return; } + //wait 5 seconds to allow time for reading if (!cmd.hasOption("nowait")) SleepUtil.sleep(5 * 1000); + //decompiler configuration File input = new File(cmd.getOptionValue("i")); File output = new File(cmd.getOptionValue("o")); String decompiler = cmd.getOptionValue("decompiler"); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/HelpCommand.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/HelpCommand.java index 1b25c575..46304090 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/HelpCommand.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/HelpCommand.java @@ -28,10 +28,10 @@ public class HelpCommand extends CLICommand "-o Selects the output file", "-t Must either be the fully qualified classname or \"all\" to decompile all as zip", "-nowait Doesn't wait for the user to read the CLI messages", - + "", "==BCV GUI Commands==", "-cleanboot Deletes the BCV directory and continues to boot into the GUI", - "-english Forces English language translations" + "-language Sets specific language translations" }) System.out.println(s); } From 32b6f4ee8afa62f2b048c413650c0156a6ee377e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 10:55:27 -0600 Subject: [PATCH 02/82] Started New TempFiles API --- .../club/bytecodeviewer/util/TempFiles.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java new file mode 100644 index 00000000..15da1a29 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java @@ -0,0 +1,43 @@ +package the.bytecode.club.bytecodeviewer.util; + +import java.io.File; + +import static the.bytecode.club.bytecodeviewer.Constants.TEMP_DIRECTORY; + +/** + * @author Konloch + * @since 10/2/2024 + */ +public class TempFiles +{ + public static File createTemporaryFile(boolean newDirecory, String extension) + { + //genereate a new temporary parent directory + File parent = newDirecory ? createTemporaryDirectory() : new File(TEMP_DIRECTORY); + + //make the parent directories + parent.mkdirs(); + + //return the temporary file + File file; + + //generate a new name until the directory no longer exists + while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) + { + } + + return file; + } + + public static File createTemporaryDirectory() + { + File directory; + + //generate a new name until the directory no longer exists + while((directory = new File(TEMP_DIRECTORY, MiscUtils.randomString(32))).exists()) + { + } + + return directory; + } +} From 8301a58db897570eec0d7113c039e1a42080f56f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 10:58:27 -0600 Subject: [PATCH 03/82] Fix getUniqueName --- .../impl/FernFlowerDecompiler.java | 2 +- .../decompilers/impl/JADXDecompiler.java | 2 +- .../decompilers/impl/SmaliDisassembler.java | 2 +- .../club/bytecodeviewer/util/MiscUtils.java | 30 +++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 30ea76e1..450cccdd 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -72,7 +72,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - String start = TEMP_DIRECTORY + FS + MiscUtils.getUniqueName("", ".class"); + String start = TEMP_DIRECTORY + FS + MiscUtils.getUniqueNameBroken("", ".class"); final File tempClass = new File(start + ".class"); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java index 2fb464ea..6532ead4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java @@ -52,7 +52,7 @@ public class JADXDecompiler extends AbstractDecompiler String fileStart = TEMP_DIRECTORY + FS; String exception = ""; - final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class"); + final File tempClass = new File(MiscUtils.getUniqueNameBroken(fileStart, ".class") + ".class"); try (FileOutputStream fos = new FileOutputStream(tempClass)) { diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java index 199838c4..19e5318a 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java @@ -52,7 +52,7 @@ public class SmaliDisassembler extends AbstractDecompiler public String decompileClassNode(ClassNode cn, byte[] bytes) { final String fileStart = TEMP_DIRECTORY + FS + "temp"; - final String start = MiscUtils.getUniqueName(fileStart, ".class"); + final String start = MiscUtils.getUniqueNameBroken(fileStart, ".class"); final File tempClass = new File(start + ".class"); final File tempDex = new File(start + ".dex"); final File tempDexOut = new File(start + "-out"); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/MiscUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/MiscUtils.java index e4c4520d..116003c6 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/MiscUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/MiscUtils.java @@ -144,6 +144,36 @@ public class MiscUtils File tempFile; String randomString; + while (searching) + { + randomString = MiscUtils.randomString(32); + uniqueName = stringStart + randomString + fileExtension; + tempFile = new File(stringStart + randomString + fileExtension); + + if (!tempFile.exists()) + searching = false; + } + + return uniqueName; + } + + /** + * Checks the file system to ensure it's a unique name + * + * @param stringStart directory it'll be in + * @param fileExtension the file extension it'll use + * @return the unique name + */ + //TODO anything using this should be updated: + // The + ".class" needs to be removed + @Deprecated + public static String getUniqueNameBroken(String stringStart, String fileExtension) + { + String uniqueName = null; + boolean searching = true; + File tempFile; + String randomString; + while (searching) { randomString = MiscUtils.randomString(32); From 5a3820b50c62bd6290f8ef6561956f61885fe218 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 10:58:41 -0600 Subject: [PATCH 04/82] Update Procyon Decompiler To New TempFIles API --- .../bytecodeviewer/decompilers/impl/ProcyonDecompiler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index c4bb26ab..7d6c8889 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -32,6 +32,7 @@ import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.EncodeUtils; import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.TempFiles; import java.io.*; import java.util.*; @@ -85,8 +86,7 @@ public class ProcyonDecompiler extends AbstractDecompiler String exception; try { - final String fileStart = TEMP_DIRECTORY + FS + "temp"; - final File tempClass = new File(MiscUtils.getUniqueName(fileStart, ".class") + ".class"); + final File tempClass = TempFiles.createTemporaryFile(false, ".class"); try (FileOutputStream fos = new FileOutputStream(tempClass)) { From 67814737c9558f43090f7b24e3d0870be7f7a1e6 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:12:41 -0600 Subject: [PATCH 05/82] Better TempFile API --- .../club/bytecodeviewer/util/TempFile.java | 81 +++++++++++++++++++ .../club/bytecodeviewer/util/TempFiles.java | 43 ---------- 2 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java delete mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java new file mode 100644 index 00000000..efb66c2e --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -0,0 +1,81 @@ +package the.bytecode.club.bytecodeviewer.util; + +import java.io.File; + +import static the.bytecode.club.bytecodeviewer.Constants.TEMP_DIRECTORY; + +/** + * @author Konloch + * @since 10/2/2024 + */ +public class TempFile +{ + private final File parent; + private final File file; + private final String filePath; + + public TempFile(File file) + { + this.parent = file.getParentFile(); + this.file = file; + this.filePath = file.getAbsolutePath(); + } + + public File getFile() + { + return file; + } + + public String getFilePath() + { + return filePath; + } + + public File createFileFromExtension(String extension) + { + File file; + + //generate a new name until the directory no longer exists + while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) + { + } + + return file; + } + + public static TempFile createTemporaryFile(boolean newDirectory, String extension) + { + //generate a new temporary parent directory + File parent = newDirectory ? createTempDirectory() : new File(TEMP_DIRECTORY); + + return new TempFile(createTempFile(parent, extension)); + } + + private static File createTempFile(File parent, String extension) + { + //make the parent directories + parent.mkdirs(); + + //return the temporary file + File file; + + //generate a new name until the directory no longer exists + while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) + { + } + + return file; + } + + private static File createTempDirectory() + { + File directory; + + //generate a new name until the directory no longer exists + while((directory = new File(TEMP_DIRECTORY, MiscUtils.randomString(32))).exists()) + { + } + + return directory; + } +} diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java deleted file mode 100644 index 15da1a29..00000000 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFiles.java +++ /dev/null @@ -1,43 +0,0 @@ -package the.bytecode.club.bytecodeviewer.util; - -import java.io.File; - -import static the.bytecode.club.bytecodeviewer.Constants.TEMP_DIRECTORY; - -/** - * @author Konloch - * @since 10/2/2024 - */ -public class TempFiles -{ - public static File createTemporaryFile(boolean newDirecory, String extension) - { - //genereate a new temporary parent directory - File parent = newDirecory ? createTemporaryDirectory() : new File(TEMP_DIRECTORY); - - //make the parent directories - parent.mkdirs(); - - //return the temporary file - File file; - - //generate a new name until the directory no longer exists - while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) - { - } - - return file; - } - - public static File createTemporaryDirectory() - { - File directory; - - //generate a new name until the directory no longer exists - while((directory = new File(TEMP_DIRECTORY, MiscUtils.randomString(32))).exists()) - { - } - - return directory; - } -} From 626b8566b9d271fc91c6778c48c75c5b563df22f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:12:52 -0600 Subject: [PATCH 06/82] Better Procyon Decompiling --- .../decompilers/impl/ProcyonDecompiler.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 7d6c8889..8f51fac6 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -31,8 +31,7 @@ import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.EncodeUtils; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; -import the.bytecode.club.bytecodeviewer.util.TempFiles; +import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; import java.util.*; @@ -86,17 +85,16 @@ public class ProcyonDecompiler extends AbstractDecompiler String exception; try { - final File tempClass = TempFiles.createTemporaryFile(false, ".class"); + final TempFile tempFile = TempFile.createTemporaryFile(false, ".class"); + final File tempClass = tempFile.createFileFromExtension(".class"); + //write the ClassNode bytes to the temp file try (FileOutputStream fos = new FileOutputStream(tempClass)) { fos.write(bytes); } - catch (IOException e) - { - BytecodeViewer.handleException(e); - } + //setup proycon decompiler settings DecompilerSettings settings = getDecompilerSettings(); LuytenTypeLoader typeLoader = new LuytenTypeLoader(); @@ -126,7 +124,8 @@ public class ProcyonDecompiler extends AbstractDecompiler exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; } - return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override From e1915328fb613f032cafd2e34d3f2776d4242814 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:20:33 -0600 Subject: [PATCH 07/82] Continued Temp File API --- .../club/bytecodeviewer/util/TempFile.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index efb66c2e..f372ec9c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -1,6 +1,7 @@ package the.bytecode.club.bytecodeviewer.util; import java.io.File; +import java.util.HashSet; import static the.bytecode.club.bytecodeviewer.Constants.TEMP_DIRECTORY; @@ -13,12 +14,19 @@ public class TempFile private final File parent; private final File file; private final String filePath; + private final HashSet createdFilePaths = new HashSet<>(); public TempFile(File file) { this.parent = file.getParentFile(); this.file = file; this.filePath = file.getAbsolutePath(); + this.createdFilePaths.add(file.getAbsolutePath()); + } + + public File getParent() + { + return parent; } public File getFile() @@ -31,6 +39,23 @@ public class TempFile return filePath; } + public void delete() + { + //delete all the items + for(String path : createdFilePaths) + { + File toDelete = new File(path); + + toDelete.delete(); + } + + //delete parent if it's not the main temp directory + if(!getParent().getAbsolutePath().equalsIgnoreCase(new File(TEMP_DIRECTORY).getAbsolutePath())) + { + getParent().delete(); + } + } + public File createFileFromExtension(String extension) { File file; @@ -40,6 +65,8 @@ public class TempFile { } + this.createdFilePaths.add(file.getAbsolutePath()); + return file; } From b65aad2a839e46a6e899367754d06afcf7617ff4 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:22:33 -0600 Subject: [PATCH 08/82] Procyon Delete Temporary Files --- .../decompilers/impl/ProcyonDecompiler.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 8f51fac6..41b86793 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -86,10 +86,10 @@ public class ProcyonDecompiler extends AbstractDecompiler try { final TempFile tempFile = TempFile.createTemporaryFile(false, ".class"); - final File tempClass = tempFile.createFileFromExtension(".class"); + final File tempClassFile = tempFile.createFileFromExtension(".class"); //write the ClassNode bytes to the temp file - try (FileOutputStream fos = new FileOutputStream(tempClass)) + try (FileOutputStream fos = new FileOutputStream(tempClassFile)) { fos.write(bytes); } @@ -99,7 +99,7 @@ public class ProcyonDecompiler extends AbstractDecompiler LuytenTypeLoader typeLoader = new LuytenTypeLoader(); MetadataSystem metadataSystem = new MetadataSystem(typeLoader); - TypeReference type = metadataSystem.lookupType(tempClass.getCanonicalPath()); + TypeReference type = metadataSystem.lookupType(tempClassFile.getCanonicalPath()); DecompilationOptions decompilationOptions = new DecompilationOptions(); decompilationOptions.setSettings(settings); @@ -113,6 +113,9 @@ public class ProcyonDecompiler extends AbstractDecompiler StringWriter stringwriter = new StringWriter(); settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions); + //delete all temporary files + tempFile.delete(); + return EncodeUtils.unicodeToString(stringwriter.toString()); } catch (StackOverflowError | Exception e) From 99e4973ec9059f33e353ed56dd36423f2812757d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:54:05 -0600 Subject: [PATCH 09/82] Procyon Fixes --- .../bytecodeviewer/decompilers/impl/ProcyonDecompiler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 41b86793..30c67921 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -83,10 +83,11 @@ public class ProcyonDecompiler extends AbstractDecompiler public String decompileClassNode(ClassNode cn, byte[] bytes) { String exception; + try { final TempFile tempFile = TempFile.createTemporaryFile(false, ".class"); - final File tempClassFile = tempFile.createFileFromExtension(".class"); + final File tempClassFile = tempFile.getFile(); //write the ClassNode bytes to the temp file try (FileOutputStream fos = new FileOutputStream(tempClassFile)) @@ -118,7 +119,7 @@ public class ProcyonDecompiler extends AbstractDecompiler return EncodeUtils.unicodeToString(stringwriter.toString()); } - catch (StackOverflowError | Exception e) + catch (Throwable e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); From 5ab1fe04b5cb1054e7913e7648511b30a333f09b Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 11:54:23 -0600 Subject: [PATCH 10/82] Temp File API Improvements --- .../club/bytecodeviewer/util/TempFile.java | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index f372ec9c..f51cd668 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -11,16 +11,16 @@ import static the.bytecode.club.bytecodeviewer.Constants.TEMP_DIRECTORY; */ public class TempFile { - private final File parent; + private File parent; private final File file; - private final String filePath; + private final String uniqueName; private final HashSet createdFilePaths = new HashSet<>(); - public TempFile(File file) + public TempFile(File file, String uniqueName) { this.parent = file.getParentFile(); this.file = file; - this.filePath = file.getAbsolutePath(); + this.uniqueName = uniqueName; this.createdFilePaths.add(file.getAbsolutePath()); } @@ -34,9 +34,14 @@ public class TempFile return file; } - public String getFilePath() + public String getUniqueName() { - return filePath; + return uniqueName; + } + + public void setParent(File parent) + { + this.parent = parent; } public void delete() @@ -57,12 +62,22 @@ public class TempFile } public File createFileFromExtension(String extension) + { + return createFileFromExtension(true, false, extension); + } + + public File createFileFromExtension(boolean newUniqueName, boolean canExist, String extension) { File file; + String uniqueName = newUniqueName ? MiscUtils.getUniqueName("", extension) : this.uniqueName + extension; + //String uniqueName = this.uniqueName + extension; + //generate a new name until the directory no longer exists - while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) + while((file = new File(parent, uniqueName)).exists()) { + if(canExist) + break; } this.createdFilePaths.add(file.getAbsolutePath()); @@ -75,23 +90,23 @@ public class TempFile //generate a new temporary parent directory File parent = newDirectory ? createTempDirectory() : new File(TEMP_DIRECTORY); - return new TempFile(createTempFile(parent, extension)); - } - - private static File createTempFile(File parent, String extension) - { //make the parent directories parent.mkdirs(); - //return the temporary file - File file; + //create the temporary variables + String uniqueName; + File file = null; //generate a new name until the directory no longer exists - while((file = new File(parent, MiscUtils.getUniqueName("", extension))).exists()) + while((uniqueName = MiscUtils.getUniqueName("", extension)) != null && + (file = new File(parent, uniqueName)).exists()) { } - return file; + if(uniqueName != null) + uniqueName = uniqueName.substring(0, uniqueName.length() - extension.length()); + + return new TempFile(file, uniqueName); } private static File createTempDirectory() From 96495c846999683076129639f72650f7f92b799d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:07:09 -0600 Subject: [PATCH 11/82] Extended Temp File API --- .../bytecode/club/bytecodeviewer/util/TempFile.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index f51cd668..412c3317 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -44,6 +44,11 @@ public class TempFile this.parent = parent; } + public void markAsCreatedFile(File file) + { + createdFilePaths.add(file.getAbsolutePath()); + } + public void delete() { //delete all the items @@ -52,6 +57,11 @@ public class TempFile File toDelete = new File(path); toDelete.delete(); + + if(!toDelete.getParentFile().getAbsolutePath().equalsIgnoreCase(new File(TEMP_DIRECTORY).getAbsolutePath())) + { + toDelete.getParentFile().delete(); + } } //delete parent if it's not the main temp directory From b69389cc5f342869bda885e334c53b31748f6793 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:08:34 -0600 Subject: [PATCH 12/82] FernFlower Decompiler Changes Uses the new Temp Files API. Exceptions are properly handled. File system errors are properly displayed. No more temporary files left behind. `-ren` / rename classes option fixed. --- .../impl/FernFlowerDecompiler.java | 192 +++++++++--------- 1 file changed, 92 insertions(+), 100 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 450cccdd..26331439 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -24,7 +24,7 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; @@ -72,124 +72,116 @@ public class FernFlowerDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - String start = TEMP_DIRECTORY + FS + MiscUtils.getUniqueNameBroken("", ".class"); + String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; - final File tempClass = new File(start + ".class"); - - String exception = ""; - try (FileOutputStream fos = new FileOutputStream(tempClass)) + try { - fos.write(bytes); + final TempFile tempFile = TempFile.createTemporaryFile(true, ".class"); + final File tempClassFile = tempFile.createFileFromExtension(false, false, ".class"); + tempFile.setParent(new File(TEMP_DIRECTORY)); + File tempOutputJavaFile = tempFile.createFileFromExtension(false, true, ".java"); + //File tempOutputJavaFile = new File(TEMP_DIRECTORY, tempClassFile.getName().substring(0, tempClassFile.getName().length()-6) + ".java"); + + try (FileOutputStream fos = new FileOutputStream(tempClassFile)) + { + fos.write(bytes); + } + + if (LAUNCH_DECOMPILERS_IN_NEW_PROCESS) + { + /*try + { + BytecodeViewer.sm.pauseBlocking(); + ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll( + new String[]{ExternalResources.getSingleton().getJavaCommand(true), "-jar", ExternalResources.getSingleton().findLibrary("fernflower")}, + generateMainMethod(tempClass.getAbsolutePath(), + new File(tempDirectory).getAbsolutePath()) + )); + Process p = pb.start(); + BytecodeViewer.createdProcesses.add(p); + p.waitFor(); + } catch (Exception e) { + BytecodeViewer.handleException(e); + } finally { + BytecodeViewer.sm.resumeBlocking(); + }*/ + } + else + { + org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClassFile.getAbsolutePath(), new File(TEMP_DIRECTORY).getAbsolutePath())); + } + + tempClassFile.delete(); + + //if rename is enabled the file name will be the actual class name + if (BytecodeViewer.viewer.ren.isSelected()) + { + int indexOfLastPackage = cn.name.lastIndexOf('/'); + String classNameNoPackages = indexOfLastPackage < 0 ? cn.name : cn.name.substring(indexOfLastPackage); + tempOutputJavaFile = new File(tempFile.getParent(), classNameNoPackages + ".java"); + tempFile.markAsCreatedFile(tempOutputJavaFile); + } + + //if the output file is found, read it + if (tempOutputJavaFile.exists()) + { + String s = DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); + + //cleanup temp files + tempFile.delete(); + + return s; + } + else + { + exception = "BCV Error: " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; + } } - catch (IOException e) + catch (Exception e) { StringWriter exceptionWriter = new StringWriter(); e.printStackTrace(new PrintWriter(exceptionWriter)); e.printStackTrace(); - exception = exceptionWriter.toString(); + + exception += NL + NL + exceptionWriter; } - - if (LAUNCH_DECOMPILERS_IN_NEW_PROCESS) - { - /*try - { - BytecodeViewer.sm.pauseBlocking(); - ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll( - new String[]{ExternalResources.getSingleton().getJavaCommand(true), "-jar", ExternalResources.getSingleton().findLibrary("fernflower")}, - generateMainMethod(tempClass.getAbsolutePath(), - new File(tempDirectory).getAbsolutePath()) - )); - Process p = pb.start(); - BytecodeViewer.createdProcesses.add(p); - p.waitFor(); - } catch (Exception e) { - BytecodeViewer.handleException(e); - } finally { - BytecodeViewer.sm.resumeBlocking(); - }*/ - } - else - { - try - { - org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClass.getAbsolutePath(), new File(TEMP_DIRECTORY).getAbsolutePath())); - } - catch (Throwable e) - { - StringWriter exceptionWriter = new StringWriter(); - e.printStackTrace(new PrintWriter(exceptionWriter)); - e.printStackTrace(); - exception = exceptionWriter.toString(); - } - } - - tempClass.delete(); - - String javaDir = start; - if (BytecodeViewer.viewer.ren.isSelected()) - { - javaDir = TEMP_DIRECTORY + "class_0"; - } - - final File outputJava = new File(javaDir + ".java"); - if (outputJava.exists()) - { - String s; - try - { - s = DiskReader.loadAsString(outputJava.getAbsolutePath()); - - outputJava.delete(); - - return s; - } - catch (Exception e) - { - StringWriter exceptionWriter = new StringWriter(); - e.printStackTrace(new PrintWriter(exceptionWriter)); - e.printStackTrace(); - - exception += NL + NL + exceptionWriter; - } - } - - return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } private String[] generateMainMethod(String className, String folder) { - return new String[]{"-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()), - "-ren=" + r(BytecodeViewer.viewer.ren.isSelected()), - className, folder}; + return new String[] + { + "-rbr=" + ffOnValue(BytecodeViewer.viewer.rbr.isSelected()), + "-rsy=" + ffOnValue(BytecodeViewer.viewer.rsy.isSelected()), + "-din=" + ffOnValue(BytecodeViewer.viewer.din.isSelected()), + "-dc4=" + ffOnValue(BytecodeViewer.viewer.dc4.isSelected()), + "-das=" + ffOnValue(BytecodeViewer.viewer.das.isSelected()), + "-hes=" + ffOnValue(BytecodeViewer.viewer.hes.isSelected()), + "-hdc=" + ffOnValue(BytecodeViewer.viewer.hdc.isSelected()), + "-dgs=" + ffOnValue(BytecodeViewer.viewer.dgs.isSelected()), + "-ner=" + ffOnValue(BytecodeViewer.viewer.ner.isSelected()), + "-den=" + ffOnValue(BytecodeViewer.viewer.den.isSelected()), + "-rgn=" + ffOnValue(BytecodeViewer.viewer.rgn.isSelected()), + "-bto=" + ffOnValue(BytecodeViewer.viewer.bto.isSelected()), + "-nns=" + ffOnValue(BytecodeViewer.viewer.nns.isSelected()), + "-uto=" + ffOnValue(BytecodeViewer.viewer.uto.isSelected()), + "-udv=" + ffOnValue(BytecodeViewer.viewer.udv.isSelected()), + "-rer=" + ffOnValue(BytecodeViewer.viewer.rer.isSelected()), + "-fdi=" + ffOnValue(BytecodeViewer.viewer.fdi.isSelected()), + "-asc=" + ffOnValue(BytecodeViewer.viewer.asc.isSelected()), + "-ren=" + ffOnValue(BytecodeViewer.viewer.ren.isSelected()), + className, folder + }; } - private String r(boolean b) + private String ffOnValue(boolean b) { if (b) - { return "1"; - } else - { return "0"; - } } } From 17e1d621fec969454da14791380602134c5eb4ac Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:12:43 -0600 Subject: [PATCH 13/82] Cleanup On Decompiler Failure --- .../decompilers/impl/ProcyonDecompiler.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 30c67921..a0bd5e64 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -82,12 +82,13 @@ public class ProcyonDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { + TempFile tempFile = null; String exception; try { - final TempFile tempFile = TempFile.createTemporaryFile(false, ".class"); - final File tempClassFile = tempFile.getFile(); + tempFile = TempFile.createTemporaryFile(false, ".class"); + File tempClassFile = tempFile.getFile(); //write the ClassNode bytes to the temp file try (FileOutputStream fos = new FileOutputStream(tempClassFile)) @@ -128,6 +129,10 @@ public class ProcyonDecompiler extends AbstractDecompiler exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; } + //delete all temporary files + if(tempFile != null) + tempFile.delete(); + return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } From 03d74f3dedfcc3f5e780a34fe316f8624965f0be Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:13:00 -0600 Subject: [PATCH 14/82] FernFlower Decompiler Refactoring --- .../impl/FernFlowerDecompiler.java | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 26331439..2ed9b0d9 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -72,21 +72,25 @@ public class FernFlowerDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { + TempFile tempFile = null; String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; try { - final TempFile tempFile = TempFile.createTemporaryFile(true, ".class"); - final File tempClassFile = tempFile.createFileFromExtension(false, false, ".class"); + tempFile = TempFile.createTemporaryFile(true, ".class"); + File tempClassFile = tempFile.createFileFromExtension(false, false, ".class"); + + //load java source from temp directory tempFile.setParent(new File(TEMP_DIRECTORY)); File tempOutputJavaFile = tempFile.createFileFromExtension(false, true, ".java"); - //File tempOutputJavaFile = new File(TEMP_DIRECTORY, tempClassFile.getName().substring(0, tempClassFile.getName().length()-6) + ".java"); + //write the class-file with bytes try (FileOutputStream fos = new FileOutputStream(tempClassFile)) { fos.write(bytes); } + //decompile the class-file if (LAUNCH_DECOMPILERS_IN_NEW_PROCESS) { /*try @@ -111,8 +115,6 @@ public class FernFlowerDecompiler extends AbstractDecompiler org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClassFile.getAbsolutePath(), new File(TEMP_DIRECTORY).getAbsolutePath())); } - tempClassFile.delete(); - //if rename is enabled the file name will be the actual class name if (BytecodeViewer.viewer.ren.isSelected()) { @@ -125,12 +127,12 @@ public class FernFlowerDecompiler extends AbstractDecompiler //if the output file is found, read it if (tempOutputJavaFile.exists()) { - String s = DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); + String javaSource = DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); //cleanup temp files tempFile.delete(); - return s; + return javaSource; } else { @@ -146,6 +148,10 @@ public class FernFlowerDecompiler extends AbstractDecompiler exception += NL + NL + exceptionWriter; } + //cleanup temp files + if(tempFile != null) + tempFile.delete(); + return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } From f121870272f85db62d53a616740a71f5b210889c Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:13:36 -0600 Subject: [PATCH 15/82] Procyon Refactoring --- .../decompilers/impl/ProcyonDecompiler.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index a0bd5e64..0c04b19a 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -58,27 +58,6 @@ public class ProcyonDecompiler extends AbstractDecompiler super("Procyon Decompiler", "proycon"); } - public DecompilerSettings getDecompilerSettings() - { - DecompilerSettings settings = new DecompilerSettings(); - settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.alwaysGenerateExceptionVars.isSelected()); - settings.setExcludeNestedTypes(BytecodeViewer.viewer.excludeNestedTypes.isSelected()); - settings.setShowDebugLineNumbers(BytecodeViewer.viewer.showDebugLineNumbers.isSelected()); - settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.includeLineNumbersInBytecode.isSelected()); - settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.includeErrorDiagnostics.isSelected()); - settings.setShowSyntheticMembers(BytecodeViewer.viewer.showSyntheticMembers.isSelected()); - settings.setSimplifyMemberReferences(BytecodeViewer.viewer.simplifyMemberReferences.isSelected()); - settings.setMergeVariables(BytecodeViewer.viewer.mergeVariables.isSelected()); - settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.forceExplicitTypeArguments.isSelected()); - settings.setForceExplicitImports(BytecodeViewer.viewer.forceExplicitImports.isSelected()); - settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.flattenSwitchBlocks.isSelected()); - settings.setRetainPointlessSwitches(BytecodeViewer.viewer.retainPointlessSwitches.isSelected()); - settings.setRetainRedundantCasts(BytecodeViewer.viewer.retainRedunantCasts.isSelected()); - settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.unicodeOutputEnabled.isSelected()); - settings.setJavaFormattingOptions(JavaFormattingOptions.createDefault()); - return settings; - } - @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { @@ -246,6 +225,27 @@ public class ProcyonDecompiler extends AbstractDecompiler } } + public DecompilerSettings getDecompilerSettings() + { + DecompilerSettings settings = new DecompilerSettings(); + settings.setAlwaysGenerateExceptionVariableForCatchBlocks(BytecodeViewer.viewer.alwaysGenerateExceptionVars.isSelected()); + settings.setExcludeNestedTypes(BytecodeViewer.viewer.excludeNestedTypes.isSelected()); + settings.setShowDebugLineNumbers(BytecodeViewer.viewer.showDebugLineNumbers.isSelected()); + settings.setIncludeLineNumbersInBytecode(BytecodeViewer.viewer.includeLineNumbersInBytecode.isSelected()); + settings.setIncludeErrorDiagnostics(BytecodeViewer.viewer.includeErrorDiagnostics.isSelected()); + settings.setShowSyntheticMembers(BytecodeViewer.viewer.showSyntheticMembers.isSelected()); + settings.setSimplifyMemberReferences(BytecodeViewer.viewer.simplifyMemberReferences.isSelected()); + settings.setMergeVariables(BytecodeViewer.viewer.mergeVariables.isSelected()); + settings.setForceExplicitTypeArguments(BytecodeViewer.viewer.forceExplicitTypeArguments.isSelected()); + settings.setForceExplicitImports(BytecodeViewer.viewer.forceExplicitImports.isSelected()); + settings.setFlattenSwitchBlocks(BytecodeViewer.viewer.flattenSwitchBlocks.isSelected()); + settings.setRetainPointlessSwitches(BytecodeViewer.viewer.retainPointlessSwitches.isSelected()); + settings.setRetainRedundantCasts(BytecodeViewer.viewer.retainRedunantCasts.isSelected()); + settings.setUnicodeOutputEnabled(BytecodeViewer.viewer.unicodeOutputEnabled.isSelected()); + settings.setJavaFormattingOptions(JavaFormattingOptions.createDefault()); + return settings; + } + /** * @author DeathMarine */ From be2afd4aff377ddc8f9e9f22de24ee41e37da324 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:24:10 -0600 Subject: [PATCH 16/82] FernFlower Temp Files API Fix --- .../bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 2ed9b0d9..08b00411 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -78,7 +78,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler try { tempFile = TempFile.createTemporaryFile(true, ".class"); - File tempClassFile = tempFile.createFileFromExtension(false, false, ".class"); + File tempClassFile = tempFile.getFile(); //load java source from temp directory tempFile.setParent(new File(TEMP_DIRECTORY)); From 36e6dbf875a195c98c3eb73020b9f695b4a86a18 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:26:19 -0600 Subject: [PATCH 17/82] FernFlower Decompiler Improvements --- .../impl/FernFlowerDecompiler.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 08b00411..fc42ace7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -126,18 +126,9 @@ public class FernFlowerDecompiler extends AbstractDecompiler //if the output file is found, read it if (tempOutputJavaFile.exists()) - { - String javaSource = DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); - - //cleanup temp files - tempFile.delete(); - - return javaSource; - } + return DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); else - { exception = "BCV Error: " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; - } } catch (Exception e) { @@ -147,10 +138,12 @@ public class FernFlowerDecompiler extends AbstractDecompiler exception += NL + NL + exceptionWriter; } - - //cleanup temp files - if(tempFile != null) - tempFile.delete(); + finally + { + //cleanup temp files + if(tempFile != null) + tempFile.delete(); + } return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; From 45d722cb2d192921d7685362a0350afef74b5e6f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:30:10 -0600 Subject: [PATCH 18/82] FernFlower Catch All --- .../bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index fc42ace7..52e05ff2 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -130,7 +130,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler else exception = "BCV Error: " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; } - catch (Exception e) + catch (Throwable e) { StringWriter exceptionWriter = new StringWriter(); e.printStackTrace(new PrintWriter(exceptionWriter)); From 3f458022578897832daeedc383da324d6e8552bd Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:30:24 -0600 Subject: [PATCH 19/82] Procyon Ensure Cleanup --- .../decompilers/impl/ProcyonDecompiler.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 0c04b19a..96cc11ea 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -94,9 +94,6 @@ public class ProcyonDecompiler extends AbstractDecompiler StringWriter stringwriter = new StringWriter(); settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions); - //delete all temporary files - tempFile.delete(); - return EncodeUtils.unicodeToString(stringwriter.toString()); } catch (Throwable e) @@ -107,10 +104,12 @@ public class ProcyonDecompiler extends AbstractDecompiler exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; } - - //delete all temporary files - if(tempFile != null) - tempFile.delete(); + finally + { + //delete all temporary files + if(tempFile != null) + tempFile.delete(); + } return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; From 7fa79786917363e7401e16f32b1e51de6fa7de26 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:38:13 -0600 Subject: [PATCH 20/82] JavaP Disassembler Improvements Uses the new Temp Files API. Better failing. Refactoring. --- .../decompilers/impl/JavapDisassembler.java | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index dfb4e13d..d19ee12d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -22,24 +22,27 @@ import me.konloch.kontainer.io.DiskWriter; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Configuration; -import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsolePrintStream; import the.bytecode.club.bytecodeviewer.resources.ExternalResources; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; -import static the.bytecode.club.bytecodeviewer.Constants.FS; -import static the.bytecode.club.bytecodeviewer.api.ExceptionUI.SEND_STACKTRACE_TO; +import static the.bytecode.club.bytecodeviewer.Constants.NL; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; /** * Javap disassembler - *

+ * * https://github.com/Konloch/bytecode-viewer/issues/93 * * @author Konloch @@ -59,21 +62,23 @@ public class JavapDisassembler extends AbstractDecompiler if (!ExternalResources.getSingleton().hasJavaToolsSet()) return "Set Java Tools Path!"; - return synchronizedDecompilation(cn, bytes); + return disassembleJavaP(cn, bytes); } - private synchronized String synchronizedDecompilation(ClassNode cn, byte[] b) + private synchronized String disassembleJavaP(ClassNode cn, byte[] b) { - final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); - final File tempClass = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".class"); - - tempDirectory.mkdir(); - - DiskWriter.replaceFileBytes(tempClass.getAbsolutePath(), b, false); + TempFile tempFile = null; + String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; JFrameConsolePrintStream sysOutBuffer = null; + try { + tempFile = TempFile.createTemporaryFile(true, ".class"); + File tempClassFile = tempFile.getFile(); + + DiskWriter.replaceFileBytes(tempClassFile.getAbsolutePath(), b, false); + //load java tools into a temporary classloader URLClassLoader child = new URLClassLoader(new URL[]{new File(Configuration.javaTools).toURI().toURL()}, this.getClass().getClassLoader()); @@ -88,33 +93,45 @@ public class JavapDisassembler extends AbstractDecompiler BytecodeViewer.sm.silenceExec(true); //invoke Javap - main.invoke(null, (Object) new String[]{"-p", //Shows all classes and members - "-c", //Prints out disassembled code - //"-l", //Prints out line and local variable tables - "-constants", //Shows static final constants - tempClass.getAbsolutePath()}); + try + { + main.invoke(null, (Object) new String[]{"-p", //Shows all classes and members + "-c", //Prints out disassembled code + //"-l", //Prints out line and local variable tables + "-constants", //Shows static final constants + tempClassFile.getAbsolutePath()}); + } + catch (InvocationTargetException e) + { + //expected warning behaviour on modern JDKs (17+) + } + + //return output + sysOutBuffer.finished(); + return sysOutBuffer.getTextAreaOutputStreamOut().getBuffer().toString(); } catch (IllegalAccessException e) { return TranslatedStrings.ILLEGAL_ACCESS_ERROR.toString(); } - catch (Exception e) + catch (Throwable e) { + StringWriter exceptionWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(exceptionWriter)); e.printStackTrace(); + + exception += NL + NL + exceptionWriter; } finally { BytecodeViewer.sm.silenceExec(false); - tempClass.delete(); + + if(tempFile != null) + tempFile.delete(); } - if (sysOutBuffer != null) - { - sysOutBuffer.finished(); - return sysOutBuffer.getTextAreaOutputStreamOut().getBuffer().toString(); - } - - return SEND_STACKTRACE_TO; + return "JavaP " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override From 3f407ea50663080a28c3f3f8803486a532d8da61 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:40:26 -0600 Subject: [PATCH 21/82] Cleanup --- .../club/bytecodeviewer/decompilers/impl/JavapDisassembler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index d19ee12d..cf57240c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -70,7 +70,7 @@ public class JavapDisassembler extends AbstractDecompiler TempFile tempFile = null; String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; - JFrameConsolePrintStream sysOutBuffer = null; + JFrameConsolePrintStream sysOutBuffer; try { From 334a9231fcece12800ae9fbcdc91e1f1bc939408 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:47:52 -0600 Subject: [PATCH 22/82] Temp File API Improvements --- .../the/bytecode/club/bytecodeviewer/util/TempFile.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index 412c3317..d3ff04cb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -13,7 +13,7 @@ public class TempFile { private File parent; private final File file; - private final String uniqueName; + private String uniqueName; private final HashSet createdFilePaths = new HashSet<>(); public TempFile(File file, String uniqueName) @@ -44,6 +44,11 @@ public class TempFile this.parent = parent; } + public void setUniqueName(String uniqueName) + { + this.uniqueName = uniqueName; + } + public void markAsCreatedFile(File file) { createdFilePaths.add(file.getAbsolutePath()); From ac025d6b178066d2c64baa76d929a7d34b11768e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:48:14 -0600 Subject: [PATCH 23/82] Comments --- .../bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java | 1 + .../club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 52e05ff2..fe526fab 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -77,6 +77,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler try { + //create the temporary files tempFile = TempFile.createTemporaryFile(true, ".class"); File tempClassFile = tempFile.getFile(); diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 96cc11ea..0268ad81 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -66,6 +66,7 @@ public class ProcyonDecompiler extends AbstractDecompiler try { + //create the temporary files tempFile = TempFile.createTemporaryFile(false, ".class"); File tempClassFile = tempFile.getFile(); From 23c125cacd427a956c25a6d3238444a585a1ac79 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:48:26 -0600 Subject: [PATCH 24/82] JavaP Cleanup --- .../decompilers/impl/JavapDisassembler.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index cf57240c..8e384af8 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -65,7 +65,7 @@ public class JavapDisassembler extends AbstractDecompiler return disassembleJavaP(cn, bytes); } - private synchronized String disassembleJavaP(ClassNode cn, byte[] b) + private synchronized String disassembleJavaP(ClassNode cn, byte[] bytes) { TempFile tempFile = null; String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; @@ -74,10 +74,12 @@ public class JavapDisassembler extends AbstractDecompiler try { + //create the temporary files tempFile = TempFile.createTemporaryFile(true, ".class"); File tempClassFile = tempFile.getFile(); - DiskWriter.replaceFileBytes(tempClassFile.getAbsolutePath(), b, false); + //write the bytes to the class-file + DiskWriter.replaceFileBytes(tempClassFile.getAbsolutePath(), bytes, false); //load java tools into a temporary classloader URLClassLoader child = new URLClassLoader(new URL[]{new File(Configuration.javaTools).toURI().toURL()}, this.getClass().getClassLoader()); @@ -103,7 +105,7 @@ public class JavapDisassembler extends AbstractDecompiler } catch (InvocationTargetException e) { - //expected warning behaviour on modern JDKs (17+) + //expected warning behaviour on JDK-15 } //return output From 95da798c586b142382ddb7bc4bdf2f3ce39eb251 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:54:17 -0600 Subject: [PATCH 25/82] Handle Deleting Folders Better --- .../club/bytecodeviewer/util/TempFile.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index d3ff04cb..8cbf9456 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -64,16 +64,28 @@ public class TempFile toDelete.delete(); if(!toDelete.getParentFile().getAbsolutePath().equalsIgnoreCase(new File(TEMP_DIRECTORY).getAbsolutePath())) - { - toDelete.getParentFile().delete(); - } + deleteFolder(toDelete.getParentFile()); } //delete parent if it's not the main temp directory if(!getParent().getAbsolutePath().equalsIgnoreCase(new File(TEMP_DIRECTORY).getAbsolutePath())) + deleteFolder(getParent()); + } + + private void deleteFolder(File file) + { + File[] files = file.listFiles(); + + if(files != null) { - getParent().delete(); + for(File subFile : files) + { + if(subFile.isDirectory()) + deleteFolder(subFile); + } } + + file.delete(); } public File createFileFromExtension(String extension) From 1a5f3fdae56fdb66947193510eba19dec1400484 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 12:55:41 -0600 Subject: [PATCH 26/82] JD-GUI Decompiler Improvements Uses the new Temp Files API. Better Failing. Temporary files are properly deleted after use. --- .../decompilers/impl/JDGUIDecompiler.java | 39 +++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java index 0c9f8654..d2f98769 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java @@ -31,6 +31,7 @@ import the.bytecode.club.bytecodeviewer.decompilers.jdgui.JDGUIClassFileUtil; import the.bytecode.club.bytecodeviewer.decompilers.jdgui.PlainTextPrinter; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; @@ -57,20 +58,23 @@ public class JDGUIDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { + TempFile tempFile = null; String exception; try { - final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); - tempDirectory.mkdir(); - - final File tempClass = new File(tempDirectory.getAbsolutePath() + FS + cn.name + ".class"); - final File tempJava = new File(tempDirectory.getAbsolutePath() + FS + cn.name + ".java"); + //create the temporary files + tempFile = TempFile.createTemporaryFile(true, ".class"); + tempFile.setUniqueName(cn.name); + File tempClassFile = tempFile.createFileFromExtension(false, false, ".class"); + File tempJavaFile = tempFile.createFileFromExtension(false, false, ".java"); + //make any folders for the packages if (cn.name.contains("/")) { String[] raw = cn.name.split("/"); - String path = tempDirectory.getAbsolutePath() + FS; + String path = tempFile.getParent().getAbsolutePath() + FS; + for (int i = 0; i < raw.length - 1; i++) { path += raw[i] + FS; @@ -79,16 +83,12 @@ public class JDGUIDecompiler extends AbstractDecompiler } } - try (FileOutputStream fos = new FileOutputStream(tempClass)) + try (FileOutputStream fos = new FileOutputStream(tempClassFile)) { fos.write(bytes); } - catch (IOException e) - { - BytecodeViewer.handleException(e); - } - String pathToClass = tempClass.getAbsolutePath().replace('/', File.separatorChar).replace('\\', File.separatorChar); + String pathToClass = tempClassFile.getAbsolutePath().replace('/', File.separatorChar).replace('\\', File.separatorChar); String directoryPath = JDGUIClassFileUtil.ExtractDirectoryPath(pathToClass); String internalPath = JDGUIClassFileUtil.ExtractInternalPath(directoryPath, pathToClass); @@ -111,14 +111,15 @@ public class JDGUIDecompiler extends AbstractDecompiler org.jd.core.v1.api.Decompiler decompiler = new ClassFileToJavaSourceDecompiler(); - try (PrintStream ps = new PrintStream(tempJava.getAbsolutePath()); PlainTextPrinter printer = new PlainTextPrinter(preferences, ps)) + try (PrintStream ps = new PrintStream(tempJavaFile.getAbsolutePath()); + PlainTextPrinter printer = new PlainTextPrinter(preferences, ps)) { decompiler.decompile(loader, printer, internalPath, preferences.getPreferences()); } - return DiskReader.loadAsString(tempJava.getAbsolutePath()); + return DiskReader.loadAsString(tempJavaFile.getAbsolutePath()); } - catch (Exception e) + catch (Throwable e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); @@ -126,8 +127,14 @@ public class JDGUIDecompiler extends AbstractDecompiler exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; } + finally + { + if(tempFile != null) + tempFile.delete(); + } - return JDGUI + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + return JDGUI + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override From e1763632ff45eb5b0643edaa76f67778004f306e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 13:04:36 -0600 Subject: [PATCH 27/82] Text Formatting Error --- .../java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java b/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java index 3f7d0a9a..7f8b93cb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/api/ExceptionUI.java @@ -41,7 +41,7 @@ import static the.bytecode.club.bytecodeviewer.Constants.*; public class ExceptionUI extends JFrameConsole { public static final String KONLOCH = "https://github.com/Konloch/bytecode-viewer/issues" + - "or Konloch at https://the.bytecode.club or konloch@gmail.com"; + " or Konloch at https://the.bytecode.club or konloch@gmail.com"; public static final String SEND_STACKTRACE_TO = buildErrorLogHeader(KONLOCH); public static final String SEND_STACKTRACE_TO_NL = SEND_STACKTRACE_TO + NL + NL; From f20cdee888b418738a5019c3545c32713b3d1154 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 13:51:52 -0600 Subject: [PATCH 28/82] Created Exception Utils --- .../bytecodeviewer/util/ExceptionUtils.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/util/ExceptionUtils.java diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ExceptionUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ExceptionUtils.java new file mode 100644 index 00000000..a05d2e1b --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ExceptionUtils.java @@ -0,0 +1,20 @@ +package the.bytecode.club.bytecodeviewer.util; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * @author Konloch + * @since 10/2/2024 + */ +public class ExceptionUtils +{ + public static String exceptionToString(Throwable e) + { + StringWriter exceptionWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(exceptionWriter)); + e.printStackTrace(); + + return exceptionWriter.toString(); + } +} From 124fa193df886af3dd2c1382a8e02fac874e36fb Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:24:55 -0600 Subject: [PATCH 29/82] Cleanup Procyon Exceptions --- .../bytecodeviewer/decompilers/impl/ProcyonDecompiler.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 0268ad81..46696722 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -31,6 +31,7 @@ import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.EncodeUtils; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; @@ -99,11 +100,7 @@ public class ProcyonDecompiler extends AbstractDecompiler } catch (Throwable e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - - exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; + exception = NL + NL + ExceptionUtils.exceptionToString(e); } finally { From a826a8e979a82d6b3b00b96e9aaaf07aeb6f922f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:25:03 -0600 Subject: [PATCH 30/82] Cleanup JD-GUI Exceptions --- .../bytecodeviewer/decompilers/impl/JDGUIDecompiler.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java index d2f98769..5f56b3b8 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java @@ -30,6 +30,7 @@ import the.bytecode.club.bytecodeviewer.decompilers.jdgui.DirectoryLoader; import the.bytecode.club.bytecodeviewer.decompilers.jdgui.JDGUIClassFileUtil; import the.bytecode.club.bytecodeviewer.decompilers.jdgui.PlainTextPrinter; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.MiscUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; @@ -121,11 +122,7 @@ public class JDGUIDecompiler extends AbstractDecompiler } catch (Throwable e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - - exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; + exception = NL + NL + ExceptionUtils.exceptionToString(e); } finally { From ab2ce702d9c3c95941bbe7ae11cb86849a808aa9 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:25:13 -0600 Subject: [PATCH 31/82] Cleanup Javap Exceptions --- .../bytecodeviewer/decompilers/impl/JavapDisassembler.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index 8e384af8..f7fbb3c3 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -27,6 +27,7 @@ import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsolePrintStream; import the.bytecode.club.bytecodeviewer.resources.ExternalResources; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.File; @@ -118,11 +119,7 @@ public class JavapDisassembler extends AbstractDecompiler } catch (Throwable e) { - StringWriter exceptionWriter = new StringWriter(); - e.printStackTrace(new PrintWriter(exceptionWriter)); - e.printStackTrace(); - - exception += NL + NL + exceptionWriter; + exception = NL + NL + ExceptionUtils.exceptionToString(e); } finally { From 8d947b67480a2360b228386dd9800b1c310463e8 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:25:26 -0600 Subject: [PATCH 32/82] Cleanup FernFlower Exceptions --- .../decompilers/impl/FernFlowerDecompiler.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index fe526fab..213a61ff 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -24,6 +24,7 @@ import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; @@ -73,7 +74,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler public String decompileClassNode(ClassNode cn, byte[] bytes) { TempFile tempFile = null; - String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; + String exception; try { @@ -129,15 +130,11 @@ public class FernFlowerDecompiler extends AbstractDecompiler if (tempOutputJavaFile.exists()) return DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); else - exception = "BCV Error: " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; + exception = FERNFLOWER + " " + ERROR + "! " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; } catch (Throwable e) { - StringWriter exceptionWriter = new StringWriter(); - e.printStackTrace(new PrintWriter(exceptionWriter)); - e.printStackTrace(); - - exception += NL + NL + exceptionWriter; + exception = NL + NL + ExceptionUtils.exceptionToString(e); } finally { From a9beeeeaaea2348c2360c9fe10f4678ec63a17f3 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:33:22 -0600 Subject: [PATCH 33/82] Fix Collision Prevention --- .../java/the/bytecode/club/bytecodeviewer/util/JarUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/JarUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/JarUtils.java index cd209f85..33efba1f 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/JarUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/JarUtils.java @@ -356,7 +356,7 @@ public class JarUtils String name = cn.name + ".class"; - if (!fileCollisionPrevention.add(name)) + if (fileCollisionPrevention.add(name)) { out.putNextEntry(new ZipEntry(name)); out.write(cw.toByteArray()); From e456952f5cf1a9e90d6fa799b9f1a5c870764e2e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 14:41:49 -0600 Subject: [PATCH 34/82] ZipUtils Cleanup --- .../club/bytecodeviewer/util/ZipUtils.java | 40 +++++-------------- 1 file changed, 10 insertions(+), 30 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java index fbc74dc1..c64aec63 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ZipUtils.java @@ -46,53 +46,33 @@ public final class ZipUtils String canonicalDestDir = new File(destinationDir).getCanonicalPath(); if (!canonicalDestDir.endsWith(File.separator)) - { canonicalDestDir += File.separator; - } - File file = new File(jarPath); - - try (JarFile jar = new JarFile(file)) + try (JarFile jarFile = new JarFile(new File(jarPath))) { - - // fist get all directories, - // then make those directory on the destination Path - /*for (Enumeration enums = jar.entries(); enums.hasMoreElements(); ) { - JarEntry entry = (JarEntry) enums.nextElement(); - - String fileName = destinationDir + File.separator + entry.getName(); - File f = new File(fileName); - - if (fileName.endsWith("/")) { - f.mkdirs(); - } - - }*/ - //now create all files - for (Enumeration enums = jar.entries(); enums.hasMoreElements(); ) + for (Enumeration enums = jarFile.entries(); + enums.hasMoreElements(); ) { JarEntry entry = enums.nextElement(); String fileName = destinationDir + File.separator + entry.getName(); - File f = new File(fileName); + File file = new File(fileName); - if (!f.getCanonicalPath().startsWith(canonicalDestDir)) + if (!file.getCanonicalPath().startsWith(canonicalDestDir)) { System.out.println("Zip Slip exploit detected. Skipping entry " + entry.getName()); continue; } - File parent = f.getParentFile(); + File parent = file.getParentFile(); if (!parent.exists()) - { parent.mkdirs(); - } if (!fileName.endsWith("/")) { - try (InputStream is = jar.getInputStream(entry); FileOutputStream fos = new FileOutputStream(f)) + try (InputStream is = jarFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(file)) { // write contents of 'is' to 'fos' while (is.available() > 0) @@ -117,6 +97,7 @@ public final class ZipUtils try (FileInputStream in = new FileInputStream(inputFile)) { int len; + while ((len = in.read(buffer)) > 0) { zos.write(buffer, 0, len); @@ -153,9 +134,7 @@ public final class ZipUtils File folder = new File(srcFile); if (folder.isDirectory()) - { addFolderToZip(path, srcFile, zip, ignore); - } else { byte[] buf = new byte[1024]; @@ -185,10 +164,11 @@ public final class ZipUtils File folder = new File(srcFile); String check = path.toLowerCase(); + //if(check.startsWith("decoded unknown") || check.startsWith("decoded lib") || check.startsWith("decoded // assets") || check.startsWith("decoded original") || check.startsWith("decoded smali") || check.startsWith // ("decoded apktool.yml")) - if (check.startsWith("decoded original") || check.startsWith("decoded smali") || check.startsWith("decoded " + "apktool.yml")) + if (check.startsWith("decoded original") || check.startsWith("decoded smali") || check.startsWith("decoded apktool.yml")) return; //if(path.equals("original") || path.equals("classes.dex") || path.equals("apktool.yml")) From 70bde7be457e9fd872f41d84440b81aa0dfa921d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:06:56 -0600 Subject: [PATCH 35/82] Added Process Utils --- .../bytecodeviewer/util/ProcessUtils.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java new file mode 100644 index 00000000..da29925f --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java @@ -0,0 +1,91 @@ +package the.bytecode.club.bytecodeviewer.util; + +import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import static the.bytecode.club.bytecodeviewer.Constants.NL; + +/** + * @author Konloch + * @since 10/2/2024 + */ +public class ProcessUtils +{ + public static StringBuilder mergeLogs(StringBuilder out, StringBuilder err, int exitCode) + { + StringBuilder logs = new StringBuilder(NL + NL); + + if(out.toString().trim().length() >= 1) + logs.append(TranslatedStrings.PROCESS2).append(" out:").append(NL).append(NL) + .append(out).append(NL).append(NL); + + if(err.toString().trim().length() >= 1) + logs.append(TranslatedStrings.PROCESS2).append(" err:").append(NL).append(NL) + .append(err).append(NL).append(NL); + + logs.append(TranslatedStrings.ERROR2).append(NL).append(NL); + logs.append(TranslatedStrings.EXIT_VALUE_IS).append(" ") + .append(exitCode).append(NL).append(NL); + + return logs; + } + + public static void readProcessToStringBuilder(Process process, StringBuilder out, StringBuilder err) throws IOException + { + + try (InputStream is = process.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) + { + BytecodeViewer.getTaskManager().delayLoop(100, task -> + { + if(!process.isAlive()) + task.stop(); + + try + { + String line; + + while ((line = br.readLine()) != null) + { + out.append(NL).append(line); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + }); + } + + try (InputStream is = process.getErrorStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) + { + BytecodeViewer.getTaskManager().delayLoop(100, task -> + { + if(!process.isAlive()) + task.stop(); + + try + { + String line; + + while ((line = br.readLine()) != null) + { + err.append(NL).append(line); + } + } + catch (Exception e) + { + e.printStackTrace(); + } + }); + } + } +} From efb43e6fb9e2700fe9cf0adccbd26f9728093564 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:10:54 -0600 Subject: [PATCH 36/82] Silence IO Errors --- .../the/bytecode/club/bytecodeviewer/util/ProcessUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java index da29925f..9dcc009a 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java @@ -56,6 +56,9 @@ public class ProcessUtils out.append(NL).append(line); } } + catch (IOException ignore) + { + } catch (Exception e) { e.printStackTrace(); @@ -81,6 +84,9 @@ public class ProcessUtils err.append(NL).append(line); } } + catch (IOException ignore) + { + } catch (Exception e) { e.printStackTrace(); From 838e40f55e2c52246cdc7f92047b0e997d3a5d68 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:19:05 -0600 Subject: [PATCH 37/82] FernFlower Exception Cleanup --- .../bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 213a61ff..0e892720 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -134,7 +134,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler } catch (Throwable e) { - exception = NL + NL + ExceptionUtils.exceptionToString(e); + exception = ExceptionUtils.exceptionToString(e); } finally { From 38920b95dd6b96914fb395b4c674f4373c76fa5c Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:19:27 -0600 Subject: [PATCH 38/82] Procyon Decompiler Cleanup --- .../club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 46696722..6bd94d7e 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -100,7 +100,7 @@ public class ProcyonDecompiler extends AbstractDecompiler } catch (Throwable e) { - exception = NL + NL + ExceptionUtils.exceptionToString(e); + exception = ExceptionUtils.exceptionToString(e); } finally { From 522ea379180fdcc3ea247d21e73b6fd9cfce2804 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:48:49 -0600 Subject: [PATCH 39/82] Added Decompiler Simulated Errors Meant for aiding in writing decompiler error notes / translations. --- src/main/java/the/bytecode/club/bytecodeviewer/Constants.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java index 4523ef92..2ebf09e6 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java @@ -87,6 +87,7 @@ public class Constants public static final String LIBS_DIRECTORY = getBCVDirectory() + FS + "libs" + FS; public static String krakatauWorkingDirectory = getBCVDirectory() + FS + "krakatau_" + krakatauVersion; public static String enjarifyWorkingDirectory = getBCVDirectory() + FS + "enjarify_" + enjarifyVersion; + public static final boolean DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS = DEV_MODE && true; //enable true / false to disable public static final PrintStream ERR = System.err; public static final PrintStream OUT = System.out; From 97a1425b9b7de292167b2ec3af67f381d06c83bb Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 15:49:09 -0600 Subject: [PATCH 40/82] Code Cleanup --- src/main/java/me/konloch/kontainer/io/DiskReader.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/me/konloch/kontainer/io/DiskReader.java b/src/main/java/me/konloch/kontainer/io/DiskReader.java index 4824c365..1dc07c95 100644 --- a/src/main/java/me/konloch/kontainer/io/DiskReader.java +++ b/src/main/java/me/konloch/kontainer/io/DiskReader.java @@ -33,7 +33,8 @@ public class DiskReader if (!file.exists()) // doesn't exist, return empty return array; - try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr)) + try (FileReader fr = new FileReader(file); + BufferedReader reader = new BufferedReader(fr)) { String add; @@ -66,7 +67,8 @@ public class DiskReader { StringBuilder s = new StringBuilder(); - try (FileReader fr = new FileReader(fileName); BufferedReader reader = new BufferedReader(fr)) + try (FileReader fr = new FileReader(fileName); + BufferedReader reader = new BufferedReader(fr)) { for (String add = reader.readLine(); add != null; add = reader.readLine()) { @@ -89,7 +91,8 @@ public class DiskReader array = new ArrayList<>(); File file = new File(fileName); - try (FileReader fr = new FileReader(file); BufferedReader reader = new BufferedReader(fr)) + try (FileReader fr = new FileReader(file); + BufferedReader reader = new BufferedReader(fr)) { String add; From f842eca7ec494bac31e2e11fa1a28f1ae15fc4db Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:09:10 -0600 Subject: [PATCH 41/82] Added Dev Mode Translation This is not meant to be translated, but it's added in here as this is where we store our global strings. --- .../club/bytecodeviewer/translation/TranslatedStrings.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/translation/TranslatedStrings.java b/src/main/java/the/bytecode/club/bytecodeviewer/translation/TranslatedStrings.java index 340fcac2..7be99424 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/translation/TranslatedStrings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/translation/TranslatedStrings.java @@ -41,6 +41,7 @@ public enum TranslatedStrings PRODUCT_H_NAME("Bytecode-Viewer"), WEBSITE("https://bytecodeviewer.com"), TBC("https://the.bytecode.club"), + DEV_MODE_SIMULATED_ERROR("Developer-Mode: Simulated Error"), EDITABLE, JAVA, From 98bacf83efa05b6f50bf68cfaa9458e1d8162308 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:10:04 -0600 Subject: [PATCH 42/82] Temporary File API Update --- .../the/bytecode/club/bytecodeviewer/util/TempFile.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index 8cbf9456..208036a5 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -39,6 +39,11 @@ public class TempFile return uniqueName; } + public void newTemporaryParent() + { + setParent(createTempDirectory()); + } + public void setParent(File parent) { this.parent = parent; @@ -98,7 +103,6 @@ public class TempFile File file; String uniqueName = newUniqueName ? MiscUtils.getUniqueName("", extension) : this.uniqueName + extension; - //String uniqueName = this.uniqueName + extension; //generate a new name until the directory no longer exists while((file = new File(parent, uniqueName)).exists()) From 2ade8f94818e8aeba2548a9a52ced36606af82ea Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:10:50 -0600 Subject: [PATCH 43/82] Process Utils API Update --- .../bytecodeviewer/util/ProcessUtils.java | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java index 9dcc009a..1ac11ba1 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java @@ -18,14 +18,14 @@ public class ProcessUtils { public static StringBuilder mergeLogs(StringBuilder out, StringBuilder err, int exitCode) { - StringBuilder logs = new StringBuilder(NL + NL); + StringBuilder logs = new StringBuilder(); if(out.toString().trim().length() >= 1) - logs.append(TranslatedStrings.PROCESS2).append(" out:").append(NL).append(NL) + logs.append(TranslatedStrings.PROCESS2).append(" out:") .append(out).append(NL).append(NL); if(err.toString().trim().length() >= 1) - logs.append(TranslatedStrings.PROCESS2).append(" err:").append(NL).append(NL) + logs.append(TranslatedStrings.PROCESS2).append(" err:") .append(err).append(NL).append(NL); logs.append(TranslatedStrings.ERROR2).append(NL).append(NL); @@ -37,12 +37,43 @@ public class ProcessUtils public static void readProcessToStringBuilder(Process process, StringBuilder out, StringBuilder err) throws IOException { - + //Read out dir output try (InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) { - BytecodeViewer.getTaskManager().delayLoop(100, task -> + String line; + while ((line = br.readLine()) != null) + { + out.append(NL).append(line); + } + } + catch (IOException ignore) + { + } + + try (InputStream is = process.getErrorStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) + { + String line; + while ((line = br.readLine()) != null) + { + err.append(NL).append(line); + } + } + catch (IOException ignore) + { + } + } + + public static void readProcessToStringBuilderAsync(Process process, StringBuilder out, StringBuilder err) throws IOException + { + try (InputStream is = process.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr)) + { + BytecodeViewer.getTaskManager().delayLoop(25, task -> { if(!process.isAlive()) task.stop(); @@ -70,7 +101,7 @@ public class ProcessUtils InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr)) { - BytecodeViewer.getTaskManager().delayLoop(100, task -> + BytecodeViewer.getTaskManager().delayLoop(25, task -> { if(!process.isAlive()) task.stop(); From 7105cf93c39fbcd9e9bf16b5a6be33408d88cad8 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:11:26 -0600 Subject: [PATCH 44/82] Comments --- .../club/bytecodeviewer/decompilers/AbstractDecompiler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java index 6cf9563b..517fdd18 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java @@ -45,6 +45,9 @@ public abstract class AbstractDecompiler return decompilerName; } + /** + * Used for the compressed exports (Zip / Jar) + */ public String getDecompilerNameProgrammatic() { return decompilerNameProgrammatic; From ce2d2cd96c456b77c1ecf9fbe1cf31fecb56493a Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:12:32 -0600 Subject: [PATCH 45/82] Abstract Decompiler API Update --- .../bytecode/club/bytecodeviewer/decompilers/Decompiler.java | 5 ++++- .../club/bytecodeviewer/resources/ResourceDecompiling.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java index b255f80c..bdb5f998 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java @@ -63,7 +63,10 @@ public enum Decompiler return getDecompiler().getDecompilerName(); } - public String getDecompilerNameProgrammic() + /** + * Used for the compressed exports (Zip / Jar) + */ + public String getDecompilerNameProgrammatic() { if(decompiler == null) return ""; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/resources/ResourceDecompiling.java b/src/main/java/the/bytecode/club/bytecodeviewer/resources/ResourceDecompiling.java index a14478ab..29c28f64 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/resources/ResourceDecompiling.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/resources/ResourceDecompiling.java @@ -258,7 +258,7 @@ public class ResourceDecompiling //decompile all opened classes to zip decompiler.getDecompiler().decompileToZip(targetJar.getAbsolutePath(), saveAll ? MiscUtils.append(outputZip, - "-" + decompiler.getDecompilerNameProgrammic() + ".zip") : outputZip.getAbsolutePath()); + "-" + decompiler.getDecompilerNameProgrammatic() + ".zip") : outputZip.getAbsolutePath()); //signal to the user that BCV is finished performing that action BytecodeViewer.updateBusyStatus(false); @@ -271,7 +271,7 @@ public class ResourceDecompiling //decompile the currently opened resource and save it to the specified file DiskWriter.replaceFile(saveAll ? MiscUtils.append(outputFile, - "-" + decompiler.getDecompilerNameProgrammic() + ".java") : outputFile.getAbsolutePath(), BCV.decompileCurrentlyOpenedClassNode(decompiler), false); + "-" + decompiler.getDecompilerNameProgrammatic() + ".java") : outputFile.getAbsolutePath(), BCV.decompileCurrentlyOpenedClassNode(decompiler), false); //signal to the user that BCV is finished performing that action BytecodeViewer.updateBusyStatus(false); From d39885407c335088c3ba9028540205266c76fc3b Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:12:58 -0600 Subject: [PATCH 46/82] Smali Disassembler Error Formatting --- .../bytecodeviewer/decompilers/impl/SmaliDisassembler.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java index 19e5318a..a175cc4d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java @@ -128,7 +128,8 @@ public class SmaliDisassembler extends AbstractDecompiler exception += ExceptionUI.SEND_STACKTRACE_TO_NL + sw; } - return SMALI + " " + DISASSEMBLER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + return SMALI + " " + DISASSEMBLER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override From b9ff7d128ac8b83dabb603586f42e35db7448338 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:30:41 -0600 Subject: [PATCH 47/82] Abstract Decompiler API Update --- .../club/bytecodeviewer/decompilers/AbstractDecompiler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java index 517fdd18..bf2cdc57 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/AbstractDecompiler.java @@ -40,6 +40,11 @@ public abstract class AbstractDecompiler public abstract void decompileToZip(String sourceJar, String zipName); + public void decompileToZipFallBack(String sourceJar, String zipName) + { + //TODO + } + public String getDecompilerName() { return decompilerName; From ceeae5843e170aa0d8c2e963ee2d6125976d3ea5 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:40:46 -0600 Subject: [PATCH 48/82] DEV_FLAG Warning --- src/main/java/the/bytecode/club/bytecodeviewer/Constants.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java index 2ebf09e6..ff449d73 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java @@ -87,6 +87,10 @@ public class Constants public static final String LIBS_DIRECTORY = getBCVDirectory() + FS + "libs" + FS; public static String krakatauWorkingDirectory = getBCVDirectory() + FS + "krakatau_" + krakatauVersion; public static String enjarifyWorkingDirectory = getBCVDirectory() + FS + "enjarify_" + enjarifyVersion; + + //DEV_FLAG_* are used for enabling tooling / systems reserved for development. + //As a precaution, all variables in here MUST ensure we are working in DEV_MODE only. + //Nothing here is meant for user level production, only development level production. public static final boolean DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS = DEV_MODE && true; //enable true / false to disable public static final PrintStream ERR = System.err; From 9391352953674c882e23806658b81ecbd1a50497 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:43:02 -0600 Subject: [PATCH 49/82] ASMifier Cleanup Better Failing. Decompile to zip fallback added. --- .../decompilers/impl/ASMifierGenerator.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java index b95842f9..85b51fa7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java @@ -21,12 +21,20 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.util.ASMifier; import org.objectweb.asm.util.TraceClassVisitor; +import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; +import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.JavaFormatterUtils; import java.io.PrintWriter; import java.io.StringWriter; +import static the.bytecode.club.bytecodeviewer.Constants.NL; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DEV_MODE_SIMULATED_ERROR; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; + /** * Objectweb ASMifier output * @@ -42,13 +50,32 @@ public class ASMifierGenerator extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - StringWriter writer = new StringWriter(); - cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer))); - return JavaFormatterUtils.formatJavaCode(writer.toString()); + String exception; + + try + { + StringWriter writer = new StringWriter(); + cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer))); + + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //format and return the java writer contents + return JavaFormatterUtils.formatJavaCode(writer.toString()); + } + catch (Throwable e) + { + exception = ExceptionUtils.exceptionToString(e); + } + + return "ASMifier " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override public void decompileToZip(String sourceJar, String zipName) { + decompileToZipFallBack(sourceJar, zipName); } } From f94c03d1782b56bebfcf34fbc8b7e74c69f2c52e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:50:49 -0600 Subject: [PATCH 50/82] ASM Disassembler Better Failing. Decompile to zip fallback added. --- .../decompilers/Decompiler.java | 2 +- ...Disassembler.java => ASMDisassembler.java} | 40 ++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) rename src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/{ASMTextifierDisassembler.java => ASMDisassembler.java} (56%) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java index bdb5f998..1a192771 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java @@ -44,7 +44,7 @@ public enum Decompiler JD_DECOMPILER(new JDGUIDecompiler()), //java decompiler JADX_DECOMPILER(new JADXDecompiler()), //java decompiler - ASM_TEXTIFY_DISASSEMBLER(new ASMTextifierDisassembler()), //bytecode disassembler + ASM_TEXTIFY_DISASSEMBLER(new ASMDisassembler()), //bytecode disassembler ASMIFIER_DECOMPILER(new ASMifierGenerator()), //bytecode disassembler / code gen JAVAP_DISASSEMBLER(new JavapDisassembler()); //bytecode disassembler diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMTextifierDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java similarity index 56% rename from src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMTextifierDisassembler.java rename to src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java index b77d45c3..e3992065 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMTextifierDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java @@ -21,19 +21,27 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.util.Textifier; import org.objectweb.asm.util.TraceClassVisitor; +import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; +import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import java.io.PrintWriter; import java.io.StringWriter; +import static the.bytecode.club.bytecodeviewer.Constants.NL; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DEV_MODE_SIMULATED_ERROR; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; + /** * Objectweb ASM Textifier output * * @author Thiakil */ -public class ASMTextifierDisassembler extends AbstractDecompiler +public class ASMDisassembler extends AbstractDecompiler { - public ASMTextifierDisassembler() + public ASMDisassembler() { super("ASM Disassembler", "asm"); } @@ -41,13 +49,35 @@ public class ASMTextifierDisassembler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - StringWriter writer = new StringWriter(); - cn.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(writer))); - return writer.toString(); + String exception; + + try + { + //create writer + StringWriter writer = new StringWriter(); + + //initialize ASM-Textifier & parse class-file + cn.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(writer))); + + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //return writer contents + return writer.toString(); + } + catch (Throwable e) + { + exception = ExceptionUtils.exceptionToString(e); + } + + return "ASM Disassembler " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override public void decompileToZip(String sourceJar, String zipName) { + decompileToZipFallBack(sourceJar, zipName); } } From dc6e1573b1ea9ca0a3aea79e36fdf4b2ec32323a Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:57:27 -0600 Subject: [PATCH 51/82] Decompiler Name Adjustments --- .../bytecodeviewer/cli/CommandLineInput.java | 2 +- .../decompilers/Decompiler.java | 4 +- .../DecompilerSelectionPane.java | 61 ++++++++++--------- .../classcontainer/ClassFileContainer.java | 4 +- src/main/resources/translations/arabic.json | 2 +- .../resources/translations/bulgarian.json | 2 +- src/main/resources/translations/croatian.json | 2 +- src/main/resources/translations/czech.json | 2 +- src/main/resources/translations/danish.json | 2 +- src/main/resources/translations/english.json | 2 +- src/main/resources/translations/estonian.json | 2 +- src/main/resources/translations/farsi.json | 2 +- src/main/resources/translations/finnish.json | 2 +- src/main/resources/translations/french.json | 2 +- src/main/resources/translations/georgian.json | 2 +- src/main/resources/translations/german.json | 2 +- src/main/resources/translations/greek.json | 2 +- src/main/resources/translations/hebrew.json | 2 +- .../resources/translations/hungarian.json | 2 +- src/main/resources/translations/italian.json | 2 +- src/main/resources/translations/japanese.json | 2 +- src/main/resources/translations/javanese.json | 2 +- src/main/resources/translations/lativan.json | 2 +- .../resources/translations/lithuanian.json | 2 +- src/main/resources/translations/malay.json | 2 +- .../resources/translations/nederlands.json | 2 +- .../resources/translations/norwegian.json | 2 +- .../resources/translations/portuguese.json | 2 +- src/main/resources/translations/romanian.json | 2 +- src/main/resources/translations/russian.json | 2 +- src/main/resources/translations/slovak.json | 2 +- .../resources/translations/slovenian.json | 2 +- src/main/resources/translations/spanish.json | 2 +- src/main/resources/translations/swedish.json | 2 +- src/main/resources/translations/thai.json | 2 +- .../resources/translations/ukrainian.json | 2 +- .../resources/translations/vietnamese.json | 2 +- 37 files changed, 70 insertions(+), 67 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java index 28fa6a87..de454b03 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java @@ -462,7 +462,7 @@ public class CommandLineInput { ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target); final ClassWriter cw = accept(cn); - String contents = Decompiler.ASMIFIER_DECOMPILER.getDecompiler().decompileClassNode(cn, cw.toByteArray()); + String contents = Decompiler.ASMIFIER_DISASSEMBLER.getDecompiler().decompileClassNode(cn, cw.toByteArray()); DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); } catch (Exception e) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java index 1a192771..ed04880c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java @@ -44,8 +44,8 @@ public enum Decompiler JD_DECOMPILER(new JDGUIDecompiler()), //java decompiler JADX_DECOMPILER(new JADXDecompiler()), //java decompiler - ASM_TEXTIFY_DISASSEMBLER(new ASMDisassembler()), //bytecode disassembler - ASMIFIER_DECOMPILER(new ASMifierGenerator()), //bytecode disassembler / code gen + ASM_DISASSEMBLER(new ASMDisassembler()), //bytecode disassembler + ASMIFIER_DISASSEMBLER(new ASMifierGenerator()), //bytecode disassembler / code gen JAVAP_DISASSEMBLER(new JavapDisassembler()); //bytecode disassembler private final AbstractDecompiler decompiler; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java index 70a8e253..037e9d8b 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java @@ -45,22 +45,25 @@ public class DecompilerSelectionPane private final JMenu menu; private final ButtonGroup group = new ButtonGroup(); private final JRadioButtonMenuItem none = new TranslatedJRadioButtonMenuItem("None", TranslatedComponents.NONE); - private final JRadioButtonMenuItem hexcode = new TranslatedJRadioButtonMenuItem("Hexcode", TranslatedComponents.HEXCODE); - private final DecompilerViewComponent procyon = new DecompilerViewComponent("Procyon", JAVA, Decompiler.PROCYON_DECOMPILER); - private final DecompilerViewComponent CFR = new DecompilerViewComponent("CFR", JAVA, Decompiler.CFR_DECOMPILER); - private final DecompilerViewComponent JADX = new DecompilerViewComponent("JADX", JAVA, Decompiler.JADX_DECOMPILER); - private final DecompilerViewComponent JD = new DecompilerViewComponent("JD-GUI", JAVA, Decompiler.JD_DECOMPILER); - private final DecompilerViewComponent fern = new DecompilerViewComponent("FernFlower", JAVA, Decompiler.FERNFLOWER_DECOMPILER); - private final DecompilerViewComponent krakatau = new DecompilerViewComponent("Krakatau", JAVA_AND_BYTECODE, Decompiler.KRAKATAU_DECOMPILER, Decompiler.KRAKATAU_DISASSEMBLER); - private final DecompilerViewComponent smali = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER); - private final DecompilerViewComponent bytecode = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); - private final DecompilerViewComponent asmTextify = new DecompilerViewComponent("ASM Textify", BYTECODE_NON_EDITABLE, Decompiler.ASM_TEXTIFY_DISASSEMBLER); - private final DecompilerViewComponent asmifier = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_DECOMPILER); - private final DecompilerViewComponent javap = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); + private final JRadioButtonMenuItem hexcodeViewer = new TranslatedJRadioButtonMenuItem("Hexcode", TranslatedComponents.HEXCODE); + //decompilers + private final DecompilerViewComponent procyonDecompiler = new DecompilerViewComponent("Procyon", JAVA, Decompiler.PROCYON_DECOMPILER); + private final DecompilerViewComponent CFRDecompiler = new DecompilerViewComponent("CFR", JAVA, Decompiler.CFR_DECOMPILER); + private final DecompilerViewComponent JADXDecompiler = new DecompilerViewComponent("JADX", JAVA, Decompiler.JADX_DECOMPILER); + private final DecompilerViewComponent JDCoreDecompiler = new DecompilerViewComponent("JD-GUI", JAVA, Decompiler.JD_DECOMPILER); + private final DecompilerViewComponent fernFlowerDecompiler = new DecompilerViewComponent("FernFlower", JAVA, Decompiler.FERNFLOWER_DECOMPILER); + //disassemblers + private final DecompilerViewComponent krakatauDecompiler = new DecompilerViewComponent("Krakatau", JAVA_AND_BYTECODE, Decompiler.KRAKATAU_DECOMPILER, Decompiler.KRAKATAU_DISASSEMBLER); + private final DecompilerViewComponent smaliDisassembler = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER); + private final DecompilerViewComponent bytecodeViewer = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); + private final DecompilerViewComponent asmifier = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_DISASSEMBLER); + private final DecompilerViewComponent javapDisassembler = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); + //code-gen + private final DecompilerViewComponent asmDisassembler = new DecompilerViewComponent("ASM Disassembler", BYTECODE_NON_EDITABLE, Decompiler.ASM_DISASSEMBLER); //TODO when adding new decompilers insert the DecompilerViewComponent object into here // also in the group, then finally the build menu - public List components = new ArrayList<>(Arrays.asList(procyon, CFR, JADX, JD, fern, krakatau, smali, bytecode, asmTextify, asmifier, javap)); + public List components = new ArrayList<>(Arrays.asList(procyonDecompiler, CFRDecompiler, JADXDecompiler, JDCoreDecompiler, fernFlowerDecompiler, krakatauDecompiler, smaliDisassembler, bytecodeViewer, asmDisassembler, asmifier, javapDisassembler)); public DecompilerSelectionPane(int paneID) { @@ -83,10 +86,10 @@ public class DecompilerSelectionPane switch (paneID) { case 1: - group.setSelected(fern.getJava().getModel(), true); + group.setSelected(fernFlowerDecompiler.getJava().getModel(), true); break; case 2: - group.setSelected(bytecode.getBytecode().getModel(), true); + group.setSelected(bytecodeViewer.getBytecode().getModel(), true); break; case 3: group.setSelected(none.getModel(), true); @@ -101,12 +104,12 @@ public class DecompilerSelectionPane { //build the radiobutton group group.add(none); - group.add(hexcode); + group.add(hexcodeViewer); components.forEach(decompilerViewComponent -> decompilerViewComponent.addToGroup(group)); //build the action commands none.setActionCommand(Decompiler.NONE.name()); - hexcode.setActionCommand(Decompiler.HEXCODE_VIEWER.name()); + hexcodeViewer.setActionCommand(Decompiler.HEXCODE_VIEWER.name()); for (DecompilerViewComponent component : components) { @@ -140,28 +143,28 @@ public class DecompilerSelectionPane //build the menu menu.add(none); menu.add(new JSeparator()); - menu.add(procyon.getMenu()); - menu.add(CFR.getMenu()); + menu.add(procyonDecompiler.getMenu()); + menu.add(CFRDecompiler.getMenu()); if (!Configuration.jadxGroupedWithSmali) - menu.add(JADX.getMenu()); + menu.add(JADXDecompiler.getMenu()); - menu.add(JD.getMenu()); - menu.add(fern.getMenu()); - menu.add(krakatau.getMenu()); + menu.add(JDCoreDecompiler.getMenu()); + menu.add(fernFlowerDecompiler.getMenu()); + menu.add(krakatauDecompiler.getMenu()); menu.add(new JSeparator()); if (Configuration.jadxGroupedWithSmali) - menu.add(JADX.getMenu()); + menu.add(JADXDecompiler.getMenu()); - menu.add(smali.getMenu()); + menu.add(smaliDisassembler.getMenu()); menu.add(new JSeparator()); - menu.add(bytecode.getMenu()); - menu.add(javap.getMenu()); - menu.add(asmTextify.getMenu()); + menu.add(bytecodeViewer.getMenu()); + menu.add(javapDisassembler.getMenu()); + menu.add(asmDisassembler.getMenu()); menu.add(asmifier.getMenu()); menu.add(new JSeparator()); - menu.add(hexcode); + menu.add(hexcodeViewer); } public Decompiler getSelectedDecompiler() diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java b/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java index a8be62a3..92b73472 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java @@ -82,8 +82,8 @@ public class ClassFileContainer && !getDecompiler().equals(Decompiler.KRAKATAU_DISASSEMBLER.getDecompilerName()) && !getDecompiler().equals(Decompiler.JAVAP_DISASSEMBLER.getDecompilerName()) && !getDecompiler().equals(Decompiler.SMALI_DISASSEMBLER.getDecompilerName()) - && !getDecompiler().equals(Decompiler.ASM_TEXTIFY_DISASSEMBLER.getDecompilerName()) - && !getDecompiler().equals(Decompiler.ASMIFIER_DECOMPILER.getDecompilerName()); + && !getDecompiler().equals(Decompiler.ASM_DISASSEMBLER.getDecompilerName()) + && !getDecompiler().equals(Decompiler.ASMIFIER_DISASSEMBLER.getDecompilerName()); } public String getName() diff --git a/src/main/resources/translations/arabic.json b/src/main/resources/translations/arabic.json index c9686eb6..70751b61 100644 --- a/src/main/resources/translations/arabic.json +++ b/src/main/resources/translations/arabic.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali / Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "مساعدي التصحيح", "APPEND_BRACKETS_TO_LABEL": "إلحاق أقواس بالتسمية", diff --git a/src/main/resources/translations/bulgarian.json b/src/main/resources/translations/bulgarian.json index ac8b6c7f..6ca34ef8 100644 --- a/src/main/resources/translations/bulgarian.json +++ b/src/main/resources/translations/bulgarian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Шестнайсетичен код", "BYTECODE": "Байткод", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Декомпилатор на байткод", "DEBUG_HELPERS": "Помощници за отстраняване на грешки", "APPEND_BRACKETS_TO_LABEL": "Прилагане на скоби към етикета", diff --git a/src/main/resources/translations/croatian.json b/src/main/resources/translations/croatian.json index 1ba2de08..890712fd 100644 --- a/src/main/resources/translations/croatian.json +++ b/src/main/resources/translations/croatian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali/Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Dekompilator bajtkoda", "DEBUG_HELPERS": "Pomoćnici za ispravljanje pogrešaka", "APPEND_BRACKETS_TO_LABEL": "Dodaj zagrade na oznaku", diff --git a/src/main/resources/translations/czech.json b/src/main/resources/translations/czech.json index 5a4b32e1..42fbb3a2 100644 --- a/src/main/resources/translations/czech.json +++ b/src/main/resources/translations/czech.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytový kód", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Dekompilátor bajtového kódu", "DEBUG_HELPERS": "Pomocníci pro ladění", "APPEND_BRACKETS_TO_LABEL": "Připojení závorek ke štítku", diff --git a/src/main/resources/translations/danish.json b/src/main/resources/translations/danish.json index 691bc419..460fd878 100644 --- a/src/main/resources/translations/danish.json +++ b/src/main/resources/translations/danish.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexkode", "BYTECODE": "Bytekode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode-dekompilering", "DEBUG_HELPERS": "Hjælpemidler til fejlfinding", "APPEND_BRACKETS_TO_LABEL": "Tilføj parenteser til etiketten", diff --git a/src/main/resources/translations/english.json b/src/main/resources/translations/english.json index cf2d8e47..2a5d99f7 100644 --- a/src/main/resources/translations/english.json +++ b/src/main/resources/translations/english.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali/Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "ASMIFIER": "ASMifier", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "Debug Helpers", diff --git a/src/main/resources/translations/estonian.json b/src/main/resources/translations/estonian.json index d24b858c..dcab05a8 100644 --- a/src/main/resources/translations/estonian.json +++ b/src/main/resources/translations/estonian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Baitkoodi dekompilaator", "DEBUG_HELPERS": "Kõrvaldamise abivahendid", "APPEND_BRACKETS_TO_LABEL": "Sulgude lisamine etiketile", diff --git a/src/main/resources/translations/farsi.json b/src/main/resources/translations/farsi.json index 85409bd9..35f68aba 100644 --- a/src/main/resources/translations/farsi.json +++ b/src/main/resources/translations/farsi.json @@ -90,7 +90,7 @@ "SMALI_DEX": "اسمالی / دکس", "HEXCODE": "کد هگز", "BYTECODE": "کد Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "رمزگشایی Bytecode", "DEBUG_HELPERS": "راهنمای اشکال زدایی", "APPEND_BRACKETS_TO_LABEL": "براکت ها را به برچسب اضافه کنید", diff --git a/src/main/resources/translations/finnish.json b/src/main/resources/translations/finnish.json index 6956f46b..b83b983a 100644 --- a/src/main/resources/translations/finnish.json +++ b/src/main/resources/translations/finnish.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Heksakoodi", "BYTECODE": "Bytekoodi", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytekoodin purkuohjelma", "DEBUG_HELPERS": "Vianmäärityksen apuohjelmat", "APPEND_BRACKETS_TO_LABEL": "Liitä hakasulkeet etikettiin", diff --git a/src/main/resources/translations/french.json b/src/main/resources/translations/french.json index d907e86d..ab3cf81d 100644 --- a/src/main/resources/translations/french.json +++ b/src/main/resources/translations/french.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Décompilateur de bytecode", "DEBUG_HELPERS": "Aides au débogage", "APPEND_BRACKETS_TO_LABEL": "Ajouter des parenthèses à l'étiquette", diff --git a/src/main/resources/translations/georgian.json b/src/main/resources/translations/georgian.json index 01d4f2fd..003e592e 100644 --- a/src/main/resources/translations/georgian.json +++ b/src/main/resources/translations/georgian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "სმალი / დექსი", "HEXCODE": "ჰექსკოდი", "BYTECODE": "ბიტეკოდი", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode დეკომპილერი", "DEBUG_HELPERS": "Debug Helpers", "APPEND_BRACKETS_TO_LABEL": "დაამატეთ ფრჩხილები ლეიბლზე", diff --git a/src/main/resources/translations/german.json b/src/main/resources/translations/german.json index 91ed58d4..bd78843b 100644 --- a/src/main/resources/translations/german.json +++ b/src/main/resources/translations/german.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali/Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "ASMIFIER": "ASMifier", "BYTECODE_DECOMPILER": "Bytecode-Dekompilierer", "DEBUG_HELPERS": "Debug-Helfer", diff --git a/src/main/resources/translations/greek.json b/src/main/resources/translations/greek.json index 6a3e0426..e51058d6 100644 --- a/src/main/resources/translations/greek.json +++ b/src/main/resources/translations/greek.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Αποσυμπιεστής bytecode", "DEBUG_HELPERS": "Βοηθοί εντοπισμού σφαλμάτων", "APPEND_BRACKETS_TO_LABEL": "Προσθέστε αγκύλες στην ετικέτα", diff --git a/src/main/resources/translations/hebrew.json b/src/main/resources/translations/hebrew.json index ff7123ab..189d594d 100644 --- a/src/main/resources/translations/hebrew.json +++ b/src/main/resources/translations/hebrew.json @@ -90,7 +90,7 @@ "SMALI_DEX": "סמאלי / דקס", "HEXCODE": "הקסקוד", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Decompiler Bytecode", "DEBUG_HELPERS": "עוזרי איתור באגים", "APPEND_BRACKETS_TO_LABEL": "הוסף סוגריים לתווית", diff --git a/src/main/resources/translations/hungarian.json b/src/main/resources/translations/hungarian.json index 0855d187..b1fb55f4 100644 --- a/src/main/resources/translations/hungarian.json +++ b/src/main/resources/translations/hungarian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexkód", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode dekompiláló", "DEBUG_HELPERS": "Hibakeresési segédprogramok", "APPEND_BRACKETS_TO_LABEL": "Zárójelek hozzáadása a címkéhez", diff --git a/src/main/resources/translations/italian.json b/src/main/resources/translations/italian.json index 2fb7344a..7efbbfc1 100644 --- a/src/main/resources/translations/italian.json +++ b/src/main/resources/translations/italian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Decompilatore di bytecode", "DEBUG_HELPERS": "Aiuti per il debug", "APPEND_BRACKETS_TO_LABEL": "Aggiungere parentesi all'etichetta", diff --git a/src/main/resources/translations/japanese.json b/src/main/resources/translations/japanese.json index bfcccea3..13db8d8e 100644 --- a/src/main/resources/translations/japanese.json +++ b/src/main/resources/translations/japanese.json @@ -90,7 +90,7 @@ "SMALI_DEX": "スマリ", "HEXCODE": "ヘックスコード", "BYTECODE": "バイトコード", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "バイトコードデコンパイラー", "DEBUG_HELPERS": "デバッグヘルパー", "APPEND_BRACKETS_TO_LABEL": "ラベルに括弧をつける", diff --git a/src/main/resources/translations/javanese.json b/src/main/resources/translations/javanese.json index b19446df..c14989fd 100644 --- a/src/main/resources/translations/javanese.json +++ b/src/main/resources/translations/javanese.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali / Dex", "HEXCODE": "Hekscode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "Penolong Debug", "APPEND_BRACKETS_TO_LABEL": "Nambah Kurung Kanggo Label", diff --git a/src/main/resources/translations/lativan.json b/src/main/resources/translations/lativan.json index 0dfd0ae6..0d5bebda 100644 --- a/src/main/resources/translations/lativan.json +++ b/src/main/resources/translations/lativan.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode dekompilētājs", "DEBUG_HELPERS": "Dzesēšanas palīgierīces", "APPEND_BRACKETS_TO_LABEL": "Etiķetes pievienošana iekavās", diff --git a/src/main/resources/translations/lithuanian.json b/src/main/resources/translations/lithuanian.json index 9931c581..07b4d85c 100644 --- a/src/main/resources/translations/lithuanian.json +++ b/src/main/resources/translations/lithuanian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Šešiaženklis kodas", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytekodo dekompiliatorius", "DEBUG_HELPERS": "Derinimo pagalbininkai", "APPEND_BRACKETS_TO_LABEL": "Prie etiketės pridėkite skliaustelius", diff --git a/src/main/resources/translations/malay.json b/src/main/resources/translations/malay.json index 607d1d2b..d95a9881 100644 --- a/src/main/resources/translations/malay.json +++ b/src/main/resources/translations/malay.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali / Dex", "HEXCODE": "Kod Hex", "BYTECODE": "Kod byk", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Pengurai Bytecode", "DEBUG_HELPERS": "Pembantu Debug", "APPEND_BRACKETS_TO_LABEL": "Lampirkan Kurungan ke Label", diff --git a/src/main/resources/translations/nederlands.json b/src/main/resources/translations/nederlands.json index 934bd03c..c91472dc 100644 --- a/src/main/resources/translations/nederlands.json +++ b/src/main/resources/translations/nederlands.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode decompiler", "DEBUG_HELPERS": "Debug helpers", "APPEND_BRACKETS_TO_LABEL": "Haakjes toevoegen aan label", diff --git a/src/main/resources/translations/norwegian.json b/src/main/resources/translations/norwegian.json index 60b678aa..367ade1f 100644 --- a/src/main/resources/translations/norwegian.json +++ b/src/main/resources/translations/norwegian.json @@ -95,7 +95,7 @@ "SMALI_DEX": "Smali / Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "Feilsøkingshjelpere", diff --git a/src/main/resources/translations/portuguese.json b/src/main/resources/translations/portuguese.json index 06df9fc9..5ff66ecd 100644 --- a/src/main/resources/translations/portuguese.json +++ b/src/main/resources/translations/portuguese.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Código Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textificar", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Descompilador de Bytecode", "DEBUG_HELPERS": "Ajudantes de Depuração", "APPEND_BRACKETS_TO_LABEL": "Anexar parênteses ao rótulo", diff --git a/src/main/resources/translations/romanian.json b/src/main/resources/translations/romanian.json index f4fd12c2..0d6b4086 100644 --- a/src/main/resources/translations/romanian.json +++ b/src/main/resources/translations/romanian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Codul hexagonal", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Descompilator de Bytecode", "DEBUG_HELPERS": "Ajutoare de depanare", "APPEND_BRACKETS_TO_LABEL": "Adăugați paranteze la etichetă", diff --git a/src/main/resources/translations/russian.json b/src/main/resources/translations/russian.json index 64cd4489..a99d32bf 100644 --- a/src/main/resources/translations/russian.json +++ b/src/main/resources/translations/russian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali/Dex", "HEXCODE": "Шестнадцатеричный код", "BYTECODE": "Байт-код", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Декомпилятор байт-кода", "DEBUG_HELPERS": "Помощники отладки", "APPEND_BRACKETS_TO_LABEL": "Добавить скобки к названию", diff --git a/src/main/resources/translations/slovak.json b/src/main/resources/translations/slovak.json index 6b1b88ac..bf2bfe0f 100644 --- a/src/main/resources/translations/slovak.json +++ b/src/main/resources/translations/slovak.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Šesťmiestny kód", "BYTECODE": "Bytový kód", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Dekompilátor bytového kódu", "DEBUG_HELPERS": "Pomocníci ladenia", "APPEND_BRACKETS_TO_LABEL": "Pripojenie zátvoriek k štítku", diff --git a/src/main/resources/translations/slovenian.json b/src/main/resources/translations/slovenian.json index 2cb6a638..b6eef12b 100644 --- a/src/main/resources/translations/slovenian.json +++ b/src/main/resources/translations/slovenian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Šestmestna koda", "BYTECODE": "Bajtokoda", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Dekompiliator bajtkode", "DEBUG_HELPERS": "Pomočniki za odpravljanje napak", "APPEND_BRACKETS_TO_LABEL": "Dodajanje oklepajev k oznaki", diff --git a/src/main/resources/translations/spanish.json b/src/main/resources/translations/spanish.json index 93a21235..63b38565 100644 --- a/src/main/resources/translations/spanish.json +++ b/src/main/resources/translations/spanish.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Código hexadecimal", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Descompilador de Bytecode", "DEBUG_HELPERS": "Ayudantes de depuración", "APPEND_BRACKETS_TO_LABEL": "Añadir paréntesis a la etiqueta", diff --git a/src/main/resources/translations/swedish.json b/src/main/resources/translations/swedish.json index 836b7563..71071141 100644 --- a/src/main/resources/translations/swedish.json +++ b/src/main/resources/translations/swedish.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali", "HEXCODE": "Hexkod", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode-dekompilering", "DEBUG_HELPERS": "Hjälpmedel för felsökning", "APPEND_BRACKETS_TO_LABEL": "Lägga till parenteser till etiketten", diff --git a/src/main/resources/translations/thai.json b/src/main/resources/translations/thai.json index 1ca6fb50..80647069 100644 --- a/src/main/resources/translations/thai.json +++ b/src/main/resources/translations/thai.json @@ -90,7 +90,7 @@ "SMALI_DEX": "สมาลี/เด็กซ์", "HEXCODE": "รหัสเลขฐานสิบหก", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "ตัวช่วยดีบัก", "APPEND_BRACKETS_TO_LABEL": "ต่อท้ายวงเล็บเพื่อติดป้ายกำกับ", diff --git a/src/main/resources/translations/ukrainian.json b/src/main/resources/translations/ukrainian.json index 87fca9a4..0f07e944 100644 --- a/src/main/resources/translations/ukrainian.json +++ b/src/main/resources/translations/ukrainian.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Смалі / Декс", "HEXCODE": "Hexcode", "BYTECODE": "Байт-код", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Декомпілятор байт-коду", "DEBUG_HELPERS": "Помічники з налагодження", "APPEND_BRACKETS_TO_LABEL": "Додайте дужки до ярлика", diff --git a/src/main/resources/translations/vietnamese.json b/src/main/resources/translations/vietnamese.json index f5128ebf..aac35273 100644 --- a/src/main/resources/translations/vietnamese.json +++ b/src/main/resources/translations/vietnamese.json @@ -90,7 +90,7 @@ "SMALI_DEX": "Smali / Dex", "HEXCODE": "Hexcode", "BYTECODE": "Bytecode", - "ASM_TEXTIFY": "ASM Textify", + "ASM_TEXTIFY": "ASM Disassembler", "BYTECODE_DECOMPILER": "Bytecode Decompiler", "DEBUG_HELPERS": "Trình trợ giúp gỡ lỗi", "APPEND_BRACKETS_TO_LABEL": "Nối dấu ngoặc vào nhãn", From 7f5360c28d67eb8980beb2c125d4b136c39abc47 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 16:57:39 -0600 Subject: [PATCH 52/82] Comments --- .../bytecodeviewer/decompilers/impl/ASMifierGenerator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java index 85b51fa7..c30598a0 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java @@ -54,7 +54,10 @@ public class ASMifierGenerator extends AbstractDecompiler try { + //create writer StringWriter writer = new StringWriter(); + + //initialize ASMifier & parse class-file cn.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(writer))); //handle simulated errors From 0db6dcbd2765b0842bb6fef497359b57b054a343 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 17:01:37 -0600 Subject: [PATCH 53/82] Decompiler Name Adjustments --- .../club/bytecodeviewer/cli/CommandLineInput.java | 2 +- .../bytecodeviewer/decompilers/Decompiler.java | 2 +- .../resourceviewer/DecompilerSelectionPane.java | 14 +++++++------- .../classcontainer/ClassFileContainer.java | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java index de454b03..6aa20a79 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/CommandLineInput.java @@ -462,7 +462,7 @@ public class CommandLineInput { ClassNode cn = BytecodeViewer.blindlySearchForClassNode(target); final ClassWriter cw = accept(cn); - String contents = Decompiler.ASMIFIER_DISASSEMBLER.getDecompiler().decompileClassNode(cn, cw.toByteArray()); + String contents = Decompiler.ASMIFIER_CODE_GEN.getDecompiler().decompileClassNode(cn, cw.toByteArray()); DiskWriter.replaceFile(output.getAbsolutePath(), contents, false); } catch (Exception e) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java index ed04880c..094e0255 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/Decompiler.java @@ -45,7 +45,7 @@ public enum Decompiler JADX_DECOMPILER(new JADXDecompiler()), //java decompiler ASM_DISASSEMBLER(new ASMDisassembler()), //bytecode disassembler - ASMIFIER_DISASSEMBLER(new ASMifierGenerator()), //bytecode disassembler / code gen + ASMIFIER_CODE_GEN(new ASMifierGenerator()), //bytecode disassembler / code gen JAVAP_DISASSEMBLER(new JavapDisassembler()); //bytecode disassembler private final AbstractDecompiler decompiler; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java index 037e9d8b..c331ffdc 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java @@ -47,23 +47,23 @@ public class DecompilerSelectionPane private final JRadioButtonMenuItem none = new TranslatedJRadioButtonMenuItem("None", TranslatedComponents.NONE); private final JRadioButtonMenuItem hexcodeViewer = new TranslatedJRadioButtonMenuItem("Hexcode", TranslatedComponents.HEXCODE); //decompilers + private final DecompilerViewComponent fernFlowerDecompiler = new DecompilerViewComponent("FernFlower", JAVA, Decompiler.FERNFLOWER_DECOMPILER); private final DecompilerViewComponent procyonDecompiler = new DecompilerViewComponent("Procyon", JAVA, Decompiler.PROCYON_DECOMPILER); private final DecompilerViewComponent CFRDecompiler = new DecompilerViewComponent("CFR", JAVA, Decompiler.CFR_DECOMPILER); private final DecompilerViewComponent JADXDecompiler = new DecompilerViewComponent("JADX", JAVA, Decompiler.JADX_DECOMPILER); private final DecompilerViewComponent JDCoreDecompiler = new DecompilerViewComponent("JD-GUI", JAVA, Decompiler.JD_DECOMPILER); - private final DecompilerViewComponent fernFlowerDecompiler = new DecompilerViewComponent("FernFlower", JAVA, Decompiler.FERNFLOWER_DECOMPILER); //disassemblers + private final DecompilerViewComponent bytecodeViewer = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); + private final DecompilerViewComponent javapDisassembler = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); + private final DecompilerViewComponent asmDisassembler = new DecompilerViewComponent("ASM Disassembler", BYTECODE_NON_EDITABLE, Decompiler.ASM_DISASSEMBLER); private final DecompilerViewComponent krakatauDecompiler = new DecompilerViewComponent("Krakatau", JAVA_AND_BYTECODE, Decompiler.KRAKATAU_DECOMPILER, Decompiler.KRAKATAU_DISASSEMBLER); private final DecompilerViewComponent smaliDisassembler = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER); - private final DecompilerViewComponent bytecodeViewer = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); - private final DecompilerViewComponent asmifier = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_DISASSEMBLER); - private final DecompilerViewComponent javapDisassembler = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); //code-gen - private final DecompilerViewComponent asmDisassembler = new DecompilerViewComponent("ASM Disassembler", BYTECODE_NON_EDITABLE, Decompiler.ASM_DISASSEMBLER); + private final DecompilerViewComponent asmifierCodeGen = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_CODE_GEN); //TODO when adding new decompilers insert the DecompilerViewComponent object into here // also in the group, then finally the build menu - public List components = new ArrayList<>(Arrays.asList(procyonDecompiler, CFRDecompiler, JADXDecompiler, JDCoreDecompiler, fernFlowerDecompiler, krakatauDecompiler, smaliDisassembler, bytecodeViewer, asmDisassembler, asmifier, javapDisassembler)); + public List components = new ArrayList<>(Arrays.asList(procyonDecompiler, CFRDecompiler, JADXDecompiler, JDCoreDecompiler, fernFlowerDecompiler, krakatauDecompiler, smaliDisassembler, bytecodeViewer, asmDisassembler, asmifierCodeGen, javapDisassembler)); public DecompilerSelectionPane(int paneID) { @@ -162,7 +162,7 @@ public class DecompilerSelectionPane menu.add(bytecodeViewer.getMenu()); menu.add(javapDisassembler.getMenu()); menu.add(asmDisassembler.getMenu()); - menu.add(asmifier.getMenu()); + menu.add(asmifierCodeGen.getMenu()); menu.add(new JSeparator()); menu.add(hexcodeViewer); } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java b/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java index 92b73472..56a5e380 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/resources/classcontainer/ClassFileContainer.java @@ -83,7 +83,7 @@ public class ClassFileContainer && !getDecompiler().equals(Decompiler.JAVAP_DISASSEMBLER.getDecompilerName()) && !getDecompiler().equals(Decompiler.SMALI_DISASSEMBLER.getDecompilerName()) && !getDecompiler().equals(Decompiler.ASM_DISASSEMBLER.getDecompilerName()) - && !getDecompiler().equals(Decompiler.ASMIFIER_DISASSEMBLER.getDecompilerName()); + && !getDecompiler().equals(Decompiler.ASMIFIER_CODE_GEN.getDecompilerName()); } public String getName() From 995c0ffedef9fff4082607e53ad036eef36a0c54 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 17:41:14 -0600 Subject: [PATCH 54/82] Better Decompiler API Usage --- .../club/bytecodeviewer/decompilers/impl/ASMDisassembler.java | 2 +- .../club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java index e3992065..ad7af15c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMDisassembler.java @@ -71,7 +71,7 @@ public class ASMDisassembler extends AbstractDecompiler exception = ExceptionUtils.exceptionToString(e); } - return "ASM Disassembler " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + return getDecompilerName() + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java index c30598a0..4c62263a 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ASMifierGenerator.java @@ -72,7 +72,7 @@ public class ASMifierGenerator extends AbstractDecompiler exception = ExceptionUtils.exceptionToString(e); } - return "ASMifier " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + return getDecompilerName() + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } From aff69c295e547e05712afb4a24c05c7739fd931f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 17:42:38 -0600 Subject: [PATCH 55/82] Merged The Two ASMifier Disassemblers --- .../components/DecompilerViewComponent.java | 19 ++++++++++--------- .../DecompilerSelectionPane.java | 15 ++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/DecompilerViewComponent.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/DecompilerViewComponent.java index f08289c0..75da03ec 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/DecompilerViewComponent.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/components/DecompilerViewComponent.java @@ -57,13 +57,16 @@ public class DecompilerViewComponent private void createMenu() { - if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE) + if (type == JAVA || type == JAVA_NON_EDITABLE + || type == JAVA_AND_BYTECODE || type == JAVA_AND_BYTECODE_NON_EDITABLE) menu.add(java); - if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) + if (type == BYTECODE || type == BYTECODE_NON_EDITABLE + || type == JAVA_AND_BYTECODE || type == JAVA_AND_BYTECODE_NON_EDITABLE) menu.add(bytecode); - if (type != JAVA_NON_EDITABLE && type != BYTECODE_NON_EDITABLE) + if (type != JAVA_NON_EDITABLE && type != BYTECODE_NON_EDITABLE + && type != JAVA_AND_BYTECODE_NON_EDITABLE) { menu.add(new JSeparator()); menu.add(editable); @@ -74,11 +77,8 @@ public class DecompilerViewComponent public void addToGroup(ButtonGroup group) { - if (type == JAVA || type == JAVA_NON_EDITABLE || type == JAVA_AND_BYTECODE) - group.add(java); - - if (type == BYTECODE || type == JAVA_AND_BYTECODE || type == BYTECODE_NON_EDITABLE) - group.add(bytecode); + group.add(java); + group.add(bytecode); } public JMenu getMenu() @@ -117,6 +117,7 @@ public class DecompilerViewComponent JAVA_NON_EDITABLE, BYTECODE, BYTECODE_NON_EDITABLE, - JAVA_AND_BYTECODE; + JAVA_AND_BYTECODE, + JAVA_AND_BYTECODE_NON_EDITABLE; } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java index c331ffdc..0a032f10 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/gui/resourceviewer/DecompilerSelectionPane.java @@ -55,15 +55,16 @@ public class DecompilerSelectionPane //disassemblers private final DecompilerViewComponent bytecodeViewer = new DecompilerViewComponent("Bytecode", BYTECODE_NON_EDITABLE, Decompiler.BYTECODE_DISASSEMBLER); private final DecompilerViewComponent javapDisassembler = new DecompilerViewComponent("Javap", BYTECODE_NON_EDITABLE, Decompiler.JAVAP_DISASSEMBLER); - private final DecompilerViewComponent asmDisassembler = new DecompilerViewComponent("ASM Disassembler", BYTECODE_NON_EDITABLE, Decompiler.ASM_DISASSEMBLER); private final DecompilerViewComponent krakatauDecompiler = new DecompilerViewComponent("Krakatau", JAVA_AND_BYTECODE, Decompiler.KRAKATAU_DECOMPILER, Decompiler.KRAKATAU_DISASSEMBLER); private final DecompilerViewComponent smaliDisassembler = new DecompilerViewComponent("Smali", BYTECODE, Decompiler.SMALI_DISASSEMBLER); - //code-gen - private final DecompilerViewComponent asmifierCodeGen = new DecompilerViewComponent("ASMifier", JAVA_NON_EDITABLE, Decompiler.ASMIFIER_CODE_GEN); + //code-gen / etc + private final DecompilerViewComponent asmifierCodeGen = new DecompilerViewComponent("ASMifier", JAVA_AND_BYTECODE_NON_EDITABLE, Decompiler.ASMIFIER_CODE_GEN, Decompiler.ASM_DISASSEMBLER); //TODO when adding new decompilers insert the DecompilerViewComponent object into here // also in the group, then finally the build menu - public List components = new ArrayList<>(Arrays.asList(procyonDecompiler, CFRDecompiler, JADXDecompiler, JDCoreDecompiler, fernFlowerDecompiler, krakatauDecompiler, smaliDisassembler, bytecodeViewer, asmDisassembler, asmifierCodeGen, javapDisassembler)); + public List components = new ArrayList<>(Arrays.asList( + procyonDecompiler, CFRDecompiler, JADXDecompiler, JDCoreDecompiler, fernFlowerDecompiler, + krakatauDecompiler, smaliDisassembler, bytecodeViewer, asmifierCodeGen, javapDisassembler)); public DecompilerSelectionPane(int paneID) { @@ -118,9 +119,9 @@ public class DecompilerSelectionPane String cmd = decompiler.name(); //TODO this is pretty janky and will break if a decompiler doesn't end with _DECOMPILER suffix - if (cmd.endsWith("DECOMPILER")) + if (cmd.endsWith("_DECOMPILER") || cmd.endsWith("_CODE_GEN")) component.getJava().setActionCommand(cmd); - else// if(cmd.endsWith("DISASSEMBLER")) + else// if(cmd.endsWith("_DISASSEMBLER")) component.getBytecode().setActionCommand(cmd); } } @@ -161,7 +162,6 @@ public class DecompilerSelectionPane menu.add(new JSeparator()); menu.add(bytecodeViewer.getMenu()); menu.add(javapDisassembler.getMenu()); - menu.add(asmDisassembler.getMenu()); menu.add(asmifierCodeGen.getMenu()); menu.add(new JSeparator()); menu.add(hexcodeViewer); @@ -179,6 +179,7 @@ public class DecompilerSelectionPane while (it.hasMoreElements()) { AbstractButton button = it.nextElement(); + if (button.getActionCommand().equals(decompiler.name())) { group.setSelected(button.getModel(), true); From 45bf02e81e1bafaed5e0e374ae9895ded71a683f Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 17:51:16 -0600 Subject: [PATCH 56/82] Bytecode Disassembler Updates Better Failing. Decompile to zip fallback added. --- .../impl/BytecodeDisassembler.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BytecodeDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BytecodeDisassembler.java index 42d63980..6ac54e85 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BytecodeDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BytecodeDisassembler.java @@ -19,12 +19,20 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl; import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.bytecode.ClassNodeDecompiler; import the.bytecode.club.bytecodeviewer.decompilers.bytecode.PrefixedStringBuilder; +import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import java.util.ArrayList; +import static the.bytecode.club.bytecodeviewer.Constants.NL; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DEV_MODE_SIMULATED_ERROR; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; + /** * @author Konloch * @since 7/3/2021 @@ -39,11 +47,29 @@ public class BytecodeDisassembler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(), new ArrayList<>(), cn).toString(); + String exception; + + try + { + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //parse class-file + return ClassNodeDecompiler.decompile(new PrefixedStringBuilder(), new ArrayList<>(), cn).toString(); + } + catch (Throwable e) + { + exception = ExceptionUtils.exceptionToString(e); + } + + return getDecompilerName() + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override public void decompileToZip(String sourceJar, String zipName) { + decompileToZipFallBack(sourceJar, zipName); } } From 1d5d0bc0fa87d29b41f835a72a997b7a0667b0ed Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 17:52:30 -0600 Subject: [PATCH 57/82] CFR Decompiler Updates Error Log Update / Syntax --- .../decompilers/impl/CFRDecompiler.java | 89 +++++++++++-------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/CFRDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/CFRDecompiler.java index abcfc6d7..e56f90e2 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/CFRDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/CFRDecompiler.java @@ -29,10 +29,12 @@ import org.benf.cfr.reader.util.getopt.Options; import org.benf.cfr.reader.util.getopt.OptionsImpl; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Constants; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.resources.ResourceContainer; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import java.io.*; import java.nio.charset.StandardCharsets; @@ -44,15 +46,14 @@ import java.util.zip.ZipException; import java.util.zip.ZipOutputStream; 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.ERROR; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * CFR Java Wrapper * - * @author GraxCode - * Taken mostly out of Threadtear. + * @author GraxCode (Taken mostly out of Threadtear) */ + public class CFRDecompiler extends AbstractDecompiler { @@ -71,59 +72,69 @@ public class CFRDecompiler extends AbstractDecompiler private String decompile(ClassNode cn, String name, byte[] content) { + String exception; + try { String classPath = name + (name.endsWith(CLASS_SUFFIX) ? "" : CLASS_SUFFIX); - StringBuilder builder = new StringBuilder(); Consumer dumpDecompiled = d -> builder.append(d.getJava()); + //initialize CFR Options options = generateOptions(); ClassFileSource source = new BCVDataSource(options, cn, classPath, content); CfrDriver driver = new CfrDriver.Builder().withClassFileSource(source).withBuiltOptions(options).withOutputSink(new BCVOutputSinkFactory(dumpDecompiled)).build(); + + //decompile the class-file 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(); } - catch (Throwable t) + catch (Throwable e) { - t.printStackTrace(); - 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; + exception = ExceptionUtils.exceptionToString(e); } + + return CFR + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override public void decompileToZip(String sourceJar, String outJar) { - try (JarFile jfile = new JarFile(new File(sourceJar)); - FileOutputStream dest = new FileOutputStream(outJar); - BufferedOutputStream buffDest = new BufferedOutputStream(dest); - ZipOutputStream out = new ZipOutputStream(buffDest)) + try (JarFile jarFile = new JarFile(new File(sourceJar)); + FileOutputStream destination = new FileOutputStream(outJar); + BufferedOutputStream buffer = new BufferedOutputStream(destination); + ZipOutputStream zip = new ZipOutputStream(buffer)) { byte[] data = new byte[1024]; - - Enumeration ent = jfile.entries(); + Enumeration ent = jarFile.entries(); Set history = new HashSet<>(); + while (ent.hasMoreElements()) { JarEntry entry = ent.nextElement(); + if (entry.getName().endsWith(CLASS_SUFFIX)) { JarEntry etn = new JarEntry(entry.getName().replace(CLASS_SUFFIX, ".java")); if (history.add(etn)) { - out.putNextEntry(etn); + zip.putNextEntry(etn); + 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 { - out.closeEntry(); + zip.closeEntry(); } } } @@ -131,34 +142,36 @@ public class CFRDecompiler extends AbstractDecompiler { try { - JarEntry etn = new JarEntry(entry.getName()); - if (history.add(etn)) + JarEntry jarEntry = new JarEntry(entry.getName()); + + if (history.add(jarEntry)) continue; - history.add(etn); - out.putNextEntry(etn); - try (InputStream in = jfile.getInputStream(entry)) + + history.add(jarEntry); + zip.putNextEntry(jarEntry); + + try (InputStream input = jarFile.getInputStream(entry)) { - if (in != null) + if (input != null) { 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 { - out.closeEntry(); + zip.closeEntry(); } } - catch (ZipException ze) + catch (ZipException e) { // some jars contain duplicate pom.xml entries: ignore it - if (!ze.getMessage().contains("duplicate")) - { - throw ze; - } + if (!e.getMessage().contains("duplicate")) + throw e; } } } @@ -226,7 +239,8 @@ public class CFRDecompiler extends AbstractDecompiler private BCVDataSource(Options options, ClassNode cn, String classFilePath, byte[] content) { 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.content = content; } @@ -247,7 +261,6 @@ public class CFRDecompiler extends AbstractDecompiler return Pair.make(data, classFilePath); } - } private static class BCVOutputSinkFactory implements OutputSinkFactory @@ -274,9 +287,7 @@ public class CFRDecompiler extends AbstractDecompiler return x -> dumpDecompiled.accept((SinkReturns.Decompiled) x); } - return ignore -> - { - }; + return ignore -> {}; } } From f89ba2e6ea83d11de236934e7de068e3b2adb18d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:13:37 -0600 Subject: [PATCH 58/82] Started POC for External Decompiler Processes --- .../club/bytecodeviewer/util/ProcessUtils.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java index 1ac11ba1..c02154b7 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/ProcessUtils.java @@ -125,4 +125,22 @@ public class ProcessUtils }); } } + + public static void runDecompilerExternal(String[] args, boolean exceptionToGUI) throws IOException, InterruptedException + { + try + { + ProcessBuilder pb = new ProcessBuilder(args); + Process p = pb.start(); + BytecodeViewer.createdProcesses.add(p); + p.waitFor(); + } + catch (Exception e) + { + if(exceptionToGUI) + BytecodeViewer.handleException(e); + else + throw e; + } + } } From 39491c3c4a88b238877d1248da43de762f5cb1a9 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:19:21 -0600 Subject: [PATCH 59/82] FernFlower Decompiler Update External Process Launch Proof of Concept. Decompile to zip fallback added. --- .../impl/FernFlowerDecompiler.java | 80 ++++++++----------- 1 file changed, 35 insertions(+), 45 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 0e892720..96254a45 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -19,19 +19,23 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl; import me.konloch.kontainer.io.DiskReader; +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Constants; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; +import the.bytecode.club.bytecodeviewer.resources.ExternalResources; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; +import the.bytecode.club.bytecodeviewer.util.ProcessUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; import static the.bytecode.club.bytecodeviewer.Constants.*; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.FERNFLOWER; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * A FernFlower wrapper with all the options (except 2) @@ -47,29 +51,6 @@ public class FernFlowerDecompiler extends AbstractDecompiler super("FernFlower Decompiler", "fernflower"); } - @Override - public void decompileToZip(String sourceJar, String zipName) - { - File tempZip = new File(sourceJar); - - File f = new File(TEMP_DIRECTORY + FS + "temp" + FS); - f.mkdir(); - - try - { - org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempZip.getAbsolutePath(), TEMP_DIRECTORY + "./temp/")); - } - catch (StackOverflowError | Exception ignored) - { - } - - File tempZip2 = new File(TEMP_DIRECTORY + FS + "temp" + FS + tempZip.getName()); - if (tempZip2.exists()) - tempZip2.renameTo(new File(zipName)); - - f.delete(); - } - @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { @@ -80,14 +61,14 @@ public class FernFlowerDecompiler extends AbstractDecompiler { //create the temporary files tempFile = TempFile.createTemporaryFile(true, ".class"); - File tempClassFile = tempFile.getFile(); + File tempInputClassFile = tempFile.getFile(); //load java source from temp directory tempFile.setParent(new File(TEMP_DIRECTORY)); File tempOutputJavaFile = tempFile.createFileFromExtension(false, true, ".java"); //write the class-file with bytes - try (FileOutputStream fos = new FileOutputStream(tempClassFile)) + try (FileOutputStream fos = new FileOutputStream(tempInputClassFile)) { fos.write(bytes); } @@ -95,26 +76,16 @@ public class FernFlowerDecompiler extends AbstractDecompiler //decompile the class-file if (LAUNCH_DECOMPILERS_IN_NEW_PROCESS) { - /*try - { - BytecodeViewer.sm.pauseBlocking(); - ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll( - new String[]{ExternalResources.getSingleton().getJavaCommand(true), "-jar", ExternalResources.getSingleton().findLibrary("fernflower")}, - generateMainMethod(tempClass.getAbsolutePath(), - new File(tempDirectory).getAbsolutePath()) - )); - Process p = pb.start(); - BytecodeViewer.createdProcesses.add(p); - p.waitFor(); - } catch (Exception e) { - BytecodeViewer.handleException(e); - } finally { - BytecodeViewer.sm.resumeBlocking(); - }*/ + ProcessUtils.runDecompilerExternal(ArrayUtils.addAll(new String[] + { + ExternalResources.getSingleton().getJavaCommand(true), + "-jar", ExternalResources.getSingleton().findLibrary("fernflower") + }, generateMainMethod(tempInputClassFile.getAbsolutePath(), tempFile.getParent().getAbsolutePath()) + ), false); } else { - org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempClassFile.getAbsolutePath(), new File(TEMP_DIRECTORY).getAbsolutePath())); + org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler.main(generateMainMethod(tempInputClassFile.getAbsolutePath(), new File(TEMP_DIRECTORY).getAbsolutePath())); } //if rename is enabled the file name will be the actual class name @@ -127,7 +98,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler } //if the output file is found, read it - if (tempOutputJavaFile.exists()) + if (tempOutputJavaFile.exists() && !Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) return DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); else exception = FERNFLOWER + " " + ERROR + "! " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; @@ -147,6 +118,25 @@ public class FernFlowerDecompiler extends AbstractDecompiler + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } + @Override + public void decompileToZip(String sourceJar, String zipName) + { + File tempInputJarFile = new File(sourceJar); + File tempOutputJar = new File(TEMP_DIRECTORY + FS + "temp" + FS + tempInputJarFile.getName()); + + try + { + ConsoleDecompiler.main(generateMainMethod(tempInputJarFile.getAbsolutePath(), TEMP_DIRECTORY + "./temp/")); + } + catch (StackOverflowError | Exception ignored) + { + } + + if (tempOutputJar.exists()) + tempOutputJar.renameTo(new File(zipName)); + + } + private String[] generateMainMethod(String className, String folder) { return new String[] From a9dc390a1763595b7f97f3f98caa0e38fe23a348 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:21:31 -0600 Subject: [PATCH 60/82] FernFlower Zip Decompiler Fallback --- .../decompilers/impl/FernFlowerDecompiler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index 96254a45..d72a1d90 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -121,6 +121,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler @Override public void decompileToZip(String sourceJar, String zipName) { + final File destination = new File(zipName); File tempInputJarFile = new File(sourceJar); File tempOutputJar = new File(TEMP_DIRECTORY + FS + "temp" + FS + tempInputJarFile.getName()); @@ -133,7 +134,9 @@ public class FernFlowerDecompiler extends AbstractDecompiler } if (tempOutputJar.exists()) - tempOutputJar.renameTo(new File(zipName)); + tempOutputJar.renameTo(destination); + else //attempt to decompile using fallback + decompileToZipFallBack(tempInputJarFile.getAbsolutePath(), destination.getAbsolutePath()); } From ed59212c6f668862e56697606b5a5ae850eb3104 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:40:38 -0600 Subject: [PATCH 61/82] Added Decompiles Cleanup Flag --- .../java/the/bytecode/club/bytecodeviewer/Constants.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java index ff449d73..46f71ce1 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java @@ -47,7 +47,8 @@ public class Constants // + You can control the java arguments (more memory & stack) //the cons to this are: // + If you could keep it in memory, now you need to write to disk (windows limitations) - public static final boolean LAUNCH_DECOMPILERS_IN_NEW_PROCESS = false; //TODO + public static final boolean LAUNCH_DECOMPILERS_IN_NEW_PROCESS = false; //TODO - work in progress + // FernFlower is added //could be automatic by checking if it's loaded a class named whatever for a library //maybe it could be automatic with some maven plugin? @@ -91,7 +92,10 @@ public class Constants //DEV_FLAG_* are used for enabling tooling / systems reserved for development. //As a precaution, all variables in here MUST ensure we are working in DEV_MODE only. //Nothing here is meant for user level production, only development level production. - public static final boolean DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS = DEV_MODE && true; //enable true / false to disable + public static final boolean DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS = DEV_MODE && false; //enable true / false to disable + + //decompilers will automatically delete their temp files, useful to turn off if you want to quickly debug a decompilers results + public static boolean DECOMPILERS_AUTOMATICALLY_CLEANUP = true; public static final PrintStream ERR = System.err; public static final PrintStream OUT = System.out; From 5bac732ea97281712d8f9f33d8afd34919eaa7f6 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:42:21 -0600 Subject: [PATCH 62/82] Temp File API Update Refactoring & implemented automatic decompiler cleanup flag --- .../decompilers/impl/FernFlowerDecompiler.java | 2 +- .../the/bytecode/club/bytecodeviewer/util/TempFile.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java index d72a1d90..2b8b6315 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/FernFlowerDecompiler.java @@ -111,7 +111,7 @@ public class FernFlowerDecompiler extends AbstractDecompiler { //cleanup temp files if(tempFile != null) - tempFile.delete(); + tempFile.cleanup(); } return FERNFLOWER + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index 208036a5..d2d78683 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -1,5 +1,7 @@ package the.bytecode.club.bytecodeviewer.util; +import the.bytecode.club.bytecodeviewer.Constants; + import java.io.File; import java.util.HashSet; @@ -59,8 +61,11 @@ public class TempFile createdFilePaths.add(file.getAbsolutePath()); } - public void delete() + public void cleanup() { + if(!Constants.DECOMPILERS_AUTOMATICALLY_CLEANUP) + return; + //delete all the items for(String path : createdFilePaths) { From a625c398b2fe2c9f4010cca1c006191054a2eb4a Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:45:40 -0600 Subject: [PATCH 63/82] Start of Decompilers Automatically Reformatting Syntax --- src/main/java/the/bytecode/club/bytecodeviewer/Constants.java | 3 --- src/main/java/the/bytecode/club/bytecodeviewer/Settings.java | 4 ++++ .../java/the/bytecode/club/bytecodeviewer/util/TempFile.java | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java index 46f71ce1..ad5d2603 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Constants.java @@ -94,9 +94,6 @@ public class Constants //Nothing here is meant for user level production, only development level production. public static final boolean DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS = DEV_MODE && false; //enable true / false to disable - //decompilers will automatically delete their temp files, useful to turn off if you want to quickly debug a decompilers results - public static boolean DECOMPILERS_AUTOMATICALLY_CLEANUP = true; - public static final PrintStream ERR = System.err; public static final PrintStream OUT = System.out; diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java index 94374584..cee5038c 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/Settings.java @@ -43,6 +43,10 @@ public class Settings private static List recentPlugins; private static List recentFiles; + //decompilers will automatically delete their temp files, useful to turn off if you want to quickly debug a decompilers results + public static boolean DECOMPILERS_AUTOMATICALLY_CLEANUP = true; + public static boolean DECOMPILERS_UNIFORM_SYNTAX_FORMATTING = false; //TODO + static { try diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java index d2d78683..dc126703 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/util/TempFile.java @@ -1,6 +1,7 @@ package the.bytecode.club.bytecodeviewer.util; import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.Settings; import java.io.File; import java.util.HashSet; @@ -63,7 +64,7 @@ public class TempFile public void cleanup() { - if(!Constants.DECOMPILERS_AUTOMATICALLY_CLEANUP) + if(!Settings.DECOMPILERS_AUTOMATICALLY_CLEANUP) return; //delete all the items From b1004792b64143252c4f4222fa9b462ef742f2a6 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:46:50 -0600 Subject: [PATCH 64/82] Added Blank Decompiler Base Used for developers to copy-paste as a base when adding support to a new decompiler or disassembler --- .../decompilers/impl/BlankDecompilerBase.java | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BlankDecompilerBase.java diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BlankDecompilerBase.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BlankDecompilerBase.java new file mode 100644 index 00000000..30477d12 --- /dev/null +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/BlankDecompilerBase.java @@ -0,0 +1,102 @@ +/*************************************************************************** + * Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite * + * Copyright (C) 2014 Konloch - Konloch.com / BytecodeViewer.com * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +package the.bytecode.club.bytecodeviewer.decompilers.impl; + +import me.konloch.kontainer.io.DiskReader; +import org.objectweb.asm.tree.ClassNode; +import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.api.ExceptionUI; +import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; +import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; +import the.bytecode.club.bytecodeviewer.util.TempFile; + +import java.io.File; +import java.io.FileOutputStream; + +import static the.bytecode.club.bytecodeviewer.Constants.*; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; + +/** + * This is an unused class. This is meant to act as a blank decompiler template to aid in developers creating new decompilers / disassemblers. + * + * @author Konloch + * @since 10/02/2024 + */ +public class BlankDecompilerBase extends AbstractDecompiler +{ + public BlankDecompilerBase() + { + super("[Your] Decompiler", "yourdecompiler"); + } + + @Override + public String decompileClassNode(ClassNode cn, byte[] bytes) + { + TempFile tempFile = null; + String exception; + + try + { + //create the temporary files + tempFile = TempFile.createTemporaryFile(true, ".class"); + File tempInputClassFile = tempFile.getFile(); + File tempOutputJavaFile = tempFile.createFileFromExtension(false, true, ".java"); + + //write the class-file with bytes + try (FileOutputStream fos = new FileOutputStream(tempInputClassFile)) + { + fos.write(bytes); + } + + //decompile the class-file + //TODO this is where you would call your decompiler api + // such as YourDecompiler.decompile(tempClassFile, tempOutputJavaFile); + + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //if the output file is found, read it + if (tempOutputJavaFile.exists()) + return DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); + else + exception = getDecompilerName() + " " + ERROR + "! " + tempOutputJavaFile.getAbsolutePath() + " does not exist."; + } + catch (Throwable e) + { + exception = ExceptionUtils.exceptionToString(e); + } + finally + { + //cleanup temp files + if(tempFile != null) + tempFile.cleanup(); + } + + return getDecompilerName() + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + } + + @Override + public void decompileToZip(String sourceJar, String zipName) + { + decompileToZipFallBack(sourceJar, zipName); + } +} From a094e52add5db3f18736053e58fc2fe294139f9e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:49:44 -0600 Subject: [PATCH 65/82] JADX Decompiler Update --- .../decompilers/impl/JADXDecompiler.java | 150 ++++++++---------- 1 file changed, 68 insertions(+), 82 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java index 6532ead4..12069f1d 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JADXDecompiler.java @@ -22,17 +22,19 @@ import jadx.api.JadxArgs; import jadx.api.JadxDecompiler; import me.konloch.kontainer.io.DiskReader; import org.objectweb.asm.tree.ClassNode; -import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Constants; +import the.bytecode.club.bytecodeviewer.Settings; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; +import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.MiscUtils; +import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; import static the.bytecode.club.bytecodeviewer.Constants.*; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.JADX; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * JADX Java Wrapper @@ -49,96 +51,80 @@ public class JADXDecompiler extends AbstractDecompiler @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { - String fileStart = TEMP_DIRECTORY + FS; - - String exception = ""; - final File tempClass = new File(MiscUtils.getUniqueNameBroken(fileStart, ".class") + ".class"); - - try (FileOutputStream fos = new FileOutputStream(tempClass)) - { - fos.write(bytes); - } - catch (IOException e) - { - BytecodeViewer.handleException(e); - } - - File freeDirectory = new File(findUnusedFile(fileStart)); - freeDirectory.mkdirs(); + TempFile tempFile = null; + String exception; try { - JadxArgs args = new JadxArgs(); - args.setInputFile(tempClass); - args.setOutDir(freeDirectory); - args.setOutDirSrc(freeDirectory); - args.setOutDirRes(freeDirectory); + //create the temporary files + tempFile = TempFile.createTemporaryFile(true, ".class"); + File tempDirectory = tempFile.getParent(); + File tempClassFile = tempFile.getFile(); - JadxDecompiler jadx = new JadxDecompiler(args); - jadx.load(); - jadx.saveSources(); - } - catch (StackOverflowError | Exception e) - { - StringWriter exceptionWriter = new StringWriter(); - e.printStackTrace(new PrintWriter(exceptionWriter)); - e.printStackTrace(); - exception = exceptionWriter.toString(); - } - - tempClass.delete(); - - if (freeDirectory.exists()) - return findFile(MiscUtils.listFiles(freeDirectory)); - - if (exception.isEmpty()) - exception = "Decompiled source file not found!"; - - return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; - } - - public String findUnusedFile(String start) - { - long index = 0; - - while (true) - { - File f = new File(start + index); - - if (!f.exists()) - return f.toString(); - } - } - - public String findFile(File[] fileArray) - { - for (File f : fileArray) - { - if (f.isDirectory()) - return findFile(MiscUtils.listFiles(f)); - else + //write the class-file with bytes + try (FileOutputStream fos = new FileOutputStream(tempClassFile)) { - String s; + fos.write(bytes); + } - try - { - s = DiskReader.loadAsString(f.getAbsolutePath()); - } - catch (Exception e) - { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - String exception = ExceptionUI.SEND_STACKTRACE_TO_NL + sw; + //setup JADX Args + JadxArgs args = new JadxArgs(); + args.setInputFile(tempClassFile); + args.setOutDir(tempDirectory); + args.setOutDirSrc(tempDirectory); + args.setOutDirRes(tempDirectory); - return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; - } + //init jadx decompiler + JadxDecompiler jadx = new JadxDecompiler(args); - return s; + //load jadx + jadx.load(); + + //decompile + jadx.saveSources(); + + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + return searchForJavaFile(MiscUtils.listFiles(tempDirectory)); + } + catch (Throwable e) + { + exception = ExceptionUtils.exceptionToString(e); + } + finally + { + //cleanup temp files + if(tempFile != null) + tempFile.cleanup(); + } + + return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; + } + + public String searchForJavaFile(File[] files) throws Exception + { + for (File file : files) + { + if (file.isDirectory()) + return searchForJavaFile(MiscUtils.listFiles(file)); + else if(file.getName().toLowerCase().endsWith(".java")) + { + String contents = DiskReader.loadAsString(file.getAbsolutePath()); + + //cleanup + if(Settings.DECOMPILERS_AUTOMATICALLY_CLEANUP) + file.delete(); + + return contents; } } - return "JADX error!" + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR; + return JADX + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + + "JADX failed to produce any Java files from the provided source."; } @Override From e029c73ca437a9a181a6be86bccfb148d5448740 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 18:50:46 -0600 Subject: [PATCH 66/82] JavaP Disassembler Update --- .../decompilers/impl/JavapDisassembler.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index f7fbb3c3..1ad51b58 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -31,8 +31,6 @@ import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; @@ -69,7 +67,7 @@ public class JavapDisassembler extends AbstractDecompiler private synchronized String disassembleJavaP(ClassNode cn, byte[] bytes) { TempFile tempFile = null; - String exception = "This decompiler didn't throw an exception - this is probably a BCV logical bug"; + String exception; JFrameConsolePrintStream sysOutBuffer; @@ -115,26 +113,29 @@ public class JavapDisassembler extends AbstractDecompiler } catch (IllegalAccessException e) { + //TODO fallback using CLI (External Process API) + return TranslatedStrings.ILLEGAL_ACCESS_ERROR.toString(); } catch (Throwable e) { - exception = NL + NL + ExceptionUtils.exceptionToString(e); + exception = ExceptionUtils.exceptionToString(e); } finally { BytecodeViewer.sm.silenceExec(false); if(tempFile != null) - tempFile.delete(); + tempFile.cleanup(); } - return "JavaP " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + return getDecompilerName() + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override public void decompileToZip(String sourceJar, String zipName) { + decompileToZipFallBack(sourceJar, zipName); } } From edd09c04096b50892943764517c46db11f8b5709 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:12:50 -0600 Subject: [PATCH 67/82] JavaP Added Simulated Errors --- .../decompilers/impl/JavapDisassembler.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java index 1ad51b58..1b68a445 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JavapDisassembler.java @@ -22,6 +22,7 @@ import me.konloch.kontainer.io.DiskWriter; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Configuration; +import the.bytecode.club.bytecodeviewer.Constants; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.gui.components.JFrameConsolePrintStream; @@ -37,6 +38,7 @@ import java.net.URL; import java.net.URLClassLoader; import static the.bytecode.club.bytecodeviewer.Constants.NL; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DEV_MODE_SIMULATED_ERROR; import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; /** @@ -107,8 +109,14 @@ public class JavapDisassembler extends AbstractDecompiler //expected warning behaviour on JDK-15 } - //return output + //signal finished sysOutBuffer.finished(); + + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //return output return sysOutBuffer.getTextAreaOutputStreamOut().getBuffer().toString(); } catch (IllegalAccessException e) From 1ac293c7b848bc51a2ac8a6e67adc43d899cfab4 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:16:14 -0600 Subject: [PATCH 68/82] Procyon Decompiler Update --- .../decompilers/impl/ProcyonDecompiler.java | 229 +++++++++--------- 1 file changed, 118 insertions(+), 111 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java index 6bd94d7e..f21198d8 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/ProcyonDecompiler.java @@ -27,6 +27,7 @@ import com.strobel.decompiler.PlainTextOutput; import com.strobel.decompiler.languages.java.JavaFormattingOptions; import org.objectweb.asm.tree.ClassNode; import the.bytecode.club.bytecodeviewer.BytecodeViewer; +import the.bytecode.club.bytecodeviewer.Constants; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; @@ -42,8 +43,7 @@ import java.util.zip.ZipException; import java.util.zip.ZipOutputStream; import static the.bytecode.club.bytecodeviewer.Constants.*; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PROCYON; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * Procyon Java Decompiler Wrapper @@ -51,12 +51,13 @@ import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.PRO * @author Konloch * @author DeathMarine */ + public class ProcyonDecompiler extends AbstractDecompiler { public ProcyonDecompiler() { - super("Procyon Decompiler", "proycon"); + super("Procyon Decompiler", "procyon"); } @Override @@ -69,34 +70,43 @@ public class ProcyonDecompiler extends AbstractDecompiler { //create the temporary files tempFile = TempFile.createTemporaryFile(false, ".class"); - File tempClassFile = tempFile.getFile(); + File tempInputClassFile = tempFile.getFile(); //write the ClassNode bytes to the temp file - try (FileOutputStream fos = new FileOutputStream(tempClassFile)) + try (FileOutputStream fos = new FileOutputStream(tempInputClassFile)) { fos.write(bytes); } - //setup proycon decompiler settings + //initialize procyon DecompilerSettings settings = getDecompilerSettings(); - LuytenTypeLoader typeLoader = new LuytenTypeLoader(); MetadataSystem metadataSystem = new MetadataSystem(typeLoader); - TypeReference type = metadataSystem.lookupType(tempClassFile.getCanonicalPath()); - DecompilationOptions decompilationOptions = new DecompilationOptions(); + StringWriter writer = new StringWriter(); + + //lookup the class-file + TypeReference type = metadataSystem.lookupType(tempInputClassFile.getCanonicalPath()); + + //configure procyon decompilationOptions.setSettings(settings); decompilationOptions.setFullDecompilation(true); + //parse class-file TypeDefinition resolvedType; 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(); - settings.getLanguage().decompileType(resolvedType, new PlainTextOutput(stringwriter), decompilationOptions); + //decompile the class-file + 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) { @@ -106,7 +116,7 @@ public class ProcyonDecompiler extends AbstractDecompiler { //delete all temporary files if(tempFile != null) - tempFile.delete(); + tempFile.cleanup(); } return PROCYON + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL @@ -118,7 +128,100 @@ public class ProcyonDecompiler extends AbstractDecompiler { 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 ent = jarFile.entries(); + Set 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) { @@ -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 ent = jfile.entries(); - Set 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() { DecompilerSettings settings = new DecompilerSettings(); From 136346d238f84e736a6db84e37599a87f448a51d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:17:20 -0600 Subject: [PATCH 69/82] Krakatau Decompiler Update New Temp File API. New External Process API. General cleanup. --- .../decompilers/impl/KrakatauDecompiler.java | 192 +++++++++--------- 1 file changed, 98 insertions(+), 94 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDecompiler.java index 08be0e2a..5a146d87 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDecompiler.java @@ -28,15 +28,14 @@ import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; import the.bytecode.club.bytecodeviewer.resources.ExternalResources; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; -import the.bytecode.club.bytecodeviewer.util.JarUtils; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; -import the.bytecode.club.bytecodeviewer.util.ZipUtils; +import the.bytecode.club.bytecodeviewer.util.*; import java.io.*; import java.util.Arrays; import java.util.stream.Collectors; import static the.bytecode.club.bytecodeviewer.Constants.*; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * Krakatau Java Decompiler Wrapper, requires Python 2.7 @@ -51,24 +50,6 @@ public class KrakatauDecompiler extends AbstractDecompiler super("Krakatau Decompiler", "krakatau"); } - public String buildCLIArguments() - { - if (Configuration.library.isEmpty()) - return ""; - - File dir = new File(Configuration.library); - if (!dir.exists()) - return ""; - if (!dir.isDirectory()) - return ";" + Configuration.library; - - File[] files = dir.listFiles(); - if (files == null || files.length == 0) - return ""; - - return ";" + Arrays.stream(files).filter(File::isFile).map(File::getAbsolutePath).collect(Collectors.joining(";")); - } - @Override public String decompileClassNode(ClassNode cn, byte[] bytes) { @@ -79,104 +60,104 @@ public class KrakatauDecompiler extends AbstractDecompiler if (Configuration.rt.isEmpty()) { - BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); + BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); ExternalResources.getSingleton().selectJRERTLibrary(); } if (Configuration.rt.isEmpty()) { - BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); - return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B; + BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); + + return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B; } - final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); - final File tempJar = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar"); - - tempDirectory.mkdir(); - - JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempJar.getAbsolutePath()); - - return decompileClassNode(tempJar, tempDirectory, cn); - } - - public String decompileClassNode(File tempJar, File tempDir, ClassNode cn) - { - if (!ExternalResources.getSingleton().hasSetPython2Command()) - return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString(); - - ExternalResources.getSingleton().rtCheck(); - - if (Configuration.rt.isEmpty()) - { - BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); - ExternalResources.getSingleton().selectJRERTLibrary(); - } - - if (Configuration.rt.isEmpty()) - { - BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); - return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B; - } - - String returnString = ExceptionUI.SEND_STACKTRACE_TO_NL; + StringBuilder processOut = new StringBuilder(NL + NL); + StringBuilder processErr = new StringBuilder(NL + NL); + int exitCode = Integer.MAX_VALUE; + TempFile tempFile = null; + String exception; try { + //create the temporary files + tempFile = TempFile.createTemporaryFile(false, ".jar"); + tempFile.newTemporaryParent(); + File tempInputJarFile = tempFile.getFile(); + File tempDir = tempFile.createFileFromExtension(true, false, ".txt").getParentFile(); + File tempOutputJavaFile = new File(tempDir.getAbsolutePath() + FS + cn.name + ".java"); + + //create out dir + tempDir.mkdirs(); + tempOutputJavaFile.getParentFile().mkdirs(); + + //final File tempDirectory = new File(Constants.TEMP_DIRECTORY + FS + MiscUtils.randomString(32) + FS); + //javaFile = new File(Constants.TEMP_DIRECTORY + FS + "temp" + MiscUtils.randomString(32) + ".jar"); + + JarUtils.saveAsJarClassesOnly(BytecodeViewer.getLoadedClasses(), tempInputJarFile.getAbsolutePath()); + + if (!ExternalResources.getSingleton().hasSetPython2Command()) + return TranslatedStrings.YOU_NEED_TO_SET_YOUR_PYTHON_2_PATH.toString(); + + ExternalResources.getSingleton().rtCheck(); + + if (Configuration.rt.isEmpty()) + { + BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); + ExternalResources.getSingleton().selectJRERTLibrary(); + } + + if (Configuration.rt.isEmpty()) + { + BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); + return TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + " " + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B; + } + String[] pythonCommands = new String[]{Configuration.python2}; if (Configuration.python2Extra) pythonCommands = ArrayUtils.addAll(pythonCommands, "-2"); ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 - krakatauWorkingDirectory + FS + "decompile.py", "-skip", //love you storyyeller <3 - "-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath() + buildCLIArguments(), - "-out", tempDir.getAbsolutePath(), cn.name + ".class")); + krakatauWorkingDirectory + FS + "decompile.py", + "-skip", //love you storyyeller <3 + "-nauto", + "-path", Configuration.rt + ";" + tempInputJarFile.getAbsolutePath() + buildCLIArguments(), + "-out", tempDir.getAbsolutePath(), + cn.name + ".class")); Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); - StringBuilder log = new StringBuilder(TranslatedStrings.PROCESS2 + NL + NL); - //Read out dir output - try (InputStream is = process.getInputStream(); - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr)) - { - String line; - while ((line = br.readLine()) != null) - { - log.append(NL).append(line); - } - } + //ProcessUtils.readProcessToStringBuilderAsync(process, processOut, processErr); + ProcessUtils.readProcessToStringBuilder(process, processOut, processErr); - log.append(NL).append(NL).append(TranslatedStrings.ERROR2).append(NL).append(NL); + //wait for process to exit + exitCode = process.waitFor(); - try (InputStream is = process.getErrorStream(); - InputStreamReader isr = new InputStreamReader(is); - BufferedReader br = new BufferedReader(isr)) - { - String line; - while ((line = br.readLine()) != null) - { - log.append(NL).append(line); - } - } + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); - int exitValue = process.waitFor(); - log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); - returnString = log.toString(); - - // update the string on a successful disassemble - returnString = DiskReader.loadAsString(tempDir.getAbsolutePath() + FS + cn.name + ".java"); + // read the java file on a successful disassemble + return DiskReader.loadAsString(tempOutputJavaFile.getAbsolutePath()); } - catch (Exception e) + catch (Throwable e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - e.printStackTrace(); - returnString += NL + ExceptionUI.SEND_STACKTRACE_TO_NL + sw; + exception = ProcessUtils.mergeLogs(processOut, processErr, exitCode) + + ExceptionUtils.exceptionToString(e); + } + finally + { + //delete all temporary files + if(tempFile != null) + tempFile.cleanup(); } - return returnString; + return KRAKATAU + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL + + TranslatedStrings.SUGGESTED_FIX_DECOMPILER_ERROR + NL + NL + exception; } @Override @@ -189,7 +170,8 @@ public class KrakatauDecompiler extends AbstractDecompiler if (Configuration.rt.isEmpty()) { - BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); + BytecodeViewer.showMessage(TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_A + "\r\n" + + TranslatedStrings.YOU_NEED_TO_SET_YOUR_JAVA_RT_PATH_B); ExternalResources.getSingleton().selectJRERTLibrary(); } @@ -207,7 +189,8 @@ public class KrakatauDecompiler extends AbstractDecompiler ProcessBuilder pb = new ProcessBuilder(ArrayUtils.addAll(pythonCommands, "-O", //love you storyyeller <3 krakatauWorkingDirectory + FS + "decompile.py", "-skip", //love you storyyeller <3 - "-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(), "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath())); + "-nauto", "-path", Configuration.rt + ";" + tempJar.getAbsolutePath(), + "-out", tempDirectory.getAbsolutePath(), tempJar.getAbsolutePath())); Process process = pb.start(); BytecodeViewer.createdProcesses.add(process); @@ -221,4 +204,25 @@ public class KrakatauDecompiler extends AbstractDecompiler BytecodeViewer.handleException(e); } } + + public String buildCLIArguments() + { + if (Configuration.library.isEmpty()) + return ""; + + File dir = new File(Configuration.library); + + if (!dir.exists()) + return ""; + + if (!dir.isDirectory()) + return ";" + Configuration.library; + + File[] files = dir.listFiles(); + if (files == null || files.length == 0) + return ""; + + return ";" + Arrays.stream(files).filter(File::isFile) + .map(File::getAbsolutePath).collect(Collectors.joining(";")); + } } From f7496036d21bf674b9ac02a7af205a4f47054f3d Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:25:22 -0600 Subject: [PATCH 70/82] JD-GUi Decompiler Update --- .../decompilers/impl/JDGUIDecompiler.java | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java index 5f56b3b8..95bd7ee8 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/JDGUIDecompiler.java @@ -21,7 +21,6 @@ package the.bytecode.club.bytecodeviewer.decompilers.impl; import me.konloch.kontainer.io.DiskReader; import org.jd.core.v1.ClassFileToJavaSourceDecompiler; import org.objectweb.asm.tree.ClassNode; -import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.Constants; import the.bytecode.club.bytecodeviewer.api.ExceptionUI; import the.bytecode.club.bytecodeviewer.decompilers.AbstractDecompiler; @@ -31,15 +30,13 @@ import the.bytecode.club.bytecodeviewer.decompilers.jdgui.JDGUIClassFileUtil; import the.bytecode.club.bytecodeviewer.decompilers.jdgui.PlainTextPrinter; import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings; import the.bytecode.club.bytecodeviewer.util.ExceptionUtils; -import the.bytecode.club.bytecodeviewer.util.MiscUtils; import the.bytecode.club.bytecodeviewer.util.TempFile; import java.io.*; import static the.bytecode.club.bytecodeviewer.Constants.FS; import static the.bytecode.club.bytecodeviewer.Constants.NL; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.ERROR; -import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.JDGUI; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.*; /** * JD-Core Decompiler Wrapper @@ -71,18 +68,7 @@ public class JDGUIDecompiler extends AbstractDecompiler File tempJavaFile = tempFile.createFileFromExtension(false, false, ".java"); //make any folders for the packages - if (cn.name.contains("/")) - { - String[] raw = cn.name.split("/"); - String path = tempFile.getParent().getAbsolutePath() + FS; - - for (int i = 0; i < raw.length - 1; i++) - { - path += raw[i] + FS; - File f = new File(path); - f.mkdir(); - } - } + makeFolders(tempFile, cn); try (FileOutputStream fos = new FileOutputStream(tempClassFile)) { @@ -118,16 +104,21 @@ public class JDGUIDecompiler extends AbstractDecompiler decompiler.decompile(loader, printer, internalPath, preferences.getPreferences()); } + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + + //read the java file return DiskReader.loadAsString(tempJavaFile.getAbsolutePath()); } catch (Throwable e) { - exception = NL + NL + ExceptionUtils.exceptionToString(e); + exception = ExceptionUtils.exceptionToString(e); } finally { if(tempFile != null) - tempFile.delete(); + tempFile.cleanup(); } return JDGUI + " " + ERROR + "! " + ExceptionUI.SEND_STACKTRACE_TO + NL + NL @@ -137,6 +128,22 @@ public class JDGUIDecompiler extends AbstractDecompiler @Override public void decompileToZip(String sourceJar, String zipName) { - //TODO + decompileToZipFallBack(sourceJar, zipName); + } + + private void makeFolders(TempFile tempFile, ClassNode cn) + { + if (cn.name.contains("/")) + { + String[] raw = cn.name.split("/"); + String path = tempFile.getParent().getAbsolutePath() + FS; + + for (int i = 0; i < raw.length - 1; i++) + { + path += raw[i] + FS; + File f = new File(path); + f.mkdir(); + } + } } } From 26111456621034af7ac1a21ba687e8e0835d8825 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:26:08 -0600 Subject: [PATCH 71/82] Krakatau Disassembler Simulated Errors --- .../decompilers/impl/KrakatauDisassembler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDisassembler.java index a12ff775..3f3a64fb 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/KrakatauDisassembler.java @@ -35,6 +35,7 @@ import the.bytecode.club.bytecodeviewer.util.ZipUtils; import java.io.*; import static the.bytecode.club.bytecodeviewer.Constants.*; +import static the.bytecode.club.bytecodeviewer.translation.TranslatedStrings.DEV_MODE_SIMULATED_ERROR; /** * Krakatau Java Disassembler Wrapper, requires Python 2.7 @@ -105,6 +106,10 @@ public class KrakatauDisassembler extends AbstractDecompiler log.append(NL).append(NL).append(TranslatedStrings.EXIT_VALUE_IS).append(" ").append(exitValue); returnString = log.toString(); + //handle simulated errors + if(Constants.DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS) + throw new RuntimeException(DEV_MODE_SIMULATED_ERROR.toString()); + // update the string on a successful disassemble returnString = DiskReader.loadAsString(tempDirectory.getAbsolutePath() + FS + cn.name + ".j"); } From 5398cdaea09414e40d394d3581ecd9b570519a4e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:26:27 -0600 Subject: [PATCH 72/82] Cleanup --- .../bytecodeviewer/decompilers/impl/SmaliDisassembler.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java index a175cc4d..030bee43 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/decompilers/impl/SmaliDisassembler.java @@ -69,8 +69,6 @@ public class SmaliDisassembler extends AbstractDecompiler BytecodeViewer.handleException(e); } - //ZipUtils.zipFile(tempClass, tempZip); - Dex2Jar.saveAsDex(tempClass, tempDex, true); try @@ -106,6 +104,7 @@ public class SmaliDisassembler extends AbstractDecompiler while (!found) { File f = Objects.requireNonNull(current.listFiles())[0]; + if (f.isDirectory()) current = f; else @@ -113,7 +112,6 @@ public class SmaliDisassembler extends AbstractDecompiler outputSmali = f; found = true; } - } try { From b36c67f6eb4f7a1fbba5a7287b0bf5723c7059b5 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 19:41:37 -0600 Subject: [PATCH 73/82] CLI Clean Banner --- .../bytecodeviewer/cli/actions/commands/CleanBootCommand.java | 2 ++ .../club/bytecodeviewer/cli/actions/commands/CleanCommand.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanBootCommand.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanBootCommand.java index e74f7df2..1c28c7e4 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanBootCommand.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanBootCommand.java @@ -22,5 +22,7 @@ public class CleanBootCommand extends CLICommand public void runCommand(CommandLine cmd) { new File(Constants.getBCVDirectory()).delete(); + + System.out.println("BCV Directory Deleted - Continuing to GUI..."); } } diff --git a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanCommand.java b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanCommand.java index 9bb0b806..718ab8fe 100644 --- a/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanCommand.java +++ b/src/main/java/the/bytecode/club/bytecodeviewer/cli/actions/commands/CleanCommand.java @@ -24,5 +24,7 @@ public class CleanCommand extends CLICommand public void runCommand(CommandLine cmd) { new File(Constants.getBCVDirectory()).delete(); + + System.out.println("BCV Directory Deleted - Exiting..."); } } From 59f45e58b9592d53fbede7e71d45da35bd68e261 Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 21:06:54 -0600 Subject: [PATCH 74/82] Show Generated Xposed Class In GUI Also fixed some runtime bugs. --- plugins/java/XposedGenerator.java | 57 ++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/plugins/java/XposedGenerator.java b/plugins/java/XposedGenerator.java index 5d869cf7..38051ddc 100644 --- a/plugins/java/XposedGenerator.java +++ b/plugins/java/XposedGenerator.java @@ -46,11 +46,17 @@ public class XposedGenerator extends Plugin String className = viewer.getName(); ClassNode classnode = BytecodeViewer.getCurrentlyOpenedClassNode(); + if (classnode == null) + { + BytecodeViewer.showMessage("Open A Classfile First"); + return; + } + //Call XposedGenerator class - ParseChosenFileContent(className, classnode); + parseChosenFileContent(className, classnode); } - public static void ParseChosenFileContent(String classname, ClassNode classNode) + public static void parseChosenFileContent(String classname, ClassNode classNode) { try { @@ -64,7 +70,9 @@ public class XposedGenerator extends Plugin //Decompile using Fern String decomp = decompilefern.decompileClassNode(classNode, cont); String[] xposedTemplateTypes = {"Empty", "Parameters", "Helper"}; - @SuppressWarnings({"unchecked", "rawtypes"}) JComboBox xposedTemplateList = new JComboBox(xposedTemplateTypes); + @SuppressWarnings({"unchecked", "rawtypes"}) + JComboBox xposedTemplateList = new JComboBox(xposedTemplateTypes); + //Set results of parsed methods into a list List methodsExtracted = ProcessContentExtractedClass(decomp); String packgExtracted = ProcessContentExtractedPackage(decomp); @@ -86,6 +94,7 @@ public class XposedGenerator extends Plugin //output methods to pane box int result = JOptionPane.showConfirmDialog(null, myPanel, "Choose Template and Method for Xposed Module", JOptionPane.OK_CANCEL_OPTION); + myPanel.remove(); if (result == JOptionPane.OK_OPTION) { @@ -129,13 +138,6 @@ public class XposedGenerator extends Plugin { try { - //TODO: Prompt save dialog - File file = new File("./XposedClassTest.java"); - - // if file doesn't exist, then create it - if (!file.exists()) - file.createNewFile(); - //Extract the package name only String packageNameOnly = packageName.substring(8, packageName.length() - 2).trim(); String classToHookNameOnly = classToHook; @@ -151,18 +153,35 @@ public class XposedGenerator extends Plugin String onlyFunction = CleanUpFunction(functionSplitValues); //Write Xposed Class - String XposedClassText = "package androidpentesting.com.xposedmodule;" + "\r\n" + "import de.robv.android.xposed.IXposedHookLoadPackage;" + "\r\n" + "\r\n" + "import de.robv.android.xposed.XC_MethodHook;" + "\r\n" + "import de.robv.android.xposed.XposedBridge;" + "\r\n" + "import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;" + "\r\n" + "import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;" + "\r\n" + "\r\n" + "public class XposedClassTest implements IXposedHookLoadPackage {" + "\r\n" + "\r\n" + " public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {" + "\r\n" + "\r\n" + " String classToHook = " + "\"" + packageNameOnly + "." + onlyClass + "\";" + "\r\n" + " String functionToHook = " + "\"" + onlyFunction + "\";" + "\r\n" + " if (lpparam.packageName.equals(" + "\"" + packageNameOnly + "\"" + ")){" + "\r" + "\n" + " XposedBridge.log(" + "\" Loaded app: \" " + " + lpparam.packageName);" + "\r\n" + "\r\n" + " findAndHookMethod(" + "\"" + onlyClass + "\"" + ", lpparam.classLoader, " + " \"" + onlyFunction + "\"" + ", int.class," + "\r\n" + " new XC_MethodHook() {" + "\r\n" + " @Override" + "\r\n" + " protected void beforeHookedMethod(MethodHookParam param) throws " + "Throwable {" + "\r\n" + " //TO BE FILLED BY ANALYST" + "\r\n" + " }" + "\r\n" + " });" + "\r\n" + " }" + "\r\n" + " }" + "\r\n" + "}" + "\r\n"; - FileWriter fw = new FileWriter(file.getAbsoluteFile()); - BufferedWriter bw = new BufferedWriter(fw); - bw.write(XposedClassText); - bw.write("\r\n"); - bw.close(); + String XposedClassText = "package androidpentesting.com.xposedmodule;" + "\r\n" + + "import de.robv.android.xposed.IXposedHookLoadPackage;" + "\r\n" + "\r\n" + + "import de.robv.android.xposed.XC_MethodHook;" + "\r\n" + + "import de.robv.android.xposed.XposedBridge;" + "\r\n" + + "import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;" + "\r\n" + + "import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;" + "\r\n" + "\r\n" + + "public class XposedClassTest implements IXposedHookLoadPackage {" + "\r\n" + "\r\n" + + " public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {" + "\r\n" + "\r\n" + + " String classToHook = " + "\"" + packageNameOnly + "." + onlyClass + "\";" + "\r\n" + + " String functionToHook = " + "\"" + onlyFunction + "\";" + "\r\n" + "\r\n" + + " if (lpparam.packageName.equals(" + "\"" + packageNameOnly + "\"" + ")){" + "\r\n" + + " XposedBridge.log(" + "\" Loaded app: \" " + " + lpparam.packageName);" + "\r\n" + "\r\n" + + " findAndHookMethod(" + "\"" + onlyClass + "\"" + ", lpparam.classLoader, " + " \"" + onlyFunction + "\"" + ", int.class," + "\r\n" + + " new XC_MethodHook() {" + "\r\n" + + " @Override" + "\r\n" + + " protected void beforeHookedMethod(MethodHookParam param) throws Throwable {" + "\r\n" + + " //TO BE FILLED BY ANALYST" + "\r\n" + + " }" + "\r\n" + + " });" + "\r\n" + + " }" + "\r\n" + + " }" + "\r\n" + + "}" + "\r\n"; - JOptionPane.showMessageDialog(null, "Xposed Module Generated"); + PluginConsole gui = new PluginConsole("Xposed Code Generation"); + gui.appendText(XposedClassText); + gui.setVisible(true); } - catch (IOException e) + catch (Exception e) { - JOptionPane.showMessageDialog(null, "Error" + e); e.printStackTrace(); } } From 1f13c21dc055728db34fa389d7d3075acdd94d7e Mon Sep 17 00:00:00 2001 From: Konloch Date: Wed, 2 Oct 2024 21:12:58 -0600 Subject: [PATCH 75/82] External Plugin Cleanup / Fixes --- plugins/java/ExampleStringDecrypter.java | 68 ++++++++++++++---------- plugins/java/Skeleton.java | 9 ++-- plugins/java/XposedGenerator.java | 1 + 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/plugins/java/ExampleStringDecrypter.java b/plugins/java/ExampleStringDecrypter.java index cc7d3dab..8e71a3b4 100644 --- a/plugins/java/ExampleStringDecrypter.java +++ b/plugins/java/ExampleStringDecrypter.java @@ -1,68 +1,82 @@ import java.lang.reflect.Field; import java.util.List; + import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; +import the.bytecode.club.bytecodeviewer.*; import the.bytecode.club.bytecodeviewer.api.*; import the.bytecode.club.bytecodeviewer.gui.components.MultipleChoiceDialog; -import static the.bytecode.club.bytecodeviewer.Constants.nl; +import static the.bytecode.club.bytecodeviewer.Constants.NL; /** - ** This is an example of a String Decrypter Java Plugin for BCV. - ** - ** @author [Your-Name-Goes-Here] + * * This is an example of a String Decrypter Java Plugin for BCV. + * * + * * @author [Your-Name-Goes-Here] **/ -public class ExampleStringDecrypter extends Plugin { +public class ExampleStringDecrypter extends Plugin +{ @Override - public void execute(List classNodesList) { + public void execute(List classNodesList) + { PluginConsole gui = new PluginConsole("Example String Decrypter Java Edition"); - MultipleChoiceDialog dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING", - "WARNING: This will load the classes into the JVM and execute the initialize function" - + nl + "for each class. IF THE FILE YOU'RE LOADING IS MALICIOUS, DO NOT CONTINUE.", - new String[]{"Continue", "Cancel"}); + MultipleChoiceDialog dialog = new MultipleChoiceDialog("Bytecode Viewer - WARNING", "WARNING: This will load the classes into the JVM and execute the initialize function" + NL + + "for each class. IF THE FILE YOU'RE LOADING IS MALICIOUS, DO NOT CONTINUE.", new String[]{"Continue", "Cancel"}); - if (dialog.promptChoice() == 0) { + if (dialog.promptChoice() == 0) + { boolean needsWarning = false; - - for (ClassNode cn : classNodesList) { - try { + + for (ClassNode cn : classNodesList) + { + try + { //load the class node into the classloader BCV.getClassNodeLoader().addClass(cn); - - for (Object o : cn.fields.toArray()) { + + for (Object o : cn.fields.toArray()) + { FieldNode f = (FieldNode) o; - + //if the class contains the field z, get the class object from the class node //then print out the value of the fields inside the class //if the strings get decrypted on init, this allows you to dump the current values - - if (f.name.equals("z")) { - try { - for (Field f2 : BCV.getClassNodeLoader().nodeToClass(cn).getFields()) { + if (f.name.equals("z")) + { + try + { + for (Field f2 : BCV.getClassNodeLoader().nodeToClass(cn).getFields()) + { String s = (String) f2.get(null); if (s != null && !s.isEmpty()) gui.appendText(cn + ":" + s); } - } catch (Exception ignored) { + } + catch (Exception ignored) + { } } } - } catch (Exception e) { + } + catch (Exception e) + { gui.appendText("Failed loading class " + cn.name); e.printStackTrace(); needsWarning = true; } } - - if (needsWarning) { - BytecodeViewer.showMessage("Some classes failed to decrypt, if you'd like to decrypt all of them\n" - + "makes sure you include ALL the libraries it requires."); + + if (needsWarning) + { + BytecodeViewer.showMessage("Some classes failed to decrypt, if you'd like to decrypt all of them" + NL + + "makes sure you include ALL the libraries it requires."); } gui.setVisible(true); } } + } diff --git a/plugins/java/Skeleton.java b/plugins/java/Skeleton.java index 4177905b..32444410 100644 --- a/plugins/java/Skeleton.java +++ b/plugins/java/Skeleton.java @@ -8,12 +8,15 @@ import the.bytecode.club.bytecodeviewer.api.*; ** @author [Your Name Goes Here] **/ -public class Skeleton extends Plugin { +public class Skeleton extends Plugin +{ @Override - public void execute(List classNodesList) { + public void execute(List classNodesList) + { PluginConsole gui = new PluginConsole("Skeleton Title"); gui.setVisible(true); gui.appendText("executed skeleton example"); } -} \ No newline at end of file + +} diff --git a/plugins/java/XposedGenerator.java b/plugins/java/XposedGenerator.java index 38051ddc..70c44eed 100644 --- a/plugins/java/XposedGenerator.java +++ b/plugins/java/XposedGenerator.java @@ -327,4 +327,5 @@ public class XposedGenerator extends Plugin String QUOTE = "'"; return QUOTE + aText + QUOTE; } + } From 17d97368f38f0804dbc6f67f97b6a9cbbf1be992 Mon Sep 17 00:00:00 2001 From: Konloch Date: Thu, 3 Oct 2024 22:51:21 -0600 Subject: [PATCH 76/82] Added Disk-Lib --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index e3ef9dd3..28b80938 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,7 @@ 3.26.1 1.0.1 1.7 + 1.2.0 @@ -395,6 +396,11 @@ google-java-format ${google-java-format.version} + + com.konloch + DiskLib + ${disk-lib.version} +