For when DLLMain is the only way
LdrLockLiberator is a collection of techniques for escaping or otherwise forgoing Loader Lock while executing your code from DllMain
or anywhere else the lock may be present. It was released in conjunction with the "Perfect DLL Hijacking" article. We give you the key to unlock the library loader and do what you want with your loader (on your own computer)!
The techniques are intended to be universal, clean, and 100% safe where possible. They're designed to work without modifying memory protection or pointers. This is important for staying compatible with modern exploit mitigations. The only officially supported architecture is x86-64 (32-bits is largely extinct).
Want to learn the architectural reasons as to why DllMain
is so troublesome on Windows whereas Unix-like operating systems don't struggle here? Please, be my guest!.
It's exactly what it sounds like. Unlock Loader Lock, set loader events, and flip LdrpWorkInProgress
. It's recommended to keep RUN_PAYLOAD_DIRECTLY_FROM_DLLMAIN
undefined for the best stability.
DO NOT USE THIS TECHNIQUE IN PROUDCTION CODE. This was created as a byproduct of my sheer curiosity and will to leave no stone unturned. Anything you do with this code is on you.
We use the CRT atexit
typically used by EXEs in our DLL code to escape Loader Lock when the program exits. For dynamic loads (using LoadLibrary), this is made 100% safe by pinning (LDR_ADDREF_DLL_PIN
) our library using LdrAddRefDll
so a following FreeLibrary
won't remove our DLL from memory.
Coming soon!
The provided samples hijack MpClient.dll
from C:\Program Files\Windows Defender\Offline\OfflineScannerShell.exe
. Instructions are provided in the source code comments to easily adapt this for any other DLL and program pairing (primarily just updating the exports for static loads)!
As a proof of concept, we run ShellExecute
as the default payload. However, you can make this do anything you want!
The LdrLockLiberator.c
at the root of this project has been tested to compile on Visual Studio 2022.
Link to NTDLL by selecting the current Visual Studio project in the Solution Explorer window, then navigating to Project > Properties
in the menu bar. From the drop-down Configuration
menus at the top, select All Configurations
and All Platforms
. Now, go to Linker > Input
then append to Additional Dependencies
: ntdll.lib
.
- Go to the WDK download page
- Click on the Windows 7 WDK 7.1.0 link to start download the correct WDK version
- This is the last public WDK that officially supports linking to the original MSVCRT (
C:\Windows\System32\msvcrt.dll
) - SHA-256 checksum:
5edc723b50ea28a070cad361dd0927df402b7a861a036bbcf11d27ebba77657d
- Mount the downloaded ISO then run
KitSetup.exe
- Click through the installation process using the default options
- In the Start menu, search for "x64 Free Build Environment" then open it
- Navigate (using
cd
) toLdrLockLiberatorWDK
in this repo - Run
build
Done! Your DLL is built and ready for use!
As an alternative to WDK, compiling with MinGW would also probably work.
MIT License - Copyright (C) 2023-2024 Elliot Killick [email protected]