Skip to content
All posts
miscrevised April 10, 20264 min read

What the endpoint sees: ETW, AMSI, and userland hooks

Blue-team and detection challenges ask you to reason about how code gets watched on Windows. The three telemetry sources - ETW, AMSI, and inline API hooks - what each one records, and why evasion challenges target them.

A growing category of CTF - detection engineering, blue-team, purple-team challenges - asks a question most offensive players never think about: when a program runs on Windows, who is watching, and what do they see? Understanding endpoint telemetry is what lets you answer both 'write a detection for this behaviour' and its mirror, 'why did this malicious sample go unnoticed'. The same knowledge underlies the evasion challenges on the red side.

Modern endpoint detection and response (EDR) is not magic. It draws from a small number of well-defined telemetry sources, each of which records a specific slice of what a program does. Know the three big ones and you can reason precisely about what is and is not visible.

1. ETW - the system's built-in event firehose

Event Tracing for Windows is a logging framework baked into the OS. Hundreds of providers emit structured events - process creation, network connections, DNS queries, .NET assembly loads, PowerShell script blocks, WMI activity. EDRs subscribe to the security-relevant providers and this is where a large fraction of their visibility comes from. If you are writing a detection, ETW is usually the source; if you are studying an evasion, ETW is usually what got tampered with.

  • Microsoft-Windows-Threat-Intelligence - a kernel ETW provider that reports the sensitive operations (certain memory allocations, injection primitives) userland malware relies on. The high-value source, which is why it is protected.
  • PowerShell ScriptBlock logging - records the actual script text executed, defeating simple obfuscation because the deobfuscated block is what gets logged.
  • .NET / CLR provider - logs assembly loads, catching in-memory .NET tradecraft.

2. AMSI - the script-content inspector

The Antimalware Scan Interface is a hook point where script hosts (PowerShell, JScript, VBScript, and Office macros) hand their content to the installed antivirus for a verdict just before execution - after any deobfuscation the script did to itself. This is what catches a malicious PowerShell command even when it arrives base64-encoded and layered: AMSI sees the final, cleartext script.

AMSI is the reason 'just encode it' stopped working for script-based payloads, and the reason a whole family of challenges is about AMSI bypass - patching amsi.dll in memory, or splitting a flagged string so the buffer AMSI scans never contains the full signature. As a detection author, an AMSI bypass attempt has its own recognisable footprint (a write to amsiScanBuffer, specific byte patches) that you can hunt for.

# The concept behind a string-splitting AMSI evasion (why detections
# look for reassembly, not the literal signature):
$a = 'Amsi' + 'Utils'        # the flagged token never appears whole in one buffer
# Detection flips this around: look for the reassembly pattern and the
# in-memory patch of amsi.dll, not for the signature string itself.
Evasion and detection are two readings of the same mechanism - which is exactly what purple-team challenges test.

3. Userland API hooks - the up-close view

Many EDRs inject a DLL into every process that overwrites the first instructions of sensitive API functions (in ntdll.dll) with a jump to the EDR's own code. When the program calls, say, a memory-allocation or process-injection API, the EDR sees the call, its arguments, and can block it. This is the most intimate telemetry - it sees calls before they reach the kernel.

It is also the most tamperable, which drives its own challenge genre. Because the hooks live in the process's own copy of ntdll, the program can undo them: read a clean copy of ntdll from disk and overwrite the hooked bytes ('unhooking'), or skip ntdll entirely by invoking the system call directly ('direct syscalls'). For a detection challenge, the tell is a process whose ntdll no longer matches the on-disk version, or syscalls originating from outside ntdll's address range.

Reasoning about a challenge

Whether the task is offensive or defensive, the method is the same: identify which telemetry source is in play, then reason about what it records and where it can be tampered.

  1. Script-based payload (PowerShell/macro)? AMSI and ScriptBlock logging are the visibility; the challenge is content-level.
  2. In-memory or injection tradecraft? ETW-TI and userland hooks are the visibility; the challenge is API-level.
  3. For a detection ask: what event does the behaviour emit, and what does a normal process's baseline look like?
  4. For an evasion ask: which of the three sources sees this, and can the process blind that source from inside itself?
  5. For a hunt: look for the tamper artifact - a silent process, a patched amsi.dll, an ntdll that does not match disk.