AppInit DLLs
Malware registers a DLL in the AppInit_DLLs registry value so it is loaded into nearly every user-mode process that links against User32.dll.
The AppInit_DLLs mechanism instructs User32.dll to load a list of arbitrary DLLs into the address space of every user-mode process that loads User32.dll during initialization — which is most GUI processes. When such a process starts, User32 reads the registry value and calls LoadLibrary on each path, giving the listed DLL code execution inside many unrelated processes at once.
This makes AppInit_DLLs both broad persistence and a system-wide injection primitive: a single registry write causes the payload to be mapped into Explorer, Office, browsers, and countless others. Because of this abuse, Microsoft deprecated the feature and, on systems with Secure Boot enabled, it is disabled outright; where it still functions, the LoadAppInit_DLLs flag must be set to 1 and (on signing-enforced builds) the listed DLLs must be code-signed.
The values live under HKLM and require administrative rights to modify, but a successful registration is exceptionally durable and noisy in its reach across processes.
How it works
Two values under a single key control the mechanism:
Key: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
Name: AppInit_DLLs Data: C:\Users\Public\inject.dll
Name: LoadAppInit_DLLs Data: 1On 64-bit systems the WOW6432Node copy (HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Windows) governs 32-bit processes and is a commonly overlooked second location. The RequireSignedAppInit_DLLs value, when set to 0, relaxes signing enforcement — attackers may flip it to allow an unsigned payload. The load-bearing artifacts are a non-empty AppInit_DLLs path combined with LoadAppInit_DLLs = 1.
Detection & analysis
Static analysis:
- In a captured sample, look for the subkey string
CurrentVersion\Windowsand the value namesAppInit_DLLs/LoadAppInit_DLLs, plus the registry write APIs. A sample that setsRequireSignedAppInit_DLLsto0is a strong indicator of intent to load unsigned code. - Triage a live or imaged host with Autoruns (Sysinternals): the "AppInit" tab lists every registered DLL across both the native and WOW6432Node hives and flags unsigned entries.
- Offline forensics: parse the
SOFTWAREhive with RegRipper or Registry Explorer. On a clean systemAppInit_DLLsis empty andLoadAppInit_DLLsis0; any populated path is suspicious. Check both the native and WOW6432Node copies.
Dynamic analysis:
- Run the sample under Procmon filtered on
Path contains AppInitto capture the write. Then observe the broad fan-out: with ProcmonLoad Imageevents, the same DLL is mapped into many unrelated processes shortly after. - Sysmon Event ID 13 records the
AppInit_DLLsvalue write; Event ID 7 (Image Loaded) shows the identical unsigned DLL loaded into numerous distinct host processes — the unusual breadth of the same module is the tell.
Detection rule hint:
Alert on any write to AppInit_DLLs (native or WOW6432Node), on LoadAppInit_DLLs being set to 1, or on RequireSignedAppInit_DLLs being set to 0. At runtime, flag a single unsigned DLL from a user-writable path being loaded into a large number of unrelated User32-based processes.