> Windows Syscalls
ntoskrnl.exeT1106T1562

NtTraceEvent

Schreibt ein User-Mode-Event über ein registriertes Trace-Handle in eine ETW-Sitzung.

Prototyp

NTSTATUS NtTraceEvent(
  HANDLE TraceHandle,
  ULONG  Flags,
  ULONG  FieldSize,
  PVOID  Fields
);

Argumente

NameTypeDirDescription
TraceHandleHANDLEinTrace-/Registrierungs-Handle, von EtwRegister (oder kernelseitigem EtwRegister) erhalten.
FlagsULONGinEvent-Flags. ETW_NT_FLAGS_TRACE_HEADER (0x00400000) markiert Fields als komplettes EVENT_HEADER.
FieldSizeULONGinGesamtgröße in Bytes des von Fields adressierten Puffers.
FieldsPVOIDinZeiger auf einen EVENT_HEADER, gefolgt von EVENT_DATA_DESCRIPTOR für die Event-Nutzlast.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x5Ewin10-1507
Win10 16070x5Ewin10-1607
Win10 17030x5Ewin10-1703
Win10 17090x5Ewin10-1709
Win10 18030x5Ewin10-1803
Win10 18090x5Ewin10-1809
Win10 19030x5Ewin10-1903
Win10 19090x5Ewin10-1909
Win10 20040x5Ewin10-2004
Win10 20H20x5Ewin10-20h2
Win10 21H10x5Ewin10-21h1
Win10 21H20x5Ewin10-21h2
Win10 22H20x5Ewin10-22h2
Win11 21H20x5Ewin11-21h2
Win11 22H20x5Ewin11-22h2
Win11 23H20x5Ewin11-23h2
Win11 24H20x5Ewin11-24h2
Server 20160x5Ewinserver-2016
Server 20190x5Ewinserver-2019
Server 20220x5Ewinserver-2022
Server 20250x5Ewinserver-2025

Kernel-Modul

ntoskrnl.exeNtTraceEvent

Verwandte APIs

EventWriteEventWriteExEventWriteTransferEventRegisterEtwEventWriteTraceEventNtTraceControl

Syscall-Stub

4C 8B D1                  mov r10, rcx
B8 5E 00 00 00            mov eax, 0x5E
F6 04 25 08 03 FE 7F 01   test byte ptr [0x7FFE0308], 1
75 03                     jne short +3
0F 05                     syscall
C3                        ret
CD 2E                     int 2Eh
C3                        ret

Undokumentierte Hinweise

Der Kernel-Einstiegspunkt hinter jedem User-Mode-ETW-*Write*. `EventWrite`, `EventWriteEx`, `EventWriteTransfer`, `EtwEventWrite` und die automatisch generierten TraceLogging-Emitter münden alle in `ntdll!EtwEventWriteFull` → `NtTraceEvent`. Das TraceHandle ist *kein* Sitzungs-Handle — es ist das pro Provider von `EtwRegister` zurückgegebene Registrierungs-Handle, und der Kernel läuft die Enable-Mask des Providers durch, um zu entscheiden, welche Sitzungen das Event empfangen. Seine SSN ist von Windows 10 1507 bis Windows 11 24H2 und Server 2025 `0x5E` geblieben — eine der stabilsten Syscall-Nummern im System, vermutlich weil sie auf dem Hot-Path jeder Microsoft-Telemetrie liegt.

Häufige Malware-Nutzung

Direkter offensiver Wert begrenzt — der Aufruf schreibt Events, die Verteidiger *sehen können*. Interessant ist die Umkehrung: Implants, die einen privaten Logging-Kanal wollen, registrieren absichtlich eine Provider-GUID, die niemand sammelt, und rufen `NtTraceEvent`, um Runtime-Debug in eine Sitzung zu kritzeln, die kein SOC abonniert. Manche Loader emittieren so auch Pseudo-`Microsoft-Windows-*`-Events zur Verdünnung von Hunt-Queries. Weit mehr Aufmerksamkeit gilt der *Unterdrückung* von Writes (siehe `NtTraceControl`) als dem direkten Missbrauch dieses Aufrufs. Einige EDR-Evasion-Notizen erwähnen das Überschreiben von `EtwEventWrite` mit `ret` in ntdll, was die User-Mode-Seite genau dieses Pfads zusammenbrechen lässt.

Erkennungs­möglichkeiten

Für sich allein ist `NtTraceEvent` reines Rauschen — jede Office-App, jeder Browser-Tab, jeder Windows-Dienst feuert Tausende pro Sekunde. Entscheidend ist die *Abwesenheit* erwarteter Events aus einem Prozess, dessen ntdll gepatcht wurde (z. B. erstes Byte von `EtwEventWrite` = `0xC3`). Vergleichen Sie In-Memory-ntdll-Bytes gegen die Disk-Version für die vier klassischen ETW-Write-Stubs (`EtwEventWrite`, `EtwEventWriteFull`, `EtwEventWriteEx`, `EtwEventWriteTransfer`); jede Abweichung ist hochrelevant. Auf Sitzungsebene sind Log-Lücken bei den Providern `Microsoft-Windows-Threat-Intelligence` und `Microsoft-Windows-Kernel-Process`, korreliert zu Prozesserzeugungen, das klassische Indiz für einen ETW-Bypass.

Direkte Syscall-Beispiele

cTraceLogging write via EventWriteTransfer

// Standard TraceLogging path — ultimately calls NtTraceEvent.
#include <windows.h>
#include <evntprov.h>

static const GUID kImplantProvider =
    { 0x11111111, 0x2222, 0x3333, { 0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB } };

REGHANDLE hReg = 0;
EventRegister(&kImplantProvider, NULL, NULL, &hReg);

EVENT_DESCRIPTOR ed = { 0 };
ed.Id = 1; ed.Level = 4; // Information

EVENT_DATA_DESCRIPTOR edd;
const wchar_t* msg = L"beacon-checkin";
EventDataDescCreate(&edd, msg, (ULONG)((wcslen(msg) + 1) * sizeof(wchar_t)));

// Funnels through ntdll!EtwEventWriteFull -> NtTraceEvent.
EventWriteTransfer(hReg, &ed, NULL, NULL, 1, &edd);

asmx64 direct stub (SSN 0x5E, stable across all builds)

NtTraceEvent PROC
    mov  r10, rcx
    mov  eax, 5Eh
    syscall
    ret
NtTraceEvent ENDP

rustStealth provider with windows-sys

// Cargo: windows-sys = { version = "0.59", features = ["Win32_System_Diagnostics_Etw"] }
use windows_sys::Win32::System::Diagnostics::Etw::*;
use windows_sys::core::GUID;

const PROVIDER: GUID = GUID::from_u128(0x11111111_2222_3333_4455_66778899AABB);

unsafe fn beacon_log(msg: &[u8]) {
    let mut hreg: u64 = 0;
    EventRegister(&PROVIDER, None, std::ptr::null_mut(), &mut hreg);

    let ed = EVENT_DESCRIPTOR { Id: 1, Level: 4, ..core::mem::zeroed() };
    let mut edd = EVENT_DATA_DESCRIPTOR { Ptr: msg.as_ptr() as u64, Size: msg.len() as u32, Reserved: 0 };
    EventWrite(hreg, &ed, 1, &mut edd);
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20