ScriptGuard is a different method of protecting compiled scripts from decompilation.
(This is an update to the original release.)
ScriptGuard consists of two security measures as follows:
- ScriptGuard1 - Removes the script source code from memory as soon as the compiled script starts executing.
- ScriptGuard2 - Encrypts the source script and provides additional security against decompilation.
ScriptGuard1
ScriptGuard1 relies on the fact that compiled AutoHotkey scripts are processed in two stages (as are all scripts):
- First the source script is syntax-checked, loaded into memory structures, and optimised.
- Then the loaded script is executed from the optimised copy in memory.
This is what ScriptGuard1 does. It wipes the original script from memory at the same time as the optimised copy starts to be executed. With the script not in memory at this time, memory inspection methods will no longer be able to find the original script.
Here is the code to be #Included in your script at the top:
Code: Select all
; ------------------------------ ScriptGuard1 --------------------------------
ScriptGuard1() ; Hides AutoHotkey source in compiled scripts
{ ; By TAC109, Edition: 28Jan2023 ; Include this code in your script at the top
static _:=SubStr(A_AhkVersion,1,1)=1?ScriptGuard1():1 ;Runs when script starts
local ahk:=">AUTOHOTKEY SCRIPT<", pt:=0,sz:=0,d:=0,k,v, rx:=0x7FFFFFFFFFFFFFFF
,rc, ahk1:="~AUTOHOTKEY SCRIPT~",rs:=0x7FFFFFFFFFFFFFFF,rz:=0x7FFFFFFFFFFFFFFF
if A_IsCompiled ;^ Don't alter! ; See bit.ly/ScriptGuard for more details
{ for k,v in [ahk1, ahk, "#1"] ; Works with v1.1 & v2, and AHK_H v2
if (rc:=DllCall("FindResource", "Ptr",0, v ~= "^#\d$" ? "Ptr" : "Str", v
~= "^#\d$" ? SubStr(v,2) : v, "Ptr",10, "Ptr"))
&& (sz:=DllCall("SizeofResource","Ptr",0, "Ptr",rc, "Uint"))
&& (pt:=DllCall("LoadResource", "Ptr",0, "Ptr",rc, "Ptr"))
&& (pt:=DllCall("LockResource", "Ptr",pt, "Ptr"))
&& (DllCall("VirtualProtect","Ptr",pt, "Ptr",sz, "UInt",0x04, "UInt*",rc))
DllCall("RtlZeroMemory","Ptr",pt, "Ptr",sz), d:=k ; Wipe script from RAM
(rs=rx)?0:DllCall("VirtualProtect","Ptr",rs,"Ptr",rz,"UInt",0x02,"UInt*",rc)
(d<2)?DllCall("MessageBox","Int",0,"Str","Warning: ScriptGuard1 not active!"
. "`n`nError = " (A_LastError=1814 ? ("Resource Name '" ahk "' not found."
. "`nTo fix, see the 'Example 1' comments at https://bit.ly/BinMod.")
: A_LastError), "Str", A_ScriptName, "Int", 64):0 ; For additional security,
} } (SubStr(A_AhkVersion,1,1) = 1) ? 0 : ScriptGuard1() ; see bit.ly/BinMod
; ------------------------------------------------------------------------------
When a script which includes ScriptGuard1 is run directly without compiling first, this code will have no effect. However, in a compiled script this code will be executed automatically when the script starts to run. (There is no need for the user's script to call the ScriptGuard1() function directly.)
ScriptGuard1 can be used with AutoHotkey v1.1 and v2, and AutoHotkey_H v2.
Users of BinMod should check the end of example 1 of that documentation for additional information.
ScriptGuard2
Use of ScriptGuard2 causes the source script to be encrypted with a random key in the compiled .exe, thus hiding the AutoHotkey code from casual inspection. It also provides additional security by preventing some common methods of exposing the source script.
ScriptGuard2 is available with Ahk2Exe v1.1.34.04b or later and can be used with AutoHotkey v1.1 and v2. It is 32-bit and 64-bit compatible. It can also be used with AutoHotkey_H v2, provided that the 'Encrypt Source' parameter is set to '(none)' in the Ahk2Exe_H GUI.
If using ScriptGuard2, it is required that ScriptGuard1 with an edition date of 28 Jan 2023 or later is included in the script to be compiled.
In addition, BinMod with an edition date of 05 June 2023 or later must be used, and needs to be called by the ;@Ahk2Exe-PostExec compiler directive in your script. If you have Ahk2Exe version 1.1.34.03c or later installed, run Ahk2Exe and go to 'Help' -> 'Check for Updates'. You can update BinMod directly from there.
The ScriptGuard2 option is invoked by supplying a specific /ScriptGuard2 or /ScriptGuard2pss parameter to BinMod.
- When /ScriptGuard2 is used, the compiled executable will not be able to run if the /script switch is used when running the compiled program.
- When /ScriptGuard2pss is used, this permits the /script switch to be used when running the compiled program, but prevents the embedded script from being decrypted when this switch is used.
ScriptGuard2 Restrictions
There are some restrictions on how ScriptGuard2 can be used:
- The script to be compiled must not have additional scripts added as resources (see Embedded Scripts).
- Scripts compiled with .bin base files will be prevented from running if compressed with MPRESS or UPX. Instead use a suitable .exe base file, then running after compression will be fine.
- Compiled scripts will refuse to run if the /script parameter is used with the compiled .exe, unless the script was compiled with the /ScriptGuard2pss parameter.
Summary
For maximum protection:
- Save all the code above as ScriptGuard1.ahk somewhere convenient, such as in a standard library.
- Ensure BinMod and Ahk2Exe are up to date. (Ahk2Exe -> 'Help' -> 'Check for Updates'.)
- Insert the following code at the top of your script:
(This code is self-adjusting and need not be altered for the environment.)
Code: Select all
#Include <ScriptGuard1.ahk> ; Can adjust for location of ScriptGuard1.ahk ;@Ahk2Exe-Obey U_Bin,= "%A_BasePath~^.+\.%" = "bin" ? "Cont" : "Nop" ; .bin? ;@Ahk2Exe-Obey U_au, = "%A_IsUnicode%" ? 2 : 1 ; Base file ANSI or Unicode? ;@Ahk2Exe-PostExec "BinMod.exe" "%A_WorkFileName%" ;@Ahk2Exe-%U_Bin% "1%U_au%2.>AUTOHOTKEY SCRIPT<. RANDOM" ;@Ahk2Exe-Cont "%U_au%.AutoHotkeyGUI.RANDOM" ;@Ahk2Exe-Cont /ScriptGuard2 ; or /ScriptGuard2pss if required ;@Ahk2Exe-PostExec "BinMod.exe" "%A_WorkFileName%" "11.UPX." "1.UPX!.", 2 ;@Ahk2Exe-UpdateManifest 0 ,.
- Compile your script with Ahk2Exe.
- Check that the compiled script runs. If it doesn’t, see 'ScriptGuard2 Restrictions' above.
Updates
03 Apr 2024
Document that ScriptGuard can be used with AutoHotkey_H v2.
05 June 2023
Fix error message.
31 May 2023
Add new parameter /ScriptGuard2pss ('Permit /script switch').
02 Apr 2023
/ScriptGuard2 now has aligned mcode for faster processing.
29 Mar 2023
/ScriptGuard2 file handling is now fully Unicode compatible.
15 Feb 2023
Add 'UPX -d' prevention line to the summary.
14 Feb 2023
Ensure /ScriptGuard2 handles big .exe's.
05 Feb 2023
Add a Summary to the documentation.
30 Jan 2023
Speed up script encryption/decryption.
28 Jan 2023
Add source code encryption.
23 Aug 2020
Add parameters /ScriptGuard2 /SetDateTime /SetUTC.