Are you using NSIS (Nullsoft Scriptable Install System) to create Windows Installer executables? Do you send custom versions of your .exe installer file to each user (e.g. embedded user token or username/password)? Would you like to have NSIS build one master installer file and easily embed the user data into the installer without having to rebuild or resign the installer? Then this article is for you!
I will demonstrate how to implement the NSIS ReadCustomerData function to customize your master installer file for each user.
I will share my custom version of the AppendPayload program originally written by Aymeric Barthe and shared in his blog post Changing a Signed Executable Without Altering Windows Digital Signature. I will also demonstrate Linux and macOS (OSX) compilation/usage.
Our users can login to our website to download a custom installer that includes their account details. The Linux program reads the original signed NSIS installer, reads a data file that contains the user data, and writes a new installer file with the embedded customer data. Windows recognizes the original digital signature since we are just adding arbitrary data and did not modify the code.
We provide a Windows application for our users. When I researched moving this particular Windows application to NSIS, I was very interested in the NSIS ReadCustomerData function that read arbitrary data appended to the end of the executable (.exe) file. This would allow us to customize our signed installer file with user data (e.g. user token or username/password) without generating and signing a separate installer for each user.
The NSIS ReadCustomerData documentation was a little slim, so I will discuss a few nontrivial steps.
- Decide which “ReadCustomerData” function you will use. Both functions should provide the same results, though the second function seems faster. Save the function to a file named “ReadCustomerData.nsi”.
- Add the following code near the top of your primary .nsi file to import the function you saved in the previous step.
; Include ReadCustomerData function !include ReadCustomerData.nsi
- Add the following code to your main Section to verify that you can (or cannot) read your custom data.
; Read Customer Data (e.g. "username;password") Push "CUSTDATA:" Call ReadCustomerData Pop $1 StrCmp $1 "" 0 +3 MessageBox MB_OK "No data found" Abort MessageBox MB_OK "Customer data: [$1]"
- Create (and sign, if applicable) your NSIS installer executable file.
Now you are ready to append data to the end of your installer! When you run your installer, it will display a message box that says “No data found”. Continue reading to learn how to add a custom payload.
If you have a complex payload with multiple values, I highly recommend that you go back to the NSIS ReadCustomerData function page and use their functions to parse the data.
Embed User Data Method #1 – INVALID DIGITAL SIGNATURE
I initially attempted the following method as discussed in this Stack Overflow article. While NSIS does seem to be able to read the custom user data appended to the end of the .exe file using this method, Windows 10 no longer recognizes the digital signature of the NSIS installer file.
REM DO NOT USE THIS METHOD IF YOU SIGNED YOUR EXECUTABLE! copy setup.exe user123.exe echo "USERDATA:username;password" >> user123.exe
To clarify, the Digital Signature tab on the file properties page is no longer present when data is appended to a signed executable in this way. Windows 10 does not throw an error warning that the signature is invalid. Rather, Windows treats the executable as unsigned.
Embed User Data Method #2 – VALID DIGITAL SIGNATURE
I was able to successfully embed custom user data into the signed NSIS installer .exe file by using the method described in Aymeric Barthe‘s blog post Changing a Signed Executable Without Altering Windows Digital Signature.
We compile and sign our installers on Windows, but we would like to customize and distribute the installer from our Linux servers (e.g. generate custom installer on the fly when requested by user). I was able to make a few minor changes to Aymeric’s code so that it would compile and run correctly on Linux and macOS (OSX).
Download my port to Linux/macOS in my “Signed NSIS exe Append Payload” GitHub repository.