NtCreateEvent
Erzeugt ein benanntes oder unbenanntes Event-Synchronisationsobjekt und liefert ein Handle.
Prototyp
NTSTATUS NtCreateEvent( PHANDLE EventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, EVENT_TYPE EventType, BOOLEAN InitialState );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| EventHandle | PHANDLE | out | Erhält bei Erfolg das Handle auf das neu erzeugte Event-Objekt. |
| DesiredAccess | ACCESS_MASK | in | Zugriffsmaske, z. B. EVENT_ALL_ACCESS, EVENT_MODIFY_STATE, SYNCHRONIZE. |
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Optionale Objektattribute. NULL für unbenannt; für IPC einen Namen unter \BaseNamedObjects angeben. |
| EventType | EVENT_TYPE | in | NotificationEvent (manuelles Reset) oder SynchronizationEvent (Auto-Reset). |
| InitialState | BOOLEAN | in | TRUE wenn das Event initial signalisiert ist, sonst FALSE. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x48 | win10-1507 |
| Win10 1607 | 0x48 | win10-1607 |
| Win10 1703 | 0x48 | win10-1703 |
| Win10 1709 | 0x48 | win10-1709 |
| Win10 1803 | 0x48 | win10-1803 |
| Win10 1809 | 0x48 | win10-1809 |
| Win10 1903 | 0x48 | win10-1903 |
| Win10 1909 | 0x48 | win10-1909 |
| Win10 2004 | 0x48 | win10-2004 |
| Win10 20H2 | 0x48 | win10-20h2 |
| Win10 21H1 | 0x48 | win10-21h1 |
| Win10 21H2 | 0x48 | win10-21h2 |
| Win10 22H2 | 0x48 | win10-22h2 |
| Win11 21H2 | 0x48 | win11-21h2 |
| Win11 22H2 | 0x48 | win11-22h2 |
| Win11 23H2 | 0x48 | win11-23h2 |
| Win11 24H2 | 0x48 | win11-24h2 |
| Server 2016 | 0x48 | winserver-2016 |
| Server 2019 | 0x48 | winserver-2019 |
| Server 2022 | 0x48 | winserver-2022 |
| Server 2025 | 0x48 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 48 00 00 00 mov eax, 0x48 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
Erzeugt ein Executive-Event-Objekt über ObCreateObject + KeInitializeEvent in ntoskrnl.exe. SSN `0x48` ist über jeden Win10- und Win11-Build bislang stabil. Zwei `EVENT_TYPE`-Werte sind relevant: `NotificationEvent` bleibt bis zum manuellen Reset signalisiert (Broadcast-Semantik), während `SynchronizationEvent` nach Freigabe eines einzelnen Waiters automatisch zurückgesetzt wird (Semaphor-mit-Eins-Semantik). Wird in `ObjectAttributes` ein Name unter `\BaseNamedObjects` angegeben, wird das Event zu einer prozessübergreifenden IPC-Primitive — jeder Prozess, der den Namen mit `NtOpenEvent` öffnen kann, teilt sich dasselbe Kernelobjekt.
Häufige Malware-Nutzung
Dient als Synchronisationsrückgrat moderner Sleep-Masks (Ekko, Foliage, Cronos, Zilean): der Implant erzeugt ein Auto-Reset-Event, reiht einen Timer ein, dessen APC-Routine es signalisiert, und wartet in einem alertable Wait darauf — sodass die ROP-Kette die Implant-Region zwischen Beacons neu verschlüsseln kann. Bildet zudem die Hälfte von Named-Pipe-und-Event-C2-Designs (Brute Ratel C4, Sliver-Pivot-Pipes), bei denen das benannte Event „Befehl verfügbar" ohne Polling-Schleife signalisiert. Ein signalisiertes benanntes Event ist außerdem ein verbreiteter Single-Instance-Check.
Erkennungsmöglichkeiten
Event-Erzeugung ist in jedem Windows-Prozess sehr häufig und für sich kein brauchbares Signal. Erkennung konzentriert sich auf *Name* und *Handle-Besitzer*: Events mit Namen wie `Global\<random-guid>`, prozessübergreifend von Nicht-System-Parents geöffnet, oder Events, deren Handle ein Prozess hält, der zugleich eine beschreibbare Section und einen Timer hält (die Ekko-Triade). Sysmon protokolliert Event-Erzeugung nicht direkt; ETW `Microsoft-Windows-Kernel-Object` und Object-Manager-Handle-Audits lassen sich selektiv aktivieren. EDRs, die Handle-Tabellen bei Suspend-/Sleep-Übergängen durchgehen, erkennen das Sleep-Mask-Muster zuverlässig.
Direkte Syscall-Beispiele
asmx64 direct stub
; Direct syscall stub for NtCreateEvent (SSN 0x48, stable across Win10/11)
NtCreateEvent PROC
mov r10, rcx ; syscall convention
mov eax, 48h ; SSN
syscall
ret
NtCreateEvent ENDPcEkko sleep-mask event setup
// Auto-reset event signalled by a timer APC; waited on alertably to drive the chain.
HANDLE hEvent = NULL;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0 };
NTSTATUS st = NtCreateEvent(&hEvent,
EVENT_ALL_ACCESS,
&oa,
SynchronizationEvent,
FALSE);
if (!NT_SUCCESS(st)) return st;
// hEvent is now the rendezvous point between the implant thread and the timer APC.rustwindows-sys named event for single-instance
// Cargo: windows-sys = "0.59" (Win32_System_Threading)
use windows_sys::Win32::System::Threading::CreateEventW;
use windows_sys::Win32::Foundation::{GetLastError, ERROR_ALREADY_EXISTS};
use std::ptr::null;
unsafe fn ensure_single_instance(name: *const u16) -> bool {
let h = CreateEventW(null(), 1, 0, name);
if h.is_null() { return false; }
GetLastError() != ERROR_ALREADY_EXISTS
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20