This is an all-in-one Java deobfuscator which will deobfuscate code obfuscated by most obfuscators available on the market.
The deobfuscator supports deobfuscation of transformations such as string literal encryption, or reflection obfuscation. These transformations have been hard coded for a specific obfuscator, but generic deobfuscators are also available.
Things like method names, class names, etc cannot be deobfuscated because their renaming is irreversible. The information needed to deobfuscate is removed.
Check out this guide
public class SomeRandomDeobfuscator {
public static void main(String[] args) throws Throwable {
Configuration config = new Configuration();
config.setInput(new File("input.jar"));
config.setOutput(new File("output.jar"));
config.setPath(Arrays.asList(
new File("C:\\Program Files\\Java\\jdk_8\\jre\\lib\\rt.jar"),
new File("C:\\Program Files\\Java\\jdk_8\\jre\\lib\\jce.jar"),
new File("C:\\Program Files\\Java\\jdk_8\\jre\\lib\\ext\\jfxrt.jar"),
new File("C:\\Program Files\\Java\\jdk_8\\lib\\tools.jar")
));
config.setTransformers(Arrays.asList(
TransformerConfig.configFor(PeepholeOptimizer.class)
));
new Deobfuscator(config).start();
}
}
If you don't want to import the project, you can always use the command line interface.
Argument | Description |
---|---|
--config | The configuration file |
You may specify multiple transformers, and they will be applied in the order given. Order does matter as sometimes one transformation depends on another not being present.
If you wish to use one of the default transformers, then you may remove the com.javadeobfuscator.deobfuscator.transformers
prefix.
Here is a sample config.yaml
:
input: input.jar
output: output.jar
transformers:
- normalizer.MethodNormalizer:
mapping-file: normalizer.txt
- stringer.StringEncryptionTransformer
- normalizer.ClassNormalizer: {}
normalizer.FieldNormalizer: {}
For more details, please take a look at the wiki.
Official transformers are linked via the Transformers
class.
Transformer | Canonical Name | Description |
---|---|---|
Allatori.STRING_ENCRYPTION | allatori.StringEncryptionTransformer | Decrypts strings encrypted by Allatori |
DashO.STRING_ENCRYPTION | dasho.StringEncryptionTransformer | Decrypts strings encrypted by DashO |
SkidSuite.STRING_ENCRYPTION | skidsuite2.StringEncryptionTransformer | Decrypts strings encrypted by SkidSuite2 |
SkidSuite.FAKE_EXCEPTION | skidsuite2.FakeExceptionTransformer | Remove fake exceptions by SkidSuite2 |
Stringer.STRING_ENCRYPTION | stringer.StringEncryptionTransformer | Decrypts strings encrypted by Stringer |
Stringer.INVOKEDYNAMIC | stringer.InvokedynamicTransformer | Decrypts invokedynamic obfuscated calls by Stringer (Below version 3.0.0) |
Stringer.REFLECTION_OBFUSCATION | stringer.ReflectionObfuscationTransformer | Decrypts reflection obfuscated calls by Stringer (Below version 3.0.0) |
Stringer.HIDEACCESS_OBFUSCATION | stringer.HideAccessObfuscationTransformer | Decrypts hide access by Stringer (Included invokedynamic and reflection) |
Stringer.RESOURCE_ENCRYPTION | stringer.ResourceEncryptionTransformer | Decrypts encrypted resources by Stringer |
Zelix.STRING_ENCRYPTION | zelix.StringEncryptionTransformer | Decrypts strings encrypted by Zelix |
Zelix.REFLECTION_OBFUSCATION | zelix.ReflectionObfuscationTransformer | Decrypts reflection obfuscated calls by Zelix |
Zelix.FLOW_OBFUSCATION | zelix.FlowObfuscationTransformer | Removes flow obfuscation by Zelix |
Smoke.STRING_ENCRYPTION | smoke.StringEncryptionTransformer | Removes string encryption by Smoke |
Smoke.NUMBER_OBFUSCATION | smoke.NumberObfuscationTransformer | Removes number obfuscation by Smoke |
Smoke.ILLEGAL_VARIABLE | smoke.IllegalVariableTransformer | Removes illegal variables by Smoke |
General.PEEPHOLE_OPTIMIZER | general.peephole.PeepholeOptimizer | Optimizes the code |
General.Removers.SYNTHETIC_BRIDGE | general.remover.SyntheticBridgeRemover | Removes synthetic and bridge modifiers from all methods and fields |
General.Removers.LINE_NUMBER | general.remover.LineNumberRemover | Removes line number metadata |
General.Removers.ILLEGAL_VARARGS | general.remover.IllegalVarargsRemover | Unmangles methods marked as variadic but aren't really |
General.Removers.ILLEGAL_SIGNATURE | general.remover.IllegalSignatureRemover | Removes illegal signatures from members |
General.Removers.LOCAL_VARIABLE | general.remover.LocalVariableRemover | Removes local variables from methods |
Normalizer.CLASS_NORMALIZER | normalizer.ClassNormalizer | Renames all classes to Class |
Normalizer.METHOD_NORMALIZER | normalizer.MethodNormalizer | Renames all methods to Method |
Normalizer.FIELD_NORMALIZER | normalizer.FieldNormalizer | Renames all fields to Field |
Normalizer.PACKAGE_NORMALIZER | normalizer.PackageNormalizer | Renames all packages to Package |
Normalizer.SOURCEFILE_CLASS_NORMALIZER | normalizer.SourceFileClassNormalizer | Recovers SourceFile attributes when possible |
Normalizer.DUPLICATE_RENAMER | normalizer.DuplicateRenamer | Renames all classes, methods, and fields with name clashes |
The latest build can be downloaded from my CI Server
Zelix Klassmaster
Stringer
Allatori
DashO
DexGuard
Smoke
SkidSuite2 (dead, some forks are listed here)
Generic obfuscation
You need to specify all the JARs that the input file references. You'll almost always need to add rt.jar
(which contains all the classes used by the Java Runtime)
Increase your stack size. For example, java -Xss128m -jar deobfuscator.jar
Technically, yes, you could use something like dex2jar or enjarify, but try simplify first. It's a deobfuscator of sorts built specifically for Android.
Java Deobfuscator is licensed under the Apache 2.0 license.