Tuesday, October 13, 2026

Inside NTDLL-reconstruction: flipping between hooked and clean ntdll stubs on demand

Inside NTDLL-reconstruction: flipping between hooked and clean ntdll stubs on demand

NTDLL-reconstruction is a small C library demonstrating a userland EDR evasion technique that lets an operator flip between hooked and unhooked ntdll.dll syscall stubs at will, primarily for red-team research and defensive education.

Toolsk4r4b/NTDLL-reconstruction — a C library for flipping a process between hooked and unhooked ntdll.dll syscall stubs
CategoryUserland EDR bypass / Windows internals research (syscall technique)
Primary UseRed-team operators and malware researchers studying how a process can alternate between the instrumented ntdll.dll loaded by an EDR and a reconstructed clean copy via ntdll_reconstruction_flip()
Safe UseEducational and documentary analysis for authorized red-team engagements, isolated lab environments, and defensive engineers designing hook-integrity telemetry; not for use against systems you do not own or are not contracted to test
Telemetry NoteThe flip operation necessarily toggles memory protections on syscall stub regions, which is exactly the observable defenders should key on: allocation/protection changes around the ntdll.dll text section, unbacked executable memory, and VirtualProtect-style transitions on ntll pages are classic detection angles for this class of technique

sk4r4b/NTDLL-reconstruction is a compact C project, sitting at 23 stars on GitHub, that implements a userland EDR bypass technique the author describes as allowing a process to flip between an unhooked and a hooked ntdll.dll at will. The name deliberately evokes two well-established families of offensive Windows research: NTDLL unhooking, where a clean copy of the DLL's syscall stubs is recovered to escape usermode hooks, and Hell's Gate-style dynamic syscall number resolution. Rather than picking one, the project merges the ideas into a stateful primitive, and that statefulness is what makes it interesting to analyze.

Most unhooking approaches are one-shot: you grab a pristine ntdll.dll — typically by mapping it from disk via LoadLibrary on a known-good copy — copy the .text section over the hooked stubs, and carry on. The README frames this project differently. Instead of permanently replacing the EDR-instrumented stubs, the library maintains a struct hook_cache and exposes ntdll_reconstruction_flip(cache), which alternates the process between what the author calls the hooked stub and the clean stub. This ping-pong model is conceptually notable because it lets a payload keep the EDR's view of the process intact for the majority of its lifetime, dropping to clean syscalls only for the narrow windows where direct syscall execution is required.

The public interface is minimal and honest about that. The README shows an initialization call, ntdll_reconstruction_init(), which returns a pointer to the hook_cache structure or a null on failure, and then a loop where ntdll_reconstruction_flip(cache) is called repeatedly to swing back and forth between states, with Sleep(1234) pacing the demo. The error handling idiom — checking the returned cache pointer and throwing on null — is spelled out explicitly, which tells you the author expects the flip to be fallible in practice, likely around memory protection transitions or mapping failures.

Integration is deliberately manual, which is itself a design signal. Rather than shipping a build system or a prebuilt binary, the README instructs you to drag and drop the .h and .c files into your own project. Two implementation gaps are explicitly left to the integrator: the header-file definitions for CRT functions, which you must either reimplement yourself or source from your preferred runtime strategy, and the switch_memory_protection function inside the .c file, which the author states you must implement yourself for the project to work correctly. This is a common pattern in evasion research code — keeping the memory-protection primitive external so the library stays portable across toolchains and avoids depending on a specific VirtualProtect-flavored implementation that would itself be a detection signature.

The switch_memory_protection requirement is the most analytically revealing detail in the README. Flipping between hooked and clean stubs means changing page attributes on executable memory that the EDR believes it owns — typically toggling between read-execute and read-write states so the stub bytes can be swapped or remapped. By refusing to hardcode that operation, the library sidesteps committing to VirtualProtect, VirtualProtectEx, or an NtProtectVirtualMemory-based approach, all of which carry different telemetry profiles. An authorized operator integrating this would choose the primitive that best matches their engagement's evasion requirements; a defender reading the same code learns exactly which API surfaces to monitor for this behavior class.

From a defensive perspective, the technique's core trade-off is instructive. Permanent unhooking gives an EDR zero visibility into every subsequent native call, but it also produces a stable, scannable artifact: a .text section in ntdll.dll that no longer matches the on-disk image, which integrity checks readily flag. The flip model reduces the window during which the process is in a divergent state, but each transition multiplies the number of memory-protection events on the same pages. That asymmetry is where detection lives: sustained, repeated protection changes on the ntdll image's executable region are anomalous regardless of how brief each unhooked interval is, and EDR vendors increasingly baseline exactly this kind of page-level churn.

The lineage the README gestures at is worth understanding for context. Hell's Gate, and its many descendants, resolve syscall numbers at runtime by parsing the stub opcodes of ntdll.dll in memory, dodging hardcoded SSN tables that break across Windows builds. Classic unhooking instead restores the physical stub bytes. A project described as mixing unhooking with Hell's Gate variants is presumably using the clean, reconstructed stubs not merely for direct execution but as a trustworthy source for syscall-number extraction — the reconstructed region gives you unhooked opcodes to parse, while the ability to flip back means the EDR's hooks are restored when you are done reading them. The README does not spell out the internal mechanics in detail, but the author links a companion blog post at hxxps://leosmith.wtf/blog/ntdll_reconstruction.html documenting how it was built, which is the right place to verify the internals rather than guessing.

Where this fits in an authorized workflow is narrow but real: detection-engineering teams building coverage for unhooking behavior, red teams validating whether their EDR target catches transient stub manipulation, and malware analysts mapping the current ecosystem of direct-syscall techniques. The code is written in plain C with no license file at the time of review, which matters if you plan to embed it in a proprietary toolkit — treat it as research code until licensing is clarified, and note the repository carries no topics or formal release artifacts, reinforcing its proof-of-concept character.

Caveats for anyone evaluating maturity: the README is short, there is no test suite, no build instructions beyond copy-paste integration, and two critical functions are left as exercises. None of that is damning for a technique demonstration — most evasion research on GitHub ships exactly this way — but it does mean the burden of correctness sits entirely on the integrator. A malformed switch_memory_protection implementation or a mishandled hook_cache will crash the process or, worse from an operational standpoint, leave the ntdll.dll image permanently diverged and trivially detectable.

As a documentary specimen, NTDLL-reconstruction is a clean, readable example of where userland evasion research is heading: away from static bypasses and toward stateful, reversible manipulation of the EDR's own instrumentation. For defenders, the takeaway is that hook-based visibility should never be the only layer — kernel-assisted syscall inspection, image-integrity comparison against the on-disk ntdll.dll, and behavioral baselining of page-protection events all address this flip-style model. For authorized offensive professionals, it is a compact building block worth studying before reuse, ideally alongside the author's companion writeup for the full construction narrative.

Official project repository for sk4r4b/NTDLL-reconstruction.
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.