UNHOOKING
DIRECT SYSCALLS
INDIRECT SYSCALLS
FRESH NTDLL
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting EDR Unhooking and Direct and Indirect Syscalls

User-mode hooks only work if attackers walk through them. Unhooking and raw syscalls are ways to walk around, and the detours are visible from the kernel and the call stack.

Scroll

Many EDR sensors place user-mode hooks in ntdll.dll. Offensive tooling removes them by overwriting the hooked code with a clean copy from disk, a suspended process or the KnownDlls section, or avoids them altogether with direct syscalls (a syscall instruction in the tool’s own code) and indirect syscalls (jumping to the instruction inside ntdll). Each variant leaves artifacts that do not depend on the hooks it evades.

Signals at a Glance

SignalWhereATT&CK
A second, clean copy of ntdll read from disk or mapped from KnownDllsFile-read auditing, EDR section telemetryT1562.001
ntdll.dll loaded or created outside System32 or SysWOW64Sysmon 7, Sysmon 11T1562.001
Write over the ntdll .text section of the current processEDR memory telemetry, Threat-Intelligence ETWT1562.001
syscall instruction executing from a non-ntdll module or private memoryKernel instrumentation callback, EDRT1106
Call stack to a sensitive syscall that skips expected user-mode framesETW stack walk, EDRT1106

Spotting Unhooking

Overwriting hooks requires a source of clean bytes, and getting them is the loud part. Reading ntdll.dll from System32 by a process that is not the loader, opening the \KnownDlls\ntdll.dll section, or spawning a suspended process just to copy its ntdll are all uncommon. Where you cannot see reads, catch copies and unusual loads:

title: ntdll.dll Loaded or Created Outside System Directories
logsource:
  product: windows
  category: image_load
detection:
  selection:
    ImageLoaded|endswith: '\ntdll.dll'
  filter_system:
    ImageLoaded|startswith:
      - 'C:\Windows\System32\'
      - 'C:\Windows\SysWOW64\'
      - 'C:\Windows\WinSxS\'
  condition: selection and not filter_system
level: high
# tune/validate: crash-dump tooling and some forensic utilities load copies of ntdll.

Spotting Direct and Indirect Syscalls

A direct syscall stub in tool code has a small fixed shape: move the first argument to r10, load the service number into eax, and execute syscall. Legitimate Windows code almost always makes that call from within ntdll or win32u. Scan for the shape in modules that are neither:

rule Syscall_Stub_Outside_Ntdll
{
    meta:
        description = "x64 syscall stub pattern (mov r10, rcx; mov eax, N; syscall; ret)"
        note = "tune/validate: scan non-system modules and memory only; expect noise in runtimes"
    strings:
        $stub = { 4C 8B D1 B8 ?? ?? 00 00 0F 05 C3 }
        $stub_test = { 4C 8B D1 B8 ?? ?? 00 00 F6 04 25 08 03 FE 7F 01 75 03 0F 05 C3 }
    condition:
        uint16(0) == 0x5A4D and (#stub > 3 or #stub_test > 3)
}

Indirect syscalls hide from the pattern by jumping into ntdll for the final instruction, so the return address looks legitimate. The remaining tell is the stack above it:

Vetted sources

Use the SigmaHQ image-load rules for ntdll, Elastic’s detections for ntdll unhooking and syscall abuse, MITRE ATT&CK T1562.001 and T1106, and public research on SysWhispers-style stubs to refine YARA. Atomic Red Team and lab loaders let you confirm what your EDR sees. Baseline your own environment — developer tools and crash handlers have legitimate reasons to map ntdll.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026