Thursday, October 29, 2026

Inside ReflectiveDLLRefresher: how Cylances research project strips security hooks from memory

Inside ReflectiveDLLRefresher: how Cylance's research project strips security hooks from memory

ReflectiveDLLRefresher is a proof-of-concept research toolkit from CylanceVulnResearch that scans a process's own memory and restores clean copies of hooked libraries, published for authorized red-team and defensive study.

ToolCylanceVulnResearch/ReflectiveDLLRefresher — reflective DLL that unhooks libraries loaded in process memory, with modified UPX, TLS-injection and Meterpreter integrations
CategoryWindows evasion research / memory manipulation toolkit (C)
Primary UseDemonstrating userland-hooking evasion by rescanning a process's memory space and refreshing hooked DLLs such as ntdll.dll in a lab environment
Safe UseStrictly for authorized penetration tests, malware-research labs, and defensive teams validating that userland hooking is not relied on as a sole control
Telemetry NoteUnhooking is observable by defenders via kernel-backed telemetry: comparing on-disk DLL exports against in-memory images, EDR callback telemetry, injection events from Inject.exe, and UPX-packed entropy anomalies

ReflectiveDLLRefresher is one of the most instructive artifacts in the userland-unhooking genre, published by CylanceVulnResearch not as a turnkey weapon but as a demonstration of a defensive weakness. The core insight it encodes is simple and important: many endpoint products enforce policy by patching the first bytes of exported functions inside DLLs that are already mapped into a process, and those patches live in user-modifiable memory. A reflective DLL that rescans its own process space and refreshes the hooked libraries from clean on-disk copies can therefore revert that instrumentation, which is why mature detection strategies cannot depend on userland hooks alone.

The repository's centerpiece is the reflective DLL itself, which the README describes as scanning the process's memory space and unhooking the currently loaded libraries. The reflective part matters: the DLL carries its own loader logic, so it maps and relocates itself when invoked rather than relying on the standard Windows loader, leaving a smaller footprint in the loader lock and PEB module lists than a conventional LoadLibrary path would. That property is exactly what makes it a useful research subject for defenders who want to understand why unlinked module enumeration matters in memory forensics.

For standalone experimentation, the project ships DLLRefresher.exe, a test harness that performs the scan-and-unhook sequence in the current process. This is the component to study first in a lab: run it under a debugger or a monitoring harness and observe which regions of which libraries change, which exports are touched, and what memory-allocation patterns the refresh produces. Because it operates on its own process rather than a foreign target, it is a comparatively safe way to characterize the technique before building detections against it.

The second component is a fork of UPX, maintained at CylanceVulnResearch/upx on the reflective_dll branch, which adds an -X <path/to/target.dll> parameter. When the packer runs, it embeds the specified DLL into the packed output; at runtime the stub unpacks the executable in memory, invokes the embedded DLL, and then transfers control to the original entry point. The practical shape of the invocation is upx -o packed_binary.exe -X ReflectiveDLL.x86.dll target_binary.exe, and the significance for defenders is that the unpacking-plus-unhooking sequence happens entirely in memory before the host binary's main even runs, which frustrates static inspection and post-launch hooking alike.

The Meterpreter integration is where the project crosses from generic research into offensive tooling territory, and it deserves a sober read. The repository provides a modified metsrv.dll plus associated extension DLLs that unhook loaded libraries before meterpreter initializes, so a session comes up in an environment where security-product hooks have already been neutralized. The README explains that the files drop into metasploit-framework/data/meterpreter/ and are used with a standard handler configuration such as windows/x64/meterpreter/reverse_tcp. From a defender's perspective, the takeaway is that implant frameworks can be recompiled with pre-initialization unhooking, so hook tampering should be treated as a high-fidelity alert rather than an assumed-impossible event.

Alongside the implant-side work, the repo includes Inject.exe, a small utility that injects a named DLL into a process identified by PID, for example Inject.exe 2964 ReflectiveDLLRefresher.x86.dll. There is also an integration path through the Metasploit post-exploitation module post/windows/manage/reflective_dll_inject, which loads the DLL into an existing session's process and executes its reflective loader. These components are operational in nature, which is precisely why they belong in an authorized lab: they let a red team or detection-engineering group exercise the technique end to end against instrumented test hosts rather than speculate about it.

The most conceptually interesting piece for students of the PE format is tlsInjector.py, described as a modified version of Borja Merino's script extended to support reflective DLL injection. It takes a reflective DLL and embeds it into the TLS section of a 32-bit executable — the README notes 64-bit is not supported — so that the DLL executes via the TLS callback mechanism before the image's regular entry point. TLS callbacks are a classic early-execution primitive, and pairing one with reflective loading demonstrates how code can run before conventional breakpoint targets, an important consideration when instrumenting analysis environments.

Architecturally, the project is a small ecosystem rather than a single binary: the unhooking DLL, the harness, the injector, the packer fork, and the meterpreter rebuilds all exercise the same primitive from different delivery vectors. For detection engineering, that breadth is the lesson. The delivery mechanism varies — packed stub, TLS callback, Inject.exe, metasploit post module — but the observable core is consistent: a process re-mapping or overwriting pages of libraries that were already loaded, typically restoring pristine on-disk content over patched prologues. Counting on any one hook to survive that is not a strategy.

For authorized teams, the highest-value use of ReflectiveDLLRefresher is purple-team validation. Red operators can confirm whether their tooling survives the environment; blue analysts can then verify that kernel- or hypervisor-backed telemetry — like module-stomping detection, export-table comparison between disk and memory, and alerts on unexpected self-modification of mapped images — actually fires. If your product's story ends at userland hooks, this repo is the canonical evidence that the story is incomplete, and reviewing it costs an afternoon in a snapshot lab.

One caveat worth stating plainly: the repository carries a NOASSERTION license, 324 stars, and is written in C, but it is old research code by a vendor vulnerability-research team, and portions like the Meterpreter integrations are closer to weaponized samples than library-grade tooling. Treat the binaries as untrusted, build in an isolated VM, and never point the injector or implant at systems outside your owned and authorized test range. Used that way, it remains one of the cleanest public demonstrations of the hook-versus-unhook arms race on Windows.

Official project repository for CylanceVulnResearch/ReflectiveDLLRefresher.
Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.

Share articleFacebookXLinkedIn

Continue exploring

Browse all articles →

0 comentários:

Post a Comment

Note: Only a member of this blog may post a comment.