base on For when DLLMain is the only way <div align="center">
<a href="https://github.com/ElliotKillick/LdrLockLiberator">
<img width="160" src="logo.webp" alt="Logo" />
</a>
</div>
<h2 align="center">
LdrLockLiberator
</h2>
<p align="center">
For when <b>DLLMain</b> is the only way
</p>
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"](https://elliotonsecurity.com/perfect-dll-hijacking) article. We give you the <b>key</b> 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!](https://github.com/ElliotKillick/windows-vs-linux-loader-architecture#the-root-of-dllmain-problems).
## Techniques
### LdrFullUnlock
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.
### Escaping at the Exit
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 <b>100% safe</b> by pinning (`LDR_ADDREF_DLL_PIN`) our library using `LdrAddRefDll` so a following `FreeLibrary` won't remove our DLL from memory.
### Using Locks to Our Advantage
Coming soon!
## Samples
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!
## Compilation
### Visual Studio
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`.
### WDK
#### Installing the Correct WDK
1. Go to the [WDK download page](https://learn.microsoft.com/en-us/windows-hardware/drivers/other-wdk-downloads#step-2-install-the-wdk)
2. Click on the Windows 7 [WDK 7.1.0](https://www.microsoft.com/en-us/download/confirmation.aspx?id=11800) 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`
3. Mount the downloaded ISO then run `KitSetup.exe`
4. Click through the installation process using the default options
#### Compiling
1. In the Start menu, search for "x64 Free Build Environment" then open it
2. Navigate (using `cd`) to `LdrLockLiberatorWDK` in this repo
3. Run `build`
Done! Your DLL is built and ready for use!
As an alternative to WDK, compiling with MinGW would also probably work.
## License
MIT License - Copyright (C) 2023-2024 Elliot Killick <
[email protected]>
", Assign "at most 3 tags" to the expected json: {"id":"4449","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"