diff --git a/assets/run-deobfuscator.gif b/assets/run-deobfuscator.gif index 7e5cfe97..69fc4124 100644 Binary files a/assets/run-deobfuscator.gif and b/assets/run-deobfuscator.gif differ diff --git a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/Context.java b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/Context.java index e74c372d..c2179f28 100644 --- a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/Context.java +++ b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/Context.java @@ -14,23 +14,26 @@ public class Context { private final Map originalClasses = new ConcurrentHashMap<>(); private final Map files = new ConcurrentHashMap<>(); - private LibraryClassLoader loader; - private SandBox sandBox; + private final DeobfuscatorOptions options; + private final LibraryClassLoader loader; + private final SandBox sandBox; - public LibraryClassLoader getLoader() { - return loader; + public Context(DeobfuscatorOptions options, LibraryClassLoader loader, SandBox sandBox) { + this.options = options; + this.loader = loader; + this.sandBox = sandBox; } - public void setLoader(LibraryClassLoader loader) { - this.loader = loader; + public DeobfuscatorOptions getOptions() { + return options; } - public SandBox getSandBox() { - return sandBox; + public LibraryClassLoader getLoader() { + return loader; } - public void setSandBox(SandBox sandBox) { - this.sandBox = sandBox; + public SandBox getSandBox() { + return sandBox; } public Collection classes() { diff --git a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/DeobfuscatorOptions.java b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/DeobfuscatorOptions.java new file mode 100644 index 00000000..09facfdf --- /dev/null +++ b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/context/DeobfuscatorOptions.java @@ -0,0 +1,247 @@ +package uwu.narumi.deobfuscator.api.context; + +import dev.xdark.ssvm.VirtualMachine; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import uwu.narumi.deobfuscator.api.transformer.Transformer; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +/** + * Immutable options for deobfuscator + */ +public record DeobfuscatorOptions( + @Nullable Path inputJar, + List classes, + Set libraries, + + @Nullable Path outputJar, + @Nullable Path outputDir, + + List> transformers, + + int classReaderFlags, + int classWriterFlags, + + boolean consoleDebug, + boolean suppressErrors, + boolean verifyBytecode, + + VirtualMachine virtualMachine +) { + public static DeobfuscatorOptions.Builder builder() { + return new DeobfuscatorOptions.Builder(); + } + + public record ExternalClass(Path path, String relativePath) { + } + + /** + * Builder for {@link DeobfuscatorOptions} + */ + public static class Builder { + // Inputs + @Nullable + private Path inputJar = null; + private final List classes = new ArrayList<>(); + private final Set libraries = new HashSet<>(); + + // Outputs + @Nullable + private Path outputJar = null; + @Nullable + private Path outputDir = null; + + // Transformers + private final List> transformers = new ArrayList<>(); + + // Other config + private int classReaderFlags = ClassReader.SKIP_FRAMES; + private int classWriterFlags = ClassWriter.COMPUTE_FRAMES; + + private boolean consoleDebug = false; + private boolean suppressErrors = false; + private boolean verifyBytecode = false; + + private VirtualMachine virtualMachine = null; + + private Builder() { + } + + /** + * Your input jar file + */ + @Contract("_ -> this") + public DeobfuscatorOptions.Builder inputJar(@Nullable Path inputJar) { + this.inputJar = inputJar; + if (this.inputJar != null) { + String fullName = inputJar.getFileName().toString(); + int dot = fullName.lastIndexOf('.'); + + // Auto fill output jar + this.outputJar = inputJar.getParent() + .resolve(dot == -1 ? fullName + "-out" : fullName.substring(0, dot) + "-out" + fullName.substring(dot)); + this.libraries.add(inputJar); + } + return this; + } + + /** + * Output jar for deobfuscated classes. Automatically filled when input jar is set + */ + @Contract("_ -> this") + public DeobfuscatorOptions.Builder outputJar(@Nullable Path outputJar) { + this.outputJar = outputJar; + return this; + } + + /** + * Set output dir it if you want to output raw compiled classes instead of jar file + */ + @Contract("_ -> this") + public DeobfuscatorOptions.Builder outputDir(@Nullable Path outputDir) { + this.outputDir = outputDir; + return this; + } + + @Contract("_ -> this") + public DeobfuscatorOptions.Builder libraries(Path... paths) { + this.libraries.addAll(List.of(paths)); + return this; + } + + /** + * Add external class to deobfuscate + * + * @param path Path to external class + * @param relativePath Relative path for saving purposes + */ + @Contract("_,_ -> this") + public DeobfuscatorOptions.Builder clazz(Path path, String relativePath) { + this.classes.add(new DeobfuscatorOptions.ExternalClass(path, relativePath)); + return this; + } + + /** + * Transformers to run. You need to specify them in lambda form: + *
+     * {@code
+     * () -> new MyTransformer(true, false),
+     * () -> new AnotherTransformer(),
+     * () -> new SuperTransformer()
+     * }
+     * 
+ * + * We can push it further, and we can replace lambdas with no arguments with method references: + *
+     * {@code
+     * () -> new MyTransformer(true, false),
+     * AnotherTransformer::new,
+     * SuperTransformer::new
+     * }
+     * 
+ */ + @SafeVarargs + @Contract("_ -> this") + public final DeobfuscatorOptions.Builder transformers(Supplier... transformers) { + this.transformers.addAll(List.of(transformers)); + return this; + } + + /** + * Flags for {@link ClassReader} + */ + @Contract("_ -> this") + public DeobfuscatorOptions.Builder classReaderFlags(int classReaderFlags) { + this.classReaderFlags = classReaderFlags; + return this; + } + + /** + * Flags for {@link ClassWriter} + */ + @Contract("_ -> this") + public DeobfuscatorOptions.Builder classWriterFlags(int classWriterFlags) { + this.classWriterFlags = classWriterFlags; + return this; + } + + /** + * Enables stacktraces logging + */ + @Contract(" -> this") + public DeobfuscatorOptions.Builder consoleDebug() { + this.consoleDebug = true; + return this; + } + + /** + * Continue deobfuscation even if errors occur + */ + @Contract(" -> this") + public DeobfuscatorOptions.Builder suppressErrors() { + this.suppressErrors = true; + return this; + } + + /** + * Verify bytecode after each transformer run. Useful when debugging which + * transformer is causing issues (aka broke bytecode) + */ + @Contract(" -> this") + public DeobfuscatorOptions.Builder verifyBytecode() { + this.verifyBytecode = true; + return this; + } + + @Contract("_ -> this") + public DeobfuscatorOptions.Builder virtualMachine(VirtualMachine virtualMachine) { + this.virtualMachine = virtualMachine; + return this; + } + + /** + * Build immutable {@link DeobfuscatorOptions} with options verification + */ + public DeobfuscatorOptions build() { + // Verify some options + if (this.inputJar == null && this.classes.isEmpty()) { + throw new IllegalStateException("No input files provided"); + } + if (this.outputJar == null && this.outputDir == null) { + throw new IllegalStateException("No output file or directory provided"); + } + if (this.outputJar != null && this.outputDir != null) { + throw new IllegalStateException("Output jar and output dir cannot be set at the same time"); + } + + return new DeobfuscatorOptions( + // Input + inputJar, + classes, + libraries, + // Output + outputJar, + outputDir, + // Transformers + transformers, + // Flags + classReaderFlags, + classWriterFlags, + // Other config + consoleDebug, + suppressErrors, + verifyBytecode, + + virtualMachine + ); + } + } +} diff --git a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/transformer/Transformer.java b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/transformer/Transformer.java index 36a4f343..96701eb7 100644 --- a/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/transformer/Transformer.java +++ b/deobfuscator-api/src/main/java/uwu/narumi/deobfuscator/api/transformer/Transformer.java @@ -87,18 +87,21 @@ private static boolean transform( LOGGER.info("Ended {} transformer in {} ms", transformer.name(), (System.currentTimeMillis() - start)); // Bytecode verification - /*if (oldInstance == null && changed) { - // Verify if code is valid + if (context.getOptions().verifyBytecode() && oldInstance == null && changed) { + // Verify if bytecode is valid try { verifyBytecode(scope, context); } catch (RuntimeException e) { LOGGER.error("Transformer {} produced invalid bytecode", transformer.name(), e); } - }*/ + } } catch (TransformerException e) { LOGGER.error("! {}: {}", transformer.name(), e.getMessage()); } catch (Exception e) { LOGGER.error("Error occurred when transforming {}", transformer.name(), e); + if (!context.getOptions().suppressErrors()) { + throw new RuntimeException(e); + } } LOGGER.info("-------------------------------------\n"); diff --git a/deobfuscator-impl/src/main/java/uwu/narumi/deobfuscator/Deobfuscator.java b/deobfuscator-impl/src/main/java/uwu/narumi/deobfuscator/Deobfuscator.java index b91d467a..59db8b8f 100644 --- a/deobfuscator-impl/src/main/java/uwu/narumi/deobfuscator/Deobfuscator.java +++ b/deobfuscator-impl/src/main/java/uwu/narumi/deobfuscator/Deobfuscator.java @@ -1,10 +1,6 @@ package uwu.narumi.deobfuscator; -import dev.xdark.ssvm.VirtualMachine; - import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -13,13 +9,13 @@ import java.util.function.Supplier; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassWriter; import uwu.narumi.deobfuscator.api.asm.ClassWrapper; import uwu.narumi.deobfuscator.api.context.Context; +import uwu.narumi.deobfuscator.api.context.DeobfuscatorOptions; +import uwu.narumi.deobfuscator.api.execution.SandBox; import uwu.narumi.deobfuscator.api.helper.ClassHelper; import uwu.narumi.deobfuscator.api.helper.FileHelper; import uwu.narumi.deobfuscator.api.library.Library; @@ -28,75 +24,56 @@ public class Deobfuscator { - private static final Logger LOGGER = LogManager.getLogger(Deobfuscator.class); - - private final Context context = new Context(); - - private final List> transformers = new ArrayList<>(); - @Nullable - private final Path inputJar; - @Nullable - private final Path outputJar; - @Nullable - private final Path outputDir; - private final List classes; + /** + * Creates a new {@link Deobfuscator} instance from its options + */ + public static Deobfuscator from(DeobfuscatorOptions options) { + return new Deobfuscator(options); + } - private final int classReaderFlags; - private final int classWriterFlags; - private final boolean consoleDebug; + private static final Logger LOGGER = LogManager.getLogger(Deobfuscator.class); - private Deobfuscator(Builder builder) throws FileNotFoundException { - if (builder.inputJar == null && builder.classes.isEmpty()) { - throw new FileNotFoundException("No input files provided"); - } + private final DeobfuscatorOptions options; + private final Context context; - if (builder.outputJar != null && Files.exists(builder.outputJar)) + private Deobfuscator(DeobfuscatorOptions options) { + if (options.outputJar() != null && Files.exists(options.outputJar())) { LOGGER.warn("Output file already exist, data will be overwritten"); + } - this.inputJar = builder.inputJar; - this.outputJar = builder.outputJar; - this.outputDir = builder.outputDir; - this.classes = builder.classes; - - this.transformers.addAll(builder.transformers); - this.classReaderFlags = builder.classReaderFlags; - this.classWriterFlags = builder.classWriterFlags; - this.consoleDebug = builder.consoleDebug; + this.options = options; - this.context.setLoader( - new LibraryClassLoader( - this.getClass().getClassLoader(), - builder.libraries.stream().map(path -> new Library(path, this.classWriterFlags)).toList())); + LibraryClassLoader libraryClassLoader = new LibraryClassLoader( + this.getClass().getClassLoader(), + options.libraries().stream().map(path -> new Library(path, options.classWriterFlags())).toList() + ); // Temporary disabled until the sandbox is fixed + SandBox sandBox = null; /*try { - this.context.setSandBox( - new SandBox( - this.context.getLoader(), - builder.virtualMachine == null ? new VirtualMachine() : builder.virtualMachine)); + sandBox = new SandBox( + this.context.getLoader(), + options.virtualMachine() == null ? new VirtualMachine() : options.virtualMachine() + ); } catch (Throwable t) { LOGGER.error("SSVM bootstrap failed"); LOGGER.debug("Error", t); - if (consoleDebug) t.printStackTrace(); - - this.context.setSandBox(null); + if (options.consoleDebug()) t.printStackTrace(); }*/ - } - public static Builder builder() { - return new Builder(); + this.context = new Context(options, libraryClassLoader, sandBox); } public void start() { try { loadInput(); - transform(transformers); + transform(this.options.transformers()); saveOutput(); } catch (Exception e) { LOGGER.error("Error occurred while obfuscation"); LOGGER.debug("Error", e); - if (consoleDebug) e.printStackTrace(); + if (this.options.consoleDebug()) e.printStackTrace(); } } @@ -105,23 +82,23 @@ public Context getContext() { } private void loadInput() { - if (inputJar != null) { - LOGGER.info("Loading jar file: {}", inputJar); + if (this.options.inputJar() != null) { + LOGGER.info("Loading jar file: {}", this.options.inputJar()); // Load jar - FileHelper.loadFilesFromZip(inputJar, this::loadClass); - LOGGER.info("Loaded jar file: {}\n", inputJar); + FileHelper.loadFilesFromZip(this.options.inputJar(), this::loadClass); + LOGGER.info("Loaded jar file: {}\n", this.options.inputJar()); } - for (ExternalClass clazz : classes) { - LOGGER.info("Loading class: {}", clazz.relativePath); + for (DeobfuscatorOptions.ExternalClass clazz : this.options.classes()) { + LOGGER.info("Loading class: {}", clazz.relativePath()); - try (InputStream inputStream = new FileInputStream(clazz.path.toFile())) { + try (InputStream inputStream = new FileInputStream(clazz.path().toFile())) { // Load class - this.loadClass(clazz.relativePath, inputStream.readAllBytes()); + this.loadClass(clazz.relativePath(), inputStream.readAllBytes()); - LOGGER.info("Loaded class: {}\n", clazz.relativePath); + LOGGER.info("Loaded class: {}\n", clazz.relativePath()); } catch (IOException e) { - LOGGER.error("Could not load class: {}", clazz.relativePath, e); + LOGGER.error("Could not load class: {}", clazz.relativePath(), e); } } } @@ -132,8 +109,8 @@ private void loadClass(String path, byte[] bytes) { ClassWrapper classWrapper = ClassHelper.loadClass( path, bytes, - this.classReaderFlags, - this.classWriterFlags, + this.options.classReaderFlags(), + this.options.classWriterFlags(), true ); context.getClasses().putIfAbsent(classWrapper.name(), classWrapper); @@ -146,7 +123,7 @@ private void loadClass(String path, byte[] bytes) { LOGGER.debug("Error", e); context.getFiles().putIfAbsent(path, bytes); - if (consoleDebug) e.printStackTrace(); + if (this.options.consoleDebug()) e.printStackTrace(); } } @@ -161,9 +138,9 @@ public void transform(List> transformers) { * Saves deobfuscation output result */ private void saveOutput() { - if (outputJar != null) { + if (this.options.outputJar() != null) { saveToJar(); - } else if (outputDir != null) { + } else if (this.options.outputDir() != null) { saveClassesToDir(); } else { throw new IllegalStateException("No output file or directory provided"); @@ -171,7 +148,7 @@ private void saveOutput() { } private void saveClassesToDir() { - LOGGER.info("Saving classes to output directory: {}", outputDir); + LOGGER.info("Saving classes to output directory: {}", this.options.outputDir()); context .getClasses() @@ -179,7 +156,7 @@ private void saveClassesToDir() { try { byte[] data = classWrapper.compileToBytes(this.context); - Path path = this.outputDir.resolve(classWrapper.getPath() + ".class"); + Path path = this.options.outputDir().resolve(classWrapper.getPath() + ".class"); Files.createDirectories(path.getParent()); Files.write(path, data); } catch (Exception e) { @@ -192,9 +169,9 @@ private void saveClassesToDir() { } private void saveToJar() { - LOGGER.info("Saving output file: {}", outputJar); + LOGGER.info("Saving output file: {}", this.options.outputJar()); - try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(outputJar))) { + try (ZipOutputStream zipOutputStream = new ZipOutputStream(Files.newOutputStream(this.options.outputJar()))) { zipOutputStream.setLevel(9); context @@ -211,13 +188,14 @@ private void saveToJar() { "Could not save class, saving original class instead of deobfuscated: {}", classWrapper.name()); LOGGER.debug("Error", e); - if (consoleDebug) e.printStackTrace(); + if (this.options.consoleDebug()) e.printStackTrace(); try { byte[] data = ClassHelper.classToBytes( context.getOriginalClasses().get(classWrapper.name()).getClassNode(), - classWriterFlags); + this.options.classWriterFlags() + ); zipOutputStream.putNextEntry(new ZipEntry(classWrapper.name() + ".class")); zipOutputStream.write(data); @@ -225,7 +203,7 @@ private void saveToJar() { LOGGER.error("Could not save original class: {}", classWrapper.name()); LOGGER.debug("Error", e2); - if (consoleDebug) e2.printStackTrace(); + if (this.options.consoleDebug()) e2.printStackTrace(); } } @@ -244,117 +222,17 @@ private void saveToJar() { LOGGER.error("Could not save file: {}", name); LOGGER.debug("Error", e); - if (consoleDebug) e.printStackTrace(); + if (this.options.consoleDebug()) e.printStackTrace(); } context.getFiles().remove(name); }); } catch (Exception e) { - LOGGER.error("Could not save output file: {}", outputJar); + LOGGER.error("Could not save output file: {}", this.options.outputJar()); LOGGER.debug("Error", e); - if (consoleDebug) e.printStackTrace(); - } - - LOGGER.info("Saved output file: {}\n", outputJar); - } - - public static class Builder { - - private final Set libraries = new HashSet<>(); - @Nullable - private Path inputJar = null; - @Nullable - private Path outputJar = null; - @Nullable - private Path outputDir = null; - private List classes = new ArrayList<>(); - private List> transformers = List.of(); - - private int classReaderFlags = ClassReader.SKIP_FRAMES; - private int classWriterFlags = ClassWriter.COMPUTE_FRAMES; - - private boolean consoleDebug; - - private VirtualMachine virtualMachine; - - private Builder() {} - - public Builder inputJar(@Nullable Path inputJar) { - this.inputJar = inputJar; - if (this.inputJar != null) { - String fullName = inputJar.getFileName().toString(); - int dot = fullName.lastIndexOf('.'); - this.outputJar = - inputJar - .getParent() - .resolve( - dot == -1 - ? fullName + "-out" - : fullName.substring(0, dot) + "-out" + fullName.substring(dot)); - this.libraries.add(inputJar); - } - return this; - } - - public Builder outputJar(@Nullable Path outputJar) { - this.outputJar = outputJar; - return this; - } - - /** - * Output dir for deobfuscated classes - */ - public Builder outputDir(@Nullable Path outputDir) { - this.outputDir = outputDir; - return this; - } - - public Builder libraries(Path... paths) { - this.libraries.addAll(List.of(paths)); - return this; - } - - /** - * Add external class to deobfuscate - * @param path Path to external class - * @param relativePath Relative path for saving purposes - */ - public Builder clazz(Path path, String relativePath) { - this.classes.add(new ExternalClass(path, relativePath)); - return this; - } - - @SafeVarargs - public final Builder transformers(Supplier... transformers) { - this.transformers = Arrays.asList(transformers); - return this; - } - - public Builder classReaderFlags(int classReaderFlags) { - this.classReaderFlags = classReaderFlags; - return this; - } - - public Builder classWriterFlags(int classWriterFlags) { - this.classWriterFlags = classWriterFlags; - return this; - } - - public Builder consoleDebug() { - this.consoleDebug = true; - return this; + if (this.options.consoleDebug()) e.printStackTrace(); } - public Builder virtualMachine(VirtualMachine virtualMachine) { - this.virtualMachine = virtualMachine; - return this; - } - - public Deobfuscator build() throws FileNotFoundException { - return new Deobfuscator(this); - } - } - - public record ExternalClass(Path path, String relativePath) { + LOGGER.info("Saved output file: {}\n", this.options.outputJar()); } } diff --git a/deobfuscator-impl/src/test/java/Bootstrap.java b/deobfuscator-impl/src/test/java/Bootstrap.java index fdfba9c3..0e7a551a 100644 --- a/deobfuscator-impl/src/test/java/Bootstrap.java +++ b/deobfuscator-impl/src/test/java/Bootstrap.java @@ -3,21 +3,28 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import uwu.narumi.deobfuscator.Deobfuscator; +import uwu.narumi.deobfuscator.api.context.DeobfuscatorOptions; +import uwu.narumi.deobfuscator.core.other.composed.ComposedGeneralFlowTransformer; public class Bootstrap { - public static void main(String[] args) throws Exception { - Deobfuscator.builder() - .inputJar(Path.of("work", "obf-test.jar")) - .virtualMachine( - new VirtualMachine() { - // you can do shit - }) - .transformers() - .consoleDebug() - .classReaderFlags(ClassReader.SKIP_FRAMES) - .classWriterFlags(ClassWriter.COMPUTE_FRAMES) - .build() - .start(); + public static void main(String[] args) { + Deobfuscator.from( + DeobfuscatorOptions.builder() + .inputJar(Path.of("work", "obf-test.jar")) + .virtualMachine( + new VirtualMachine() { + // you can do shit + }) + .transformers( + // Pick your transformers here + () -> new ComposedGeneralFlowTransformer() + ) + .consoleDebug() + .suppressErrors() + .classReaderFlags(ClassReader.SKIP_FRAMES) + .classWriterFlags(ClassWriter.COMPUTE_FRAMES) + .build() + ).start(); } } diff --git a/deobfuscator-impl/src/test/java/uwu/narumii/deobfuscator/base/TestDeobfuscationBase.java b/deobfuscator-impl/src/test/java/uwu/narumii/deobfuscator/base/TestDeobfuscationBase.java index 89ba3f69..57617161 100644 --- a/deobfuscator-impl/src/test/java/uwu/narumii/deobfuscator/base/TestDeobfuscationBase.java +++ b/deobfuscator-impl/src/test/java/uwu/narumii/deobfuscator/base/TestDeobfuscationBase.java @@ -15,6 +15,7 @@ import org.opentest4j.TestAbortedException; import uwu.narumi.deobfuscator.Deobfuscator; import uwu.narumi.deobfuscator.api.asm.ClassWrapper; +import uwu.narumi.deobfuscator.api.context.DeobfuscatorOptions; import uwu.narumi.deobfuscator.api.helper.FileHelper; import uwu.narumi.deobfuscator.api.transformer.Transformer; @@ -85,7 +86,7 @@ public DynamicTest buildTest() { */ private void runTest() { // Setup builder - Deobfuscator.Builder deobfuscatorBuilder = Deobfuscator.builder() + DeobfuscatorOptions.Builder optionsBuilder = DeobfuscatorOptions.builder() .transformers(this.transformers.toArray(new Supplier[0])); Path inputDir = null; @@ -103,7 +104,7 @@ private void runTest() { // Add jar input Path inputJarPath = COMPILED_CLASSES_PATH.resolve(relativePath); - deobfuscatorBuilder.inputJar(inputJarPath); + optionsBuilder.inputJar(inputJarPath); inputDir = DEOBFUSCATED_CLASSES_PATH.resolve(relativePath); } else { @@ -114,23 +115,17 @@ private void runTest() { } // Add class - deobfuscatorBuilder.clazz(compiledClassPath, sourceName); + optionsBuilder.clazz(compiledClassPath, sourceName); } } - Deobfuscator deobfuscator; - try { - // Build deobfuscator - deobfuscator = deobfuscatorBuilder - .outputJar(null) - .outputDir(DEOBFUSCATED_CLASSES_PATH.resolve(this.inputType.directory())) - .build(); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } + // Last configurations + optionsBuilder + .outputJar(null) + .outputDir(DEOBFUSCATED_CLASSES_PATH.resolve(this.inputType.directory())); - // Run deobfuscator! - deobfuscator.start(); + // Build and run deobfuscator! + Deobfuscator.from(optionsBuilder.build()).start(); // Init context sources List contextSources = new ArrayList<>(); diff --git a/testData/results/java/TestUniversalNumberTransformer.dec b/testData/results/java/TestUniversalNumberTransformer.dec index 64cb9c4d..ed745598 100644 --- a/testData/results/java/TestUniversalNumberTransformer.dec +++ b/testData/results/java/TestUniversalNumberTransformer.dec @@ -14,4 +14,26 @@ public class TestUniversalNumberTransformer { System.out.println(b); } } + + public void numberCasts() { + long temp1 = 3458347593845798359L; + int a = 1090614743; + long temp2 = 6873457893573587384L; + float b = 6.873458E18F; + double temp3 = 23423.32412121212; + float c = 23423.324F; + } + + public void methodCallsOnLiterals() { + int a = 12; + int b = -1408655867; + int c = 123; + int d = 10; + int e = 28311552; + long f = 5413326752099336192L; + int g = 1123434234; + float h = 1.72E-43F; + long i = 4638364436490267302L; + double j = 6.0831E-319; + } } diff --git a/testData/src/java/src/main/java/TestUniversalNumberTransformer.java b/testData/src/java/src/main/java/TestUniversalNumberTransformer.java index 654bc9a9..b76424d0 100644 --- a/testData/src/java/src/main/java/TestUniversalNumberTransformer.java +++ b/testData/src/java/src/main/java/TestUniversalNumberTransformer.java @@ -16,4 +16,28 @@ public void divideByZero() { System.out.println(b); } } + + public void numberCasts() { + long temp1 = 3458347593845798359L; + int a = (int) temp1; + long temp2 = 6873457893573587384L; + float b = (float) temp2; + double temp3 = 23423.3241212121212125433534534523423464523423454567568354345354354354354345345354534534534345345534389467459867498679845687459867984576894589679845689458969847545343543544d; + float c = (float) temp3; + } + + public void methodCallsOnLiterals() { + int a = "dfgdfgdfgdfg".length(); + int b = "asddsf".hashCode(); + int c = Integer.parseInt("123"); + int d = Integer.parseInt("1010", 2); + int e = Integer.reverse(3456); + long f = Long.reverse(1234L); + + int g = Float.floatToIntBits(123.123f); + float h = Float.intBitsToFloat(123); + + long i = Double.doubleToLongBits(123.123123123d); + double j = Double.longBitsToDouble(123123L); + } }