ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post your working scripts, libraries and tools for AHK v1.1 and older
TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 22 Aug 2020, 20:11

Introduction

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.
(TL;DR: See the Summary below.)


ScriptGuard1

ScriptGuard1 relies on the fact that compiled AutoHotkey scripts are processed in two stages (as are all scripts):
  1. First the source script is syntax-checked, loaded into memory structures, and optimised.
  2. Then the loaded script is executed from the optimised copy in memory.
The normal Ahk2Exe compilation process creates an executable, which contains the AutoHotkey interpreter, the script, and any files it includes. When the compiled executable is run, it reads and analyses the contained script in the manner shown above, prior to executing the optimised result. After execution starts, the original script contained in the executable is now no longer needed and can be safely removed from 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, but not _H
      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
; ------------------------------------------------------------------------------
This code should be copied or downloaded, and stored in a file named ScriptGuard1.ahk. It can be incorporated into your script (at or near the beginning) by using the #include statement.

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, but not with AutoHotkey_H.

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, but not with AutoHotkey_H. It is 32-bit and 64-bit compatible.

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.
Further details are provided with examples 0 and 4 of the BinMod documentation. (Additional methods of disguising a compiled script can be found there as well.)


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:

    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 ,.
    (This code is self-adjusting and need not be altered for the environment.)
  • Compile your script with Ahk2Exe.
  • Check that the compiled script runs. If it doesn’t, see 'ScriptGuard2 Restrictions' above.
When viewing the posts to this thread, be aware that posts before this one relate to an earlier version of ScriptGuard which didn't include script encryption.


Updates

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.
Last edited by TAC109 on 04 Jun 2023, 18:03, edited 38 times in total.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe


TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 24 Aug 2020, 04:42

Thanks.
I hope you find it useful. :D
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

User avatar
JoeWinograd
Posts: 2166
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by JoeWinograd » 24 Aug 2020, 12:25

Hi TAC,
TAC109 wrote:if the compiled executable is compressed with MPRESS or UPX before distribution, the script embedded in the executable will not be visible before execution
But isn't the big problem here that there are widely available MPRESS and UPX crackers out there? Even if we use a PostExec BinMod to prevent the use of UPX -d, which is the really easy way to decompress, aren't there still UPX crackers out there that can do it, albeit not as easily?
there will be only a small time-window in which the included script is visible; after the executable has been de-compressed and before the execution of the embedded script
That's excellent, but what worries me is the unlimited amount of time that the EXE is just sitting there on the bad actor's computer waiting to be cracked...or am I missing something here?

Btw, your Ahk2Exe and BinMod are working beautifully...can't thank you enough for them! Cheers, Joe

guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by guest3456 » 24 Aug 2020, 12:52

TAC109 wrote:
22 Aug 2020, 20:11
ScriptGuard1 can be used with any version 1.1 of AutoHotkey, but not with AutoHotkey_H.
why doesn't it work for _H ? and can it be modified to work on that?
TAC109 wrote:
22 Aug 2020, 20:11
ScriptGuard2 provides additional security for ScriptGuard1 by making a small change to the AutoHotkey interpreter generated when the script is compiled. Use of this feature is entirely optional, but gives some additional security to ScriptGuard1.
what change is made to the interpreter? and how/what is the additional security that is provided by it?


User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by kczx3 » 24 Aug 2020, 14:22

I echo @JoeWinograd's thoughts about decompressing the compressed executable via MPRESS or UPX. You'd really need a password to encrypt/hash against and the person with the executable would need to know the password to decrypt, right?

TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 24 Aug 2020, 18:10

ScriptGuard is not designed to be the complete answer to preventing compiled scripts from being revealed by a determined hacker, but is more to prevent casual examination of the script in a running compiled .exe. It grew from an idea I had that the script in memory was no longer needed after the .exe had started executing. Just over a dozen lines of code to allow the user to close off this particular avenue of inspection, which is one I have used myself at times to see a compiled script. If you are already using heavy-weight anti-cracking measures to protect your .exe's, then ScriptGuard will not be of interest to you.

@JoeWinograd I suppose the answer to your comments is to use a stronger compressor on your .exe's, but I don't have expertise in this area.

