Skip to content

apython123/Radon

Repository files navigation

Radon Java Obfuscator Build Status

Yet another Java obfuscator. If I forgot to credit you, just make a pull-request or open an issue.

Licenses get to go with the manifest in src/META-INF (yay!)

Usage: java -jar Radon.jar --config exampleconfig.yml

Alternatively, you can also use java -jar Radon.jar --help for help.

Example config:

Input: "C:/Users/Buddy/Desktop/RadonOBF/Counter.jar"Output: "C:/Users/Buddy/Desktop/Counter-OBF.jar"StringEncryption: NormalInvokeDynamic: HeavyFlowObfuscation: NormalLocalVariableObfuscation: RemoveLineNumberObfuscation: RemoveSourceNameObfuscation: RemoveSourceDebugObfuscation: RemoveHideCode: TrueCrasher: TrueShuffler: TrueInnerClassRemover: TrueStringPool: TrueNumberObfuscation: TrueTrashClasses: 50Renamer: TrueWatermarkType: ConstantPoolWatermarkMessage: ItzSomebodyWatermarkKey: PASSWORDExpiryTime: 5/25/2018ExpiryMessage: "YOUR SOFTWARE TRIAL HAS ENDED!!! YOU MUST NOW PAY $100000000 FOR THE FULL VERSION LULZ"Libraries: - "C:/Program Files/Java/jre1.8.0_xxx/lib/rt.jar"Exempts: - "Class: org/objectweb/asm/*" - "StringPool: me/itzsomebody/counter/Counter$1" - "InvokeDynamic: me/itzsomebody/counter/Counter" - "Renamer: me/itzsomebody/counter/Counter$1" - "Renamer: me/itzsomebody/counter/Counter.process(*"

Valid config options you can use:

OptionExpected Value(s)Desc
InputStringInput file to obfuscate
OutputStringOutput file to dump result of obfuscation
LibrariesString ListLibraries used to compile the input
ExemptsString ListExempted classes, methods, or fields from obfuscation
StringEncryptionString (SuperLight/Light/Normal/Heavy)Type of string encryption to apply
FlowObfuscationString (Light/Normal)Type of flow obfuscation to apply
InvokeDynamicString (Light/Normal/Heavy)Type of invokedynamic obfuscation to apply
LocalVariableObfuscationString (Obfuscate/Remove)Type of local variable obfuscation to apply
CrasherBooleanDetermines if the decompiler crasher should be applied
HideCodeBooleanDetermines if synthetic modifiers should be applied
StringPoolBooleanDetermines if strings should be pooled
LineNumberObfuscationString (Obfuscate/Remove)Type of line number obfuscation to apply
NumberObfuscationBooleanDetermines if integers should be split into simple math expressions
SourceNameObfuscationString (Obfuscate/Remove)Type of source name obfuscation to apply
SourceDebugObfuscationString (Obfuscate/Remove)Type of source debug obfuscation to apply
TrashClassesIntegerNumber of trash classes to generate
WatermarkMessageStringMessage to watermark into the output
WatermarkTypeString (ConstantPool/Signature)Type of watermark to apply
WatermarkKeyStringKey used to encrypt watermarks
SpigotPluginStringDetermines if input should be treated as a spigot/bungee plugin
RenamerBooleanDetermines if obfuscator should rename classes and methods
ShufflerBooleanDetermines if obfuscator should re-arrange class members
InnerClassRemoverBooleanDetermines if obfuscator should remove inner-class information
ExpiryTimeStringMessage to insert for expiry obfuscation (useful for trialware)
ExpiryMessageStringMessage to show when set your trialware goes past expiration date (rip)
DictionaryIntegerType of string generation to use in obfuscation.

Dictionary types

Valid dictionary types you can use:

OptionDescription
0(Default) Generates a string containing 10 characters composed entirely out of space-like characters.
1Generates a string containing 10 characters unrecognized by the JVM causing them to show as white-boxes.
2Generates an alpha-numeric string of length 4.

Exempting

The character '*' can be used as a wildcard for "anything which starts with before this". So "me/itzsomebody/*" will match "me/itzsomebody/ExampleClass1", "me/itzsomebody/example/ExampleClass2". This also works on method matching, "me/itzsomebody/example/Example.exampleMethod(*" will match any method which has the name "exampleMethod" in "me/itzsomebody/example/Example".

Valid exempt types you can use:

