Aidsfuscator is a java bytecode obfuscator that aims to become one of, if not the best free obfuscators.
Join the discord server!
- Trimming
- Name obfuscation (optional aggressive overloading!)
- Control Flow Flattening
- Control Flow Shuffling
- LocalVariableTable clearing
- LineNumberTable mutation
- Method salting
- Class salting
- Integer encryption
- String Encryption (with anti-tamper + concatenation obfuscation)
- Reference obfuscation (fields and methods)
- Custom dictionary support
- Fat JAR support
- CLI
- Config system
- Exclusion system with annotations
- Exclusion preset system
- Automatic
fabric.mod.jsonhandling - Annotations API
Over these 2 years of me working with Java bytecode, I noticed that there's not many good free Java bytecode obfuscator options out there, so I decided to make one myself. It is also a passion project.
I made a poll on Aidsfuscators/Cryptics discord server, asking if anyone wanted me to rewrite the v1 aidsfuscator. The majority said yes, so that's what makes me want to do this project.
- Download the zip file from the releases page.
- Extract the ZIP file
- Your config.json and exclusions.json files should stay in your workspace folder, everything else can stay outside.
- Run the obfuscator with Java 25:
java -jar aidsfuscator.jar --config=config.json --exclusions=exclusions.json
aidsfuscator.jar
workspace
|- aidsfuscator-api.jar
|- config.json
|- initOrder.java
|- references.json
\- exclusions.json
- Do not run it with
java -jar aidsfuscator --config=workspace/config.json --exclusions=workspace/exclusions.json. Aidsfuscator automatically prefixesworkspace/before any workspace item, that isn't the libs folder or input file.
Starting from v2.9.0, Aidsfuscator now has an API JAR file with a few annotations. This JAR can be added to your projects dependencies and you can annotate methods, fields and classes with these annotations to exclude them from obfuscation. These annotations get removed in the Aidsfuscators post-processor.
You can add exclusions and inclusions with the follow format in the exclusions file:
{
"token": {
"class": [
"example/Exclusion",
"!example/Inclusion"
],
"field": [
"example/Exclusion.excludedMethod Ljava/lang/String;",
"!example/Inclusions.includedMethod Ljava/lang/String;"
],
"method": [
"example/Exclusion.excludedMethod(IJZBDFSCLjava/lang/String;)V",
"!example/Inclusion.includedMethod(IJZBDFSCLjava/lang/String;)V"
],
"annotation": [
"example/ExampleAnnotation"
]
}
}Replace token with any of these:
global(Excludes a class globally from all obfuscation. Applies to classes only)renameClass(Excludes a class from being renamed. Applies to classes only)renameField(Excludes a field from being renamed. Applies to classes and fields)renameMethod(Excludes a method from being renamed. Applies to classes and methods)localNames(Excludes LVT (Local Variable Table) from getting its names cleared. Applies to classes and methods)lineNumbers(Excludes LNT (Line Number Table) from getting obfuscated. Applies to classes and methods)trim(Excludes trimming of a specific member. Applies to classes, fields and methods)methodSalting(Excludes a method from being salted. Applies to classes and methods)classSalting(Excludes a class from being salted. Applies to classes only)referenceObfuscate(Excludes a method from getting references obfuscated in it. Applies to classes and methods)fixConstants(Excludes a field from getting its value moved to the static initializer. Applies to classes and fields)integerEncrypt(Excludes a class or method from getting its integer values encrypted. Applies to classes and methods)stringEncrypt(Excludes a class or method from getting its string literals encrypted. Applies to classes and methods)controlFlowFlatten(Excludes a method from getting its control flow flattened into a switch. Applies to classes and methods)controlFlowShuffle(Excludes a method from getting its control flow shuffled. Applies to classes and methods)
If you wanted to exclude every method with the name "test" and with any parameters with return type void from getting Control Flow Flattening and Integer Encryption applied to it, your exclusion file would look like this:
{
"controlFlowFlatten": {
"method": [
"*.test(*)V"
]
},
"integerEncrypt": {
"method": [
"*.test(*)V"
]
}
}Class Initialization Order allows you to strengthen class salts by specifying pairs of classes that execute in order. The initOrder.json file is a JSON array of JSON arrays,
but you have to add only two classes in the second array. For example:
If you are sure that pkg.Class2 first gets initialized by pkg.Class1 and you add it to the file, your file should look like this:
[
["pkg.Class1", "pkg.Class2"]
]You can add multiple of these class pairs and you can chain them, but you have to be certain that the order is true, otherwise wrong values may get outputted.
Reference Obfuscation Inclusions is a file that specifies reference obfuscation candidates. It uses the same matching system as in exclusions. Examples:
- Any method called
testin any class with any parameters with any return type
*.test(*)* - Any method called
testin any class with NO parameters withvoidreturn type
*.test()V - Any method called
testin classpkg.TestClasswith first parameterlongwithjava.lang.Stringreturn type
pkg/TestClass.test(J*)Ljava/lang/String; - Any method called
testin any class that ends withsubpkg.TestClasswith last parameterbooleanwithintreturn type
*/subpkg/TestClass.test(*Z)I - Any method called
testin any class that's under a package calledpkgwith any parameters and return value (shortened)
*/pkg/*.test(*
- Any field called
testin any class with any return type
*.test * - Any field called
testin any class withbooleanreturn type
*.test Z - Any field called
testin classpkg.TestClasswithjava.lang.Stringreturn type
pkg/TestClass.test Ljava/lang/String; - Any field called
testin any class that ends withsubpkg.TestClasswithintreturn type
*/subpkg/TestClass.test I - Any field called
testin any class that's under a package calledpkgwith any return value
*/pkg/*.test *
Keep in mind: for fields, separate return type from name with a space.