Skip to content
⌘ NSIS Forum Archive

Fix for $PROFILE variable in UAC/Elevated installers (AV Safe)

2 posts

Rizonesoft#

Fix for $PROFILE variable in UAC/Elevated installers (AV Safe)

Hi all,

I'm sharing a solution to a common UAC elevation issue.

The Issue: When you use RequestExecutionLevel admin, variables like $PROFILE and $APPDATA point to the Admin account. If you want to install a config file for the original user, you usually have to resort to plugins that hunt for explorer.exe.

The Fix: I found that the old "Explorer Process" method is getting flagged by modern AV heuristics as malicious (Token Stealing). I wrote a small open-source plugin, GetOriginalUser, that uses the WTS (Windows Terminal Services) API instead.
  • Zero AV Detections: It uses standard OS APIs to query the Session Manager.
  • No Process Handles: It doesn't touch other processes, so it's safer and more stable.
  • Correct Paths: Resolves User Shell Folders from the Registry to handle redirected folders.

Link: https://github.com/rizonesoft/GetOriginalUser

Usage: You can use the CLI tool with nsExec (simplest) or call the DLL directly with the System plugin.

CLI Example:

Section "Main"
File "GetOriginalUser.exe"

# Get the original user's Documents folder
# Value names map to Registry 'User Shell Folders' (Personal, AppData, Desktop, etc.)
nsExec::ExecToStack '"$PLUGINSDIR\GetOriginalUser.exe" --env Personal'
Pop $0 ; Return Code
Pop $1 ; The Path (e.g., C:\Users\Bob\Documents)

DetailPrint "Real User Docs: $1"
SectionEnd
Anders#
This issue only happens when a non-admin user UAC elevates (over the shoulder elevation). Please note that the ProfileList value is not guaranteed (by Microsoft) to exist in all domain scenarios (but presumably it will if you are logged in as that user on the local machine) nor is the registry hive for that used guaranteed to be loaded (but it probably is if Explorer is using it).

You are not really supposed to touch HKCU nor the users profile when asking for elevation because you are probably performing a machine/all-users install but there might be edge cases where you have a single user install mode but have to install a driver or a service.

I have not heard much about the token stealing AV issue, an elevated process duplicating a medium process token should be allowed IMHO.

The 3rd alternative is implemented by the NSIS UAC plug-in; the initial process is not elevated and it spawns its own child elevated. This does not work correctly if the non-admin manually elevated first. I believe Inno Setup also implements this mode? The advantage here is that you can spawn a non-elevated process (this can also be done with the help of the Explorer process; https://nsis.sourceforge.io/ShellExecAsUser_plug-in).