Autohotkey Dynamic Obfuscator Documentation

Table Of Content

Introduction offers an overview of the principles and features of the Obfuscator.
Obfuscation Process contains the concrete process to follow to obfuscate your program successfully.
User Manual contains the complete documentation index with all details.
-
Download has links to the last version of the Obfuscator
Whats new indicates major changes since brought by Dynamic Obfuscator L vs original version.
Example contains a complete example of a simple program obfuscated by AHK Dynamic Obfuscator.

Check out my other projects. I would be very glad if you would try EverFastAccess and give me your feedback / share if you like.
Obviously it would be a huge help if you could make even a modest donation to support.

Autohotkey Dynamic Obfuscator is Free and Open Source

Use this free open source program written in Autohotkey to obfuscate your Autohotkey scripts. Download includes all script files for the program. Check out this complete example of an Autohotkey program that is obfuscated with this program.

The original author David Malia created the first version called "AutoHotKey Obfuscator". That was the most complete Obfuscator tool for AHK. However the software was complicated to use and didn't encompass many of the AHK complexities and recent developments.

I then started to improve this whole project as I was trying to protect an ambitious 70,000 line ahk note-taking program called EverFastAccess. I decided to make this project as understandable and intuitive as possible to all AHK programmers that want to protect some of their work. After more than 5 months of full-time work this has come to this "AutoHotKey Obfuscator L" tool. I hope you will enjoy it and that it will serve you well.

Summary of Index


-

Basic concept