OptionExpected Value(s)Desc
ClassFully qualified name of internal class name (i.e. me/itzsomebody/counter/Counter)Exempts entire classes from obfuscation.
MethodFully qualified name of internal owner name + '.' + internal method name + internal method descriptor (i.e. me/itzsomebody/counter/Counter.exampleMethod()V)Exempts entire method from obfuscation.
FieldFully qualified name of internal owner name + '.' + internal field nameExempts field from obfuscation.
StringEncryptionFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from string encryption.
InvokeDynamicFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from invokedynamic obfuscation.
FlowFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from flow control obfuscation.
LocalVarsFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from local variable obfuscation.
SourceNameFully qualified internal name (i.e. me/itzsomebody/counter/Counter)Exempts class source from name obfuscation.
SourceDebugFully qualified internal name (i.e. me/itzsomebody/counter/Counter)Exempts class source from debug obfuscation.
LineNumbersFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from line number obfuscation.
StringPoolFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method from string pooling.
CrasherFully qualified internal name (i.e. me/itzsomebody/counter/Counter)Exempts class from being added an invalid class signature.
HideCodeFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter.exampleField or )Exempts class, method or field from hide code obfuscation.
NumbersFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter)Exempts class or method number obfuscation.
ShufflerFully qualified internal name (i.e. me/itzsomebody/counter/Counter)Exempts class from member shuffling.
InnerClassesFully qualified internal name (i.e. me/itzsomebody/counter/Counter)Exempts class from inner-class information removal.
RenamerFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter.exampleField or )Exempts class, method or field from renaming.
ExpiryFully qualified internal name (member name must be seperated from owner by a '.') (i.e. me/itzsomebody/counter/Counter.exampleMethod()V or me/itzsomebody/counter/Counter.exampleField or )Exempts class, method or field from expiration.

Obfuscation description

This table describes the current obfuscation settings Radon has.

Obfuscation TypeDescription
StringEncryptionThis takes the strings in your program and encrypts them. Each of the current settings are symmetrical and will NOT prevent reverse-engineers from figuring out what your program does. The super light setting uses an extremely simple xor algorithm and is not secure. The light setting uses a simple algorithm which encrypts the strings for speed. There is minimal flow obfuscation in the light setting so be aware this offers minimal protection. The normal string encryption setting is basically a flow-obfuscated version of the light string encryption, it is intended to make the decryption method more confusing. The heavy method uses AES to encrypt the strings.
FlowObfuscationThis attempts to confuse the program flow to make the decompiled code harder to understand. The light setting replaces all gotos in the program with conditionals which always evaluate to true. The light setting usually doesn't affect decompiler results by much unless you have methods with some certain flow control situations. The normal flow obfuscation attempts to find places in the bytecode where the stack is empty. It uses an injected predicate which is used to make false jumps and add some extra throw-nulls in random places.
InvokeDynamicThis abuses Java 7's new opcode, the invokedynamic. This replaces certain member access with dynamic invocations. The light invokedynamic transformer is very simple and replaces invokestatic, invokevirtual and invokeinterface with invokedynamics. This is easily reversed by experienced reverse-engineers so don't rely on this. The normal invokedynamic protection is a very slight improvement to the light settings, but still is easy to reverse. The heavy invokedynamic hides invokestatic, invokevirtual, getstatic, putstatic, getfield and putfield opcodes with invokedynamics.
LocalVariableObfuscationThis attempts to prevent local variable analysis. The obfuscation setting changes the names of the local variables to hard-to-read UTF-8 characters. The remove setting removes the local variable information completely destroying the ability to recover the local variable names. Removal setting tends to shrink jar size since it removes information in the code.
CrasherThis adds an invalid signature to classes. The intention of this transformer is to crash a majority of decompiles which attempt to take class signatures into account of the output. This crashes JD-GUI, Procyon, CFR and Javap.
HideCodeThis adds certain access flag modifiers to members of your code. Synthetic modifiers are added to classes, methods and fields and bridge modifiers are added to methods which aren't initializer methods (<init> and <clinit>).
StringPoolThis adds a method into the class which takes all the strings in the class and pools them into the added method.
LineNumberObfuscationThis attempts to obscure stacktrace output by changing line number debug information. The obfuscation setting sets line numbers to random ones. The removal setting removes them from your code entirely. The removal setting also shrinks the size of the jar.
NumberObfuscationThis splits integers into a xor expression making it difficult to determine what number is being used. This is defeated by Krakatau.
SourceNameObfuscationThis attempts to obscure stacktrace output by removing sourcefile debug information. The obfuscation setting sets all the source file names to random ones. The removal setting removes them entirely from your code. The removal setting also shrinks the size of the jar.
SourceDebugObfuscationThis attempts to obscure source debug information. The obfuscation setting sets all the source debug values to random ones. The removal setting removes them entirely from your code. The removal setting also shrinks the size of the jar.
TrashClassesThis generates garbage classes which aren't used to attempt to hide the ones that are actually used. This also prevents JByteEdit usage.
WatermarkThis marks a message into the classes which is intended for customer-identification. The constant pool option marks the message into the constant pool of each class. The signature option marks the messages into the class signature.
RenamerThis renames classes, methods and fields from their original names to random UTF-8 strings.
ShufflerThis simply changes the order of class members (methods and fields).
InnerClassRemoverThis removes innerclass information.
ExpirationObfuscationThis adds a block of expiration code into each class initializer to prevent usage of jar after the expiration date has passed.

Credits

  • OW2 ASM - ObjectWeb ASM.
  • SnakeYaml - SnameYAML.
  • VincBreaker - Author of Smoke obfuscator which I took some ideas from. (i.e. Renaming classes as spaces and splitting numbers into bitwise xor operations)
  • WindowBuilder by Eclipse - Used to make GUI (yes I know it's Java Swing, I didn't feel like remaking it in JavaFX)
  • Licel - Makers of IndyProtect.
  • Allatori Dev Team - Makers of Allatori Java Obfuscator.
  • Artel - Beta tester.

License

GNU General Public License v3.0

About

Radon Java Obfuscator

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java100.0%