Cobalt Strike User-Defined Reflective Loader (UDRL) written entirely in Rust. A ~65KB position-independent reflective loader with module stomping, synthetic call stack spoofing, sleep obfuscation (Ekko, FOLIAGE, Zilean, XOR), memory encryption, return address spoofing, IAT hooking, and heap isolation.
Named after DoublePulsar, an implant developed by the NSA's Equation Group, leaked by the Shadow Brokers in 2017.
Unlike Stephen Fewer's original approach where the reflective loader is compiled into the DLL itself as an exported function, DoublePulsar uses the prepended loader architecture where the loader is placed before the Beacon DLL. The loader is fully position-independent shellcode that decrypts and maps the Beacon payload at runtime.
Figure 1: Prepended vs embedded reflective loader architecture (diagram from Revisiting the UDRL Part 1 by Robert Bearsby / Cobalt Strike)
Import the Titan.cna script before generating shellcode. The script:
- Takes your raw Beacon payload
- RC4 encrypts it with a random 16-byte key
- Appends
[CONFIG (key + size)][Encrypted Beacon]to the loader - At runtime, the loader decrypts the Beacon in-memory and executes it
Figure 2: DoublePulsar loader pipeline overview
- Position-independent Rust reflective loader for Cobalt Strike (prepended loader)
- Module stomping (loads Beacon into a legitimate module's memory, enabled by default)
- Synthetic call stack spoofing (randomized per call, enabled by default via
spoof-uwd) - Dynamic memory encryption (isolated heap for Beacon allocations, encrypted during sleep)
- Code obfuscation and encryption (non-executable + encrypted during sleep)
- Return address spoofing via
spoof_uwd!on all hooked API calls - IAT hooking (30+ APIs, fully customizable)
- Heap isolation via
RtlCreateHeap - RC4 encryption via SystemFunction032/040/041
- Optional syscall dispatch (cringe, but it's there 🙄) (
spoof-syscallfeature, requiresspoof-uwd). Uses Hell's Gate for SSN resolution when unhooked, falls back to Halo's Gate / Tartarus Gate when hooks are detected. Dispatches via indirect syscall (jumps to thesyscall; retinstruction inside ntdll) - Does not use Cobalt Strike's Sleepmask or BeaconGate. Sleep obfuscation is handled entirely through IAT hooks
- Multiple sleep obfuscation techniques:
| Feature | Technique | Description |
|---|---|---|
sleep-ekko |
Ekko | Timer-based (TpAllocTimer/TpSetTimer) + RC4 + NtContinue chain + fiber support (default) |
sleep-foliage |
FOLIAGE | APC-based (NtQueueApcThread) + RC4 + NtContinue chain + fiber support |
sleep-zilean |
Zilean | Wait-based (TpAllocWait/TpSetWait) + RC4 + NtContinue chain + fiber support |
sleep-xor |
XOR | XOR section masking + plain Sleep (no CONTEXT chain, no fiber mode) |
x64 only. x86 is not supported.
Recommended: build on Ubuntu/WSL to avoid MinGW relocation issues on Windows.
- Rust nightly with
x86_64-pc-windows-gnutarget - MinGW-w64
- cargo-make
- nasm
# Install Rust nightly and add target
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup toolchain install nightly
rustup default nightly
rustup target add x86_64-pc-windows-gnu
# Install MinGW-w64 and nasm
sudo apt update
sudo apt install -y mingw-w64 nasm
# Install cargo-make
cargo install cargo-make
# Build
cd udrl
cargo make x64cargo make x64 # x64 release
cargo make x64-debug # x64 with debug logging (DbgPrint)
cargo make clean # clean build artifactsOnly enable one sleep feature at a time. They are mutually exclusive. Use --no-default-features when selecting a non-default technique.
# Ekko (default)
cargo make x64
# FOLIAGE
cargo build --release --target x86_64-pc-windows-gnu --features sleep-foliage --no-default-features
# Zilean
cargo build --release --target x86_64-pc-windows-gnu --features sleep-zilean --no-default-features
# XOR (no ROP chain, no fiber)
cargo build --release --target x86_64-pc-windows-gnu --features sleep-xor --no-default-featuresbin/Titan.x64.bin - x64 shellcode
Tested on Windows 10 (Build 19045) and Windows 11 (Build 22631) against Elastic 9.0.1 (trial) in prevention mode with aggressive settings and all rules enabled at the time of writing. Integrations enabled: Elastic Defend, Elastic Agent, Fleet Server, Prebuilt Security Detection Rules, Elastic Synthetics, System, and Windows. Cobalt Strike settings: Stageless Windows Executable, Raw output, x64 payload, Process exit function, winhttp library. YARA rules for detection are provided in doublepulsar.yar. Shortly after the release of this project, in the same month, Elastic published a behavioral rule targeting the call stack patterns produced by SilentMoonwalk-based spoofing implementations like uwd used in DoublePulsar.
- Not compatible with loaders that rely on the shellcode thread staying alive
- Windows builds may encounter relocation errors with newer MinGW versions (use WSL)
- AllocConsole logging can cause crashes when spammed with too many log entries, use DbgPrint instead
stage.cleanuphas known limitations with module stomping
- Austin Hudson for TitanLdr (the original UDRL that inspired AceLdr and DoublePulsar), FOLIAGE (APC-based sleep obfuscation), and titanldr-ng (CNA integration, RC4 beacon encryption/decryption, additional IAT hooks)
- Kyle Avery for AceLdr, which built on Austin Hudson's TitanLdr design and merged FOLIAGE sleep obfuscation with return address spoofing and heap isolation
- Arash Parsa (waldo-irc) for Bypassing PE-sieve and Moneta, Hook heaps and live free, and MalMemDetect
- C5pider for Stardust (PIC framework), Ekko sleep obfuscation (originally discovered by Peter Winter-Smith, implemented in MDSec's Nighthawk), and Zilean sleep obfuscation
- klezVirus, Arash Parsa (waldo-irc), and trickster0 for SilentMoonwalk (call stack spoofing) and Tartarus Gate
- Joao Victor for uwd and hypnus, used as reference for a complete rewrite as position-independent code
- Forrest Orr for Masking malicious memory artifacts
- Raphael Mudge for creating Cobalt Strike and Crystal Palace
- RastaMouse / Zero Point Security for Red Team Ops II and Crystal-Kit
- Alex Reid / Zero Point Security for BOF, UDRL & Sleepmask Development
- namazso for the original x64 return address spoofing technique
- IBM X-Force for Defining the Cobalt Strike Reflective Loader
- Bobby Cooke for BokuLoader
- Robert Bearsby / Cobalt Strike for the Revisiting the UDRL blog series and the prepended loader architecture diagram
- Lorenzo Meacci for Crystal Kit / Tradecraft Garden EDR evasion research
- Dylan Tran for Module Stomping research
- Stephen Fewer for Reflective DLL Injection (2008)
- Nick Landers for sRDI (Shellcode Reflective DLL Injection)
- J. Lospinoso for Gargoyle (timer-based code execution)
- F-Secure for Hunting for Gargoyle
- Elastic for Detecting Cobalt Strike with memory signatures
- MDSec Nighthawk study for Ekko sleep obfuscation research
- am0nsec for Hell's Gate
- Equation Group / NSA for the original DoublePulsar implant concept
License: MIT. See LICENSE
Liability: The author assumes no responsibility for misuse, damages, or legal consequences arising from the use of this software. Users are solely responsible for ensuring compliance with all applicable laws, regulations, and organizational policies. By using this software, you agree that you have proper authorization for any systems you interact with.