This programs offer several functionalities to make your source code unreadable to anyone.
This prevents users / some hackers to understand how the code works, to see your security controls, and to modify or reuse your code without permission.
For example a function like this :
ValueFromList(P_Index,P_List,Delim="|") {
global
local found
;This function returns the value from a list index
	if (Delim=#Bar#)
	P_List:=StrReplace(P_List, #DBar#, #Bar#)
	Loop, Parse, P_List, % Delim
		if (P_Index = A_Index)
			found:=A_LoopField
	return found
}
Can look like this :
kfk@#ff@kffk@f#f(#f#ffkff#ff@kk,ffk@f@fkk@@kff#k,k@kf#k@f#kkkf#f@="|") {
global
local kkk#@kfff#
if (k@k%kf#fff%%k@kfkfkk@f#f@k%#%@f@k#fk@fkf@@fkf%@f#kkkf#f@=f#f%f@kkffk@#kf#fkfk#f#k%fk%f@#f%kf)
ffk@%#ff#@f@k%f@fkk@@%@fkf@fk@k@@ff@kf%ff#k:=%k#kkf@k#%%#fk@k#@k@f#f%%@ff@kf%%k@kk%%kkf@f#kkkk#fff@k%%#ff#@f@k%(%k@f##kk#%%k@@f#kfkkfk#kkk@fffk%%k@f@%, %#k@k%%@f@k@f%%f##k@k#f#k@k%, f%kkfk%%#k#fk#k##k@fkk#kfk%f%#fk#kff@%kfkkf)
Loop, Parse, ffk%fkf#k@@ffk@kf@@kffkfff%%ffkkffk@@kfff#ff@kkf%@%#k@k#kk@%fkk@@kff#k, % k@k%kf@f%f%@k#kk#k@f@ffkk%k@%f@#f%f%#k#fk#k##k@fkk#kfk%kkkf#f@
if (#f#%kk@kk#k##fk@#fffff#f#k@k%%@kk#%fkf%kf@ff#f#kfkffk#ff@k#%#ff@kk = %kkf@f#@f%%fk#fff%%f#f#f@k@#kf#k#%%k#f#ff%%fkf##k%%@fkk@kfk@ffkf#%)
%ffk#%%kf#ff@f@%%f#kfk#@k%:=%kfffkk%%kf@f%%@kkk#kf#k@k#%%ff@fk@%%kffkf@#ff@#fkf%%fkf@f@%
return kk%@kkkkk@fk#f#ffk#fkf@%%k#f#@f#fffk#f@f@kkkkf#%@%k#@fkf%kfff#
}

It does that by:
  • Obfuscating your code
  • AND optionally:
  • Removing all your comments
  • Stripping all whitespaces and empty lines
  • Scrambling all your code together so that there is no logical order.
For obfuscation to work correctly, you will have to add a few Obfuscator commands to your code.
Some are mandatory, some optional.

What This Program Doesn't Do

  • This program does not obfuscate everything automatically. Nor is it able to fully obfuscate all.
  • There are many parts where you should tell him the list of what to obfuscate.
    The main thing is that the program does not obfuscate automatically your variables. You need to specify them to it.
    We did it this way to save time building this program. Also it reduces the risk of mistakes. And usually not everything needs to be obfuscated.
  • The program does not automatically process all the #include file commands in your code.
  • You need to perform a few steps and create an include text file for the Obfuscator which will indicate all your includes !
  • For variables, methods/properties and system functions you must add Obfuscator comments commands to your source code so that variables will be obfuscated.
  • For strings you must add special hidestr() functions so that your sensitive strings will appear encrypted.

  • Nevertheless the program does automatically obfuscate your functions, their parameters, and labels.

DO NOT HESITATE TO LOOK AT AND PLAY WITH EXAMPLES

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

-

Obfuscation Comment Commands

The Obfuscation Comment Commands are comments you put inside your code to give various instructions to the Obfuscator.
The commands will be highlighted in brown in this documentation all along. These commands look like :
;$OBFUSCATOR: COMMAND : OPTIONAL PARAMETER(S)
They are called comment commands because they all start with a comment sign for your code to still run correctly.
For Comment Commands to work correctly they
  • MUST START at character 1 position of the line
  • MUST START with the comment sign ";"
  • MUST CONTAIN a semicolon after the command name even if they have no parameters
Example of a command that has no parameters :
;$OBFUSCATOR: $START_BLOCK:

Understanding Obfuscation

Obfuscation is the ability to disguise things under complicated names.
The first step is to rename all functions, labels, variables etc. to complicated and non logical names.
For example myfunction() will become ffk@fkfkk()
This program only uses "fk@#" characters to make up new names that resembles the others, creating extra-confusion.

There are 2 major types of obfuscation: Straight obfuscation & Dynamic obfuscation

  • Straight obfuscation
  • Means no dynamic variables are really use to disguise a name, the name is just changed to something random. When possible though, fake empty dynamic variables are inserted in the middle of the name with use of un-assigned "%"'s variables
    E.g. myfunction() will have a new name given by the Obfuscator: e.g. ffk@fkfkk().
    The straight obfuscation will still add some fake dynamic empty variables when calling this function so that someone could not just search for this new name.
    For example it will call ffk@%fffkf%fk%ffkf%fkk() : if you take out %fffkf% %ffkf% which are empty you will find ffk@fkfkk() and then be able to find back the function that was used.
    So even if straight obfuscation already makes the code quite hard to understand this is a quite limited obfuscation.

  • Dynamic obfuscation
  • Means a lot of small global variables will be created so that each call to myfunction() will look completely different.
    It will create many variables that will be equals to the three characters to create obfuscated names "fk@#" thus creating many possibilities to call a same name.
    It will also create global obfuscated variables to split the name in 2 or more, and assign these parts to new obfuscated variables.
    Finally it still can add empty variables in the middle.
    For example if myfunction() became ffk@fkfkk().
    The program have created some character vars for each of the character it uses to creaate obfuscated names: f@fff:="f" @kkkf:="k" ...
    It has also split the function name ffk@fkfkk in several parts fkfkf:="ffk@" fkfkfkfk:="fk" kkfkfk:="fkk"
    So we can now use some of these parts by calling the variables and either leave some remaining "fk@#" or call some of the character replacements.
    E.g We have thus for example ffk@fkfkk() = %fkfkf%%fkfkfkfk%%kkfkfk%() = %fkfkf%f%@kkkf%%kkfkfk%() = %fkfkf%%f@fff%k%kkfkfk%()
    Finally we can add non-assigned empty vars for example @@fff@ @kkk@ (which are ="")
    We have then for example
    ffk@fkfkk() = %fkfkf%f%@kkkf%%kkfkfk%() = %fkfkf%%@@fff@%%f@fff%k%@kkk@%%kkfkfk%()

    Thus each call of myfunction() will be very very hard to find.
    Moreover dynamic obfuscation allows more complex tactics to hide code and allow to hide more objects.
    Learn more in Difference Between Dynamic and Straight Obfuscation page.

    Hide Sensitive Strings With hidestr()

    This program allows you to obfuscate any sensitive strings in your autohotkey scripts by surrounding them with the hidestr() function. You can surround sensitive literal strings with hidestr() any place you use them like in variable assignments, in function calls, in statement parameters, and in expressions. You can do stuff like this:
    var1:= hidestr("some sensitive string") 
    
    somefunc(hidestr("some sensitive string"), parameter2)
    When this program obfuscates your program it will replace any literal strings passed as parameters to the hidestr() function with an obfuscated literal string. It will then replace the hidestr() function call itself with a call to the decode_hidestr() function and then it will obfuscate that.
    E.g the above mentioned will be converted first to something like: 
    var1:= decode_hidestr("8a4b6645d5s4545145d494a45b4564d5d45c562d1d")
    somefunc(decode_hidestr("7a456b45c46b45d645a465f32118ff48fa48b54c8d"), parameter2)
    And then the decode_hidestr() function will be obfuscated as well leading to something like:
    var1:= %fkfkf%f%@kkkf%#%fkfkfkfk%%kkfkfk%("8a4b6645d5s4af48545145d494a45b4564d5d45c562d1d")
    somefunc(%fkfkf%%@@fff@%%f@fff%k%@kkk@%%kkfkfk%("7a456b45c46b4ab125d645a465f32118ff48fa48b54c8d"), parameter2) 
    Then of course somefunc() will also be obfuscated and var1 and parameter2 can be obfuscated as well, leading to a fully obfuscated line!
    To protect sensitive strings, this program uses a variant of the Vigenere cipher.
    Your string is encoded into another smaller alphabet (e.g. hexadecimal) each character being coded to 2 characters and shifted by some random numbers being hidden at some position in the encoded string.
    You can have multiple hidestr functions for different level of protection and you should customize your own functions.
    Learn more in Use 'hidestr()' to Hide Sensitive Literal Strings in Your Script in User Manual.

    Scramble the Order of Functions and Label Sections

    This is a function that you can check or uncheck on the Obfuscator interface. It will randomize the order that your function and label sections will appear in the obfuscated code.

    You can choose to randomize all your function and label sections together or you can choose to apply a custom scrambling template.
    If you randomize all you can also leave some portions of code together by simply surrounding these portions by simple Obfuscator commands:

    The custom scrambling template allows you to organize scrambling into groups of classes. All the functions and label sections of all the classes you assign to a specific group will be randomized together and dumped into the obfuscated source code file together. You can also control the order that the groups will be dumped allowing you to create layered scrambled sandwiches of functions and label sections.

    If you have some errors with your obfuscated code, turning this function off may make debugging your obfuscated code easier.
    Learn more in Scrambling the Order of Your Whole code page.

    Strip comments and whitespaces

    This is a function that you can check or uncheck on the Obfuscator interface. When obfuscating each function, the Obfuscator will remove all extra spaces in each line and remove all comments and all comments sections surrounded by /* and */.
    You can preserve some specific comment parts by simply surrounding the portions of code where comments are to be preserved by simple Obfuscator commands.
    The Obfuscator will be able to process the standard #CommentFlag and #EschapeChar.
    Learn more in Remove Whitespaces and Comments except specific blocks page.

    This Autohotkey Obfuscator is Blazing Fast!

    Approximate time required to Obfuscate an 8,000 line Autohotkey program : less than 50s !