How do you load a DLL in every new process on a Windows machine? One way to do this is the AppInit_DLLs registry key (this key is frequently abused by malware). Every new process loading user32.dll, also loads the DLLs listed in AppInit_DLLs on startup.
But you can’t use this key to load hook-createprocess.dll, because it will load it in every process, and your Windows machine will stop working.
To selectively load DLLs, I developed a new DLL: LoadDLLViaAppInit.dll. Copy LoadDLLViaAppInit.dll to system32 and add it to the AppInit_DLLs registry key (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows). This way it gets loaded in every new process. LoadDLLViaAppInit.dll will consult config file LoadDLLViaAppInit.bl.txt in system32, this config file contains the list of processes we want to load a particular DLL into. Here’s an example:
acrord32.exe hook-createprocess.dll winword.exe hook-createprocess.dll excel.exe hook-createprocess.dll powerpnt.exe hook-createprocess.dll
This config file instructs LoadDLLViaAppInit.dll to load hook-createprocess.dll into Adobe Acrobat (acrord32.exe) and Microsoft Office (Word, Excel and PowerPoint). Important remark: the separator between the executable name and the dll name must be a TAB character. For debugging purposes, LoadDLLViaAppInit.dll logs the DLLs it loads to the debug console.
If you want to prevent a DLL from being loaded (for example to allow Adobe Reader to update itself), you’ll just have to temporarily modify the config file. And be careful with this tool, a wrong configuration can render your machine unusable (for example, if you load hook-createprocess.dll into every process, Windows won’t be able to create new processes).
Be sure to allow only administrators to write to the config file, otherwise you’re opening your machine to elevation attacks.
Starting with Windows Vista, AppInit_DLLs is not enabled by default for security reasons (it’s used a lot by malware). To enable it, you’ve to set the value of LoadAppInit_DLLs to 1. But be aware that this makes your Windows Vista (and later) machine less secure, as from then on, malware will also be able to use AppInit_DLLs to autorun.
Download:
LoadDLLViaAppInit_V0_0_0_1.zip (https)
MD5: 60B93BAF4B0F973C3EC920F2F4A180E8
SHA256: 3B528A3BAF593A2740D5655CF18BC0932801D4DF1750DE8F9C8229C0FF51E8BE
Didier,
Does this work with *all* processes or only GUI-based apps?
http://support.microsoft.com/kb/197571
Comment by H. Carvey — Thursday 24 December 2009 @ 18:10
@Harlan All processes (CUI and GUI), provided they load user32.dll (most applications do).
Comment by Didier Stevens — Tuesday 29 December 2009 @ 20:00
I realize this approach allows a lot of flexibility, but you could also just change the code for your injected DLL: in DllMain(), check if the fdwReason parameter is DLL_PROCESS_ATTACH, and then check the process name via GetModuleFileName(NULL, szProcess, sizeof(szProcess)). Then decide to load or not. If not, return FALSE from DllMain().
Comment by Mike Myers — Thursday 21 January 2010 @ 23:41
True, I’ve another unreleased DLL doing this. But like you started, I need more flexibility.
Comment by Didier Stevens — Friday 22 January 2010 @ 9:19
[…] as it is loaded inside every process (even at boot time), so please test first. Or else you use LoadDLLViaAppInit, or add it to the import table like explained […]
Pingback by LowerMyRights « Didier Stevens — Monday 11 October 2010 @ 8:41
[…] Filed under: My Software,Update — Didier Stevens @ 9:04 This new version of LoadDLLViaAppInit allows you to load more than one DLL inside a process. You separate the DLL names with a semi-colon […]
Pingback by Update: LoadDLLViaAppInit « Didier Stevens — Tuesday 26 October 2010 @ 9:04
It will only work with executables which load user32.dll. Most malicious applications don’t need user32.dll. Another issue with this approach is, that it will inject in every process, which may produce undesirable results.
http://support.microsoft.com/kb/197571
Comment by bluegene — Wednesday 27 October 2010 @ 16:58
@bluegene I don’t know where you got the idea that this is designed to load DLLs inside malware?
It is not. If you read the older posts I’m referring too, you’ll see that it is designed as an alternative to load DLLs inside user programs you want to protect, like AcroRd32.exe
It will not load in every process, like you said, only in processes that load user32.dll. I’ve discussed alternatives to this method in older posts. Furthermore, this DLL is designed to unload automatically after it has done its work, it will never remain loaded. I coded the DLL to avoid undesirable results. For example, this DLL uses only kernel32 functions. That is why the configuration is written in a text file and not in the registry.
The reason why Microsoft discourages using this key in their KB article, is that they don’t garantee that this feature will be available in newer versions of Windows.
Comment by Didier Stevens — Wednesday 27 October 2010 @ 21:34
[…] is delivered as a dll file. You can make sure the dll gets loaded into every process using LoadDLLViaAppInit or by including the heaplocker dll in the IAT of the application you want to […]
Pingback by Exploit writing tutorial part 11 : Heap Spraying Demystified | Corelan Team — Sunday 1 January 2012 @ 6:53
[…] https://blog.didierstevens.com/2009/12/23/loaddllviaappinit/ […]
Pingback by Persistence – AppInit DLLs | Penetration Testing Lab — Tuesday 7 January 2020 @ 9:39