@guest3456 Regarding AutoHotkey_H, I have not tested ScriptGuard with H, and I know that the script resource name is completely different. Otherwise it may work, but as I said I have not tested this.

Regarding your other point, I am reluctant to discuss this as I believe it would violate one of the forum rules on decompilation. Use of this ScriptGuard feature is entirely optional and if not used, does not prevent the ScriptGuard1 code from working as stated.

Cheers
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

User avatar
JoeWinograd
Posts: 2166
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by JoeWinograd » 24 Aug 2020, 22:02

TAC109 wrote:one I have used myself at times to see a compiled script
Just curious...how do you do that? Thanks, Joe

TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 24 Aug 2020, 23:00

@JoeWinograd
I believe that discussing this would violate the forum rules on decompilation.
Cheers
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by guest3456 » 24 Aug 2020, 23:04

@HotKeyIt would these work with AHK_H ?


TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 24 Aug 2020, 23:15

@guest3456
ScriptGuard2 will definitely not work with H, but ScriptGuard1 should work if the resource name is changed in the script above to that used in the H version of Ahk2Exe. @HotKeyIt could confirm?
Cheers
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

guest3456
Posts: 3453
Joined: 09 Oct 2013, 10:31

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by guest3456 » 24 Aug 2020, 23:59

@TAC109 well as far as i know, the script is not stored in plaintext in AHK_H anyway, so it might not matter if that memory is erased.


HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by HotKeyIt » 25 Aug 2020, 01:40

TAC109 wrote:
24 Aug 2020, 23:15
@guest3456
ScriptGuard2 will definitely not work with H, but ScriptGuard1 should work if the resource name is changed in the script above to that used in the H version of Ahk2Exe. @HotKeyIt could confirm?
Cheers
AFAIK yes.
guest3456 wrote:
24 Aug 2020, 23:59
@TAC109 well as far as i know, the script is not stored in plaintext in AHK_H anyway, so it might not matter if that memory is erased.
Correct.

User avatar
SirSocks
Posts: 360
Joined: 26 Oct 2018, 08:14

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by SirSocks » 25 Aug 2020, 07:11

This is awesome! Thank you very much!

EDIT 1
I utilized ScriptGuard1() by adding it to the top of my script and compiled the .ahk into a .exe. I was able to decompile the exe using the Payload Injection Method. Maybe I'm doing something incorrectly to initialize ScriptGuard1() Please see my code below. Can anyone point out what I'm doing incorrectly? Thank you.

I'm using AHK v 1.1.32

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.; --- Script Guard --- https://www.autohotkey.com/boards/viewtopic.php?f=6&t=80229
; ------------------------------  ScriptGuard1  --------------------------------
ScriptGuard1()                    ; Hides AutoHotkey source in compiled scripts
{ ; By TAC109, Edition: 23Aug2020 ; To use just include this code in your script
  static _ := ScriptGuard1()      ; Is automatically actioned when script starts
  local ahk:=">AUTOHOTKEY SCRIPT<", pt:=rc:=sz:=0
  if A_IsCompiled                 ; See bit.ly/ScriptGuard for more details
  { if (rc:=DllCall("FindResource",  "Ptr",0, "Str",ahk, "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",0x40, "UInt*",rc))
      DllCall("RtlZeroMemory", "UInt",pt, "Int",sz) ; Wipe script from memory
    else MsgBox 64,,% "Warning: ScriptGuard1 not active!`n`nError = "
      . (A_LastError=1814 ? ("Resource Name '" ahk "' not found.`nTo fix, see "
      . "the 'Example 1' comments at http://bit.ly/BinMod.") : A_LastError)
} }                               ; For additional security, see bit.ly/BinMod
; ------------------------------------------------------------------------------
return

^J::
msgbox, This is a message box.
return
EDIT 2
/ScriptGuard2 utilizing the BinMod seems to be effective to protect from Payload Injection Method. :dance:
Thank you.

User avatar
JoeWinograd
Posts: 2166
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by JoeWinograd » 25 Aug 2020, 14:09

Hi TAC,

I tested ScriptGuard1 with a 32-bit compile and it worked perfectly! Before ScriptGuard1, I could easily see the source code in the running EXE. After ScriptGuard1, I could no longer see it...very nice!

Here's a point that you may want to include in the documentation. If you use a PostExec BinMod to change ">AUTOHOTKEY SCRIPT<", then you need to change the local ahk assignment statement in ScriptGuard1.ahk. If you don't, you'll get a dialog box with this in it:

ScriptGuard1 not active.png
ScriptGuard1 not active.png (4.94 KiB) Viewed 10040 times

I also used /ScriptGuard2 in that same compile, but I don't know if it worked because I don't know what it does. :)

Thanks very much for this excellent addition to your work on Ahk2Exe and BinMod. Regards, Joe

TAC109
Posts: 1096
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by TAC109 » 25 Aug 2020, 18:06

@JoeWinograd
There is a note in BinMod.ahk near the end of Example 1 which should deal with the situation you encountered:

Code: Select all

   Users of ScriptGuard1 (bit.ly/ScriptGuard) should add a 1 to the 3rd line:
    ;@Ahk2Exe-Cont  "1%U_au%2.>AUTOHOTKEY SCRIPT<. DATA              "
                     ^
If you use this method rather than changing ScriptGuard1, the same ScriptGuard1 code can be #included in different scripts and will work regardless of the resource name alteration made with BinMod.

Cheers
Last edited by TAC109 on 27 Jan 2023, 21:33, edited 1 time in total.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe

User avatar
JoeWinograd
Posts: 2166
Joined: 10 Feb 2014, 20:00
Location: U.S. Central Time Zone

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by JoeWinograd » 25 Aug 2020, 18:21

TAC109 wrote:If you use this method rather than changing ScriptGuard1, the same ScriptGuard1 code can be #included in different scripts and will work regardless of the resource name alteration made with BinMod.
Ah, missed that...very nice! Not an issue for me, since I'm using the same resource name alteration for all my programs...but good to know! Regards, Joe

need4speed
Posts: 143
Joined: 22 Apr 2016, 06:50

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by need4speed » 28 Aug 2020, 20:25

TAC109 wrote:
22 Aug 2020, 20:11
In addition, if the compiled executable is compressed with MPRESS or UPX before distribution, the script embedded in the executable will not be visible before execution. Therefore there will be only a small time-window in which the included script is visible; after the executable has been de-compressed and before the execution of the embedded script. As this is one continual process there is very little opportunity for the source script to be extracted from the executable in any way.
Compressed executable can be identified pretty easily, in PE for instance they are highlighted purple. Even if packed executables don't contain per se any malware, they are often tagged as risk-ware, suspicious or false positives by FUD software vendors and as I don't feel like arguing with our security department why I potentially put the company on risk, I prefer to stay off such apps. From my experience sooner or later a skilled hacker may accept the challenge and write an unpacker or similar anyway. This also happened with modern, online-based security suits like denuvo, I read a story once of a guy who reverse-engineered the Skype protocol, probably out of boredom.
Furthermore imo AHK is not a good starting point if obfuscation/IP is an important factor. In my opinion the safest code is the one you don't release, or write in first place. Sorry for the drift, it's gotten late :lol:

I did only look into ScriptGuard1, and from my point of view the name is misleading. In my test I included your script and added a msgbox command then compiled the script. After running the (uncompressed) exe the source code is indeed no longer available in memory. So far so good, but as you wrote "there will be only a small time-window in which the included script is visible", this "opportunity" is enough to hack your script. I managed to do so by simply suspending the compiled script, instantly after running it. In suspended mode the source code is visible.

User avatar
SirSocks
Posts: 360
Joined: 26 Oct 2018, 08:14

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by SirSocks » 02 Sep 2020, 19:56

@need4speed Look into ScriptGuard2 it seems to be effective from my quick tests.

c7aesa7r
Posts: 209
Joined: 02 Jun 2016, 21:09

Re: ScriptGuard: Helps Protect Compiled Scripts from Decompilation

Post by c7aesa7r » 12 Sep 2020, 20:39

how can i check if the script got removed from the memory?

Post Reply

Return to “Scripts and Functions (v1)”