The Obfuscation Process for Autohotkey Scripts

The best way to approach the Autohotkey obfuscation process is to start simple by doing the least obfuscation of your code possible and then testing that output until it is bug free.


They are provided in '@Example-obfuscated-programs' folder of the Obfuscator files.


First of all you should format your #includes statements and prepare your IncludeMAP text file listing the ahk files to be obfuscated.

Then you should start Preparing Your Autohotkey Source Code for Straight Obfuscation.

You should start out with only straight obfuscation and do not enter any commands to obfuscate variables, properties, system functions, etc.

Try obfuscating for the first time following the Testing Process and leaving all the check-boxes UNchecked.

If the output code works correctly then check the first 2 check-boxes on the Obfuscator user interface to strip all whitespace and to randomize your code sections.

If that works correctly then you can start the Dynamic Obfuscation process:

First implement Dynamic Obfuscation with no secure classes and no custom scrambling palette.
Convert slowly your important functions to assume-global mode until the non-obfuscated version then the obfuscated version are working fine.

Now start inserting comment commands to tell the Obfuscator to obfuscate your variables and objects, part variables, and properties and methods. Add commands to specify the obfuscation of Autohotkey built in functions and variables. Follow the steps to hide sensitive strings and obfuscate more, obfuscate all!


The last thing you may want to do is to start create secure classes that can be broken. Secure classes require their own sequence of DUMP commands for Secure Classes so you will have to learn those.
Optionally you can adding code sections to non-secure classes as well to define a custom scrambling palette.

Finally you can rewire functions to go to other functions.



Testing Process

First Create the TransMAP which will show all found functions, labels, classes, context conditions and Obfuscator commands.
Then Run the Obfuscate Function.
Finally run the obfuscated Ahk output file.
If errors are found, check out debugging and known problems.

If you have a sudden problem with the obfuscated output code, try turning off things in the Obfuscator interface and re-running obfuscation. If you have a problem and want to look at the obfuscated source code directly, leave the code unscrambled and with the comments left in to make debugging easier.

Run the Create Translations Map Function

Choose 'Create Translations Map' from the main Obfuscator window and then indicate your source code includes map file and your output translations map file. In most cases you should run this function before you run the obfuscate function. The only exception is when you have not changed your source code but instead you are just going to alter some of the Obfuscator run options, like 'remove all whitespace and comments'.

Run the Obfuscate Function

Select the 'Obfuscate Source Code' function on the main Obfuscator window. Indicate your source code includes map file, your translations map file path created from the step above this one, and your output obfuscated file name. Check or uncheck the obfuscation run options and submit. A box will pop up giving you various statistics regarding the source code it is obfuscating like the number of each object type found and classes found. Just before the new obfuscated code file is written, a dialog box will pop up telling you the size of that file.


Prepare Your Autohotkey Source Code

This relates to "OBFUSCATION PREPARATION AND RULES" Section in User Manual
You must format your function sections and your label sections according to some simple rules.

You put Obfuscator command comments in your source code to signal various stuff to the Obfuscator.

There is only one mandatory Obfuscator command comment that is required in your source code file, the END AUTOEXECUTE command:
If you are using '#include file' statements in your program, you must do a couple of special steps.

If you use the autohotkey 'gui, +LabelPrefix' Command, some special steps are necessary.

If you are using Dynamic Obfuscation instead of Straight Obfuscation then you will have to use the Obfuscator DUMP commands to initialize the Dynamic Obfuscation Variable Fragments.


Your functions, parameters, and labels are automatically found and obfuscated by this program.
BUT Variables including global, static, and local are not automatically obfuscated. Put Obfuscator command comments in your source code in order to obfuscate your variables and objects, part variables, and properties and methods.

In order to obfuscate autohotkey system functions and variables, put obfuscater commands comments in your source code.

In order to hide sensitive strings in your code a couple of steps must be followed


Straight Obfuscation Steps

Obfuscation mode

The in-built defaults in this program are set to do dynamic obfuscation.
Therefore, to use only straight mode you have to put this command at the very beginning of your auto-execute section:

Obfuscation limitations

Straight obfuscation does not allow you to obfuscate: (not yet) properties and methods, nor autohotkey built in functions and variables.
Also, Straight obfuscation does not allow you to create secure classes that can be broken nor rewire functions to go to other functions.

All the other features work with straight obfuscation and you can still obfuscate functions, labels, variables, etc..
But remember : the straight obfuscation is much less secure than dynamic obfuscation !
The only "%"s added will be empty vars. Therefore calls and used variables can still be found ... with not so many difficulties (although the names will be the Obfuscator replacements). Moreover Autohotkey functions will be barely obfuscated (just some empty "%"s) as no obfuscation replacement name is used.

[DigiDon] Dynamic Obfuscation has been made much easier to implement partially, so you should try it quickly.


Dynamic Obfuscation Steps

Obfuscation mode

The in-built defaults in this program are set to do dynamic obfuscation. Therefore to activate dynamic obfuscation, no specific Obfuscation command to be added unless straight mode was activated.
In this case, either delete all ;$OBFUSCATOR: $STRAIGHT_MODE: commands or use
when you want to resume dynamic obfuscation.
However there are a few mandatory steps and things to know :
First, some DUMP commands are mandatory once you start using Dynamic Obfuscation.
You must implement MANDATORY DUMPS COMMANDS for dynamic obfuscation.


Dynamic Obfuscation can only be performed with assume-global functions.
SEE OFFICIAL AUTOHOTKEY DOCUMENTATION about assume-global mode and variables.
You can still use local and static variables in assume-global functions, but you will have to specify them in a LOCAL or STATIC statement within the function.
[DigiDon] All functions that do not assume-global will automatically use straight obfuscation even if dynamic obfuscation was used.
Indeed if the functions do not assume-global and dynamic obfuscation would still be used, then the value of these fragments would not be accessible within your functions and all of them would return null and the object name would not be created correctly and would result in an invalid reference. Therefore it is recommended to start transforming most of your sensitive functions in assume-global mode to test your non-obfuscated script, making sure it is bug- and conflict-free and then trying to obfuscate it again. Then slowly adding some more assume-global functions.


You use DUMP commands for each of the secure classes you have created, and to 'rewire' functions to go to other functions. For each secure class, you can use the DUMP poisoned security fragments command that will break whole sections of code at once.



This part should be improved later on...
If the output obfuscated code shows a problem that was not there in the unobfuscated version of the program, there are some general debugging things you can try.

First check that the obfuscated file seem to contain at least as much code as the unobfuscated.
Double check with the TransMAP that functions and labels were correctly recognized.
If not, then you might have not respected the brackets and return rules.

Check out the list of known program problems.

Uncheck the remove comments check-box in the Obfuscator user interface. If the problem is solved then there is a weird comment causing the issue. You can also try to surround areas of code with Comment blocks commands to find where the issue comes.

If you are using a custom function and label scrambling palette, turn that off but leave generic scrambling on and re-obfuscate. If that now solves the problem then you are not specifying all the classes you need to in your custom scrambling palette so check that carefully.

Leave the code unscrambled and with the comments left in to make debugging easier. Try to look both in the unobfuscated code and the obfuscated code to understand where the problem came from. Get line number form the error box and use comments or code fractions to locate the troubled lines.

Look if a variable that is obfuscated is used in a unusual way and try to simplify the way it is used or disable obfuscation.
Try to use msgboxes to see the dynamic values the program is trying to call and compare it with the obfuscated names generated in the TransMESS.txt file.

If the obfuscated program compiled correctly but then gives Autohotkey error boxes when running regarding undefined labels or functions then you probably did not do all the DUMPS you need to initialize your obfuscation variable fragments. If you are using dynamic obfuscation then you will always need to initialize mandatory fragments first which includes DUMPing COMMON SECURITY FRAGMENTS and DUMPing COMMON TRIPLE MESS FRAGMENTS.

Always DUMP unclassed and unsecclasses for functions and labels

For every secure class of functions and labels you define, you must initialize its object name fragments which includes DUMPing its SECURITY FRAGMENTS, DUMPing its TRIPLE MESS FRAGMENTS, and DUMPing its FRAGMENTS.

Some of the functions and variables that you use in your program may have to be specified as straight obfuscation for those objects.
For that you need to CHANGE DEFAULTS for this object type by using -1 as the 3rd parameter.
For specific variables you can also use the standard parameter set on the end of your declaration commands.
You could also try to only use straight obfuscation for some parts of code by changing obfuscation mode to straight mode.

If you are having difficulty figuring out what part of your code is the problem, you may turn off obfuscation within parts of code. You can use the CHANGE DEFAULTS and RESTORE DEFAULTS to turn off obfuscation for new objects within that code by using -1 as the first parameter. You can also turn off obfuscation of all objects (previous and new) within that code section by changing obfuscation mode to Stop obfuscation. Re-obfuscate afterwards and if that solves the problem, turn off obfuscation for a smaller section of code. You can also disable individual Obfuscator command comments within your source code by just indenting the statement. If the ';' starting the comment is beyond the 1 character, the command will not be processed.