• Main page
  • Login
Not logged in

Documentation Content

Please keep in mind that the documentation isn't complete and hasn't passed any spell-check yet!
  1. Documentation content
  2. Quick setup
  3. Name obfuscation
  4. String encryption
  5. Watermarking
  6. Annotations
  7. Config file format
  8. Build system integration

Quick setup

Before obfuscating, be sure that the smoke.license file is in the same folder as the Smoke.jar and the SmokeGUI.jar are.
If so, you can launch GUI by double-clicking it, if it doesn't work, try to type
java -jar SmokeGUI.jar
in the command line. If this try failed to, please report any further bugs or issues to the us.

When the GUI launched, you just have to follow these few steps:

  1. Choose the input and output file with the "..."-Buttons.
  2. Next, you can configure your obfuscation settings. There are more detailed descriptions about each obfuscation technique / feature below.
  3. Now, press the obfuscate-button, your application is going to be obfuscated and saved to the choosen location.
  4. If you are obfuscating a huge project which needs to be obfuscated, consider using the command line due the GUI slows Smoke tremendously. An example how to use the command line would look like this:
    java -Dfile.encoding=UTF8 -jar Smoke.jar config.smoke
Obfuscation Explanation Effectiveness Performance
String encryption The String encryption encrypts strings so you can't use string search anymore. Good - High Depends on the method
Flow obfuscation The flow obfuscation changes the programm flow without changing the function of the code resulting in highly unreadable code. Good - High Highly depends on the mode
Number obfuscation The number obfuscation replaces integers with some simple addition which has a great impact on readability. Good Mediocre
Name obfuscation The name obfuscation renames classes, method, and field so their names have no sense. Various None
Crasher Crashes FernFlower, CFR, and Krakatau. Very high Low
Method hider Hides method, effective for JD-GUI, Procyon and sometimes FernFlower / CFR. Good None
Tamper protection Terminates your program once a manipulations has been detected Good Low
InvokeDynamics Replaces method-invokes with dynamic ones. Recommended for license or high priority code. High Firstly bad, none afterwards
Trash classes Generates trash classes to hide the important ones. Mediocre None
Packager Encapsulates the bytecode in a very special way, unstable :( Depends Bad at startup, None afterwards


The name obfuscation (or first generation obfuscation) renames every class member and the class itself so the names make no sense. Also, Smoke utilises some characters indiscernible by the human eye (and also crashing ProCyon).


In most cases you just need to enable the name-obfuscation and add all dependencies so the algorithms are able to generate the method names correctly. If not so, please report it as bug.


Under the exclusions tab, you can highly configure what should be renamed and what not:

Exclusion Function
KeepClassName Don't rename the class but it's members.
KeepCompleteClass Don't rename the class and it's members.
KeepMethod Don't rename a method, syntax: className.methodName
KeepField Don't rename a field, syntax: className.fieldName
KeepPackage Keep the package name, but rename the classes within it.
KeepEnum Automatically keep the fields and the value-function on enums. This may be needed to keep compatible to config files.

Reflection handling

The name obfuscation can handle simple reflection calls, so they will continue working without exclusion. Following patterns will be detected and modified:

Class myClass = Class.forName("myClass");
(Some eventual code)
Method myMethod = myClass.getMethod("main", String[].class);

String encryption

Encrypting string is an essentials feature when it comes to advanced obfuscation. It denys hackers to find important
parts of your code by searching for strings. Further, code with encrypted strings is way harder to read than code with
plain strings since these strings often are used to gain orientation. Smoke provides you with four different string
encryptions, each using a different method to encrypt and store the strings.

Method Description
Normal The normal string encryption simple calls a decryption method once a string is used. To improve performance, decrypted strings are cached.
String-Pools The string pool encryption creates classes containing a lot of strings. Once a string is needed, it will call the string pool with the index of the string.
Heavy The heavy string encryption uses several techniques to exploit or evade automatic decompilers. Further, it uses the current symmetric encryption standard, AES, to provide maximum security.
Flow Instead of actively encrypting, the flow string encryption tries to assemble the string within the method itself. While this method is way ultimately bypasses decryption tools, it sadly runs into problems with big methods.

If you need to exclude a string from the encryption, feel free to use the keepString-Option.


Imagine the scenario that someone leaks your software which would have made you the richest man in the world, and you don't even know who did it because he used a fake name on the leaking page!

Smoke offers a solution for exactly this scenario with it's watermarking techniques which can hide any message in a way that prevent the message be show by any decompiler. Additionally, these messages are encrypted. To inject a message into the output, you just need to set a message and a encryption key under the advanced tab in the gui and be able to obfuscate your product for every customer. We will publish some snippets in different languages to integrate automated watermarking into your delivery workflow soon.

To extract the watermark from a leaked jar, just use the "Extract Watermark"-Button under the advanced tab in the GUI or if you want to use the command line interface:
java -jar Smoke.jar extract <Leaked Jar> <Encryption key>

Pro-Tip: If you load the obfuscation config before clicking the "Extract Watermark"-Button, you don't have to type the encryption key again.


Smoke allows your to configure you program with annotations. To do so, just add the Smoke-Annotations.jar to your dependencies / build path within your IDE and start using them. This annotations will be removed during obfuscation.


Can be applied to: classes, methods, fields
This annotation denies the name obfuscation to rename this method and is equal to the keepclass / keepmethod / keepfield option as described within the name obfuscation section.


Can be applied to: classes
This annotation denies the name obfuscation to rename any member of the class and the class itself, it can be treated as the keepcomplete option of the name obfuscation.

@SmokeConfig ( { "property1", "value1", "property2", "value2" } )

Can be applied to: classes, methods, fields
This annotation adds the given properties to the config, it's that simple :D

The config file format

Smoke's config format is designed to provide maximum flexibility while being easy to understand and intuitive to handle.
To achieve these goals, the configs are based on entry's which follow following syntax:
-{Range} {Property} {Value}
The range is a regex defining the classes being affected by this entry. For example, the regex "license.*" would
fit all classes within the "license" package. To pick every class, simple use "*" as range. The star specifies that any
combination of any character, "?" can be used for any character.
Once you have understood the range idea, you effectively won't have learn anything more about the config format since
the "Class specific"-page of the GUI will insert the correct property and value for you. (They should be self-explaining anyway :))


Don't rename the class "myprogram.Main":
-myprogram.Main keepClassName on

Don't rename every class within the package "org.apache":
-org.apache.* keepClassName on

Use the normal string encryption except for the package "license" which uses the heavy one:
-* stringEncryption normal
-license.* stringEncryption heavy

Build system integration

Though it's command-line-interface, Smoke can be executed in almost every build system. Here are some example configurations. This list will grow in future since some native build system integrations are currently reaching the top of the todo-list :D