> Windows Syscalls
ntoskrnl.exeT1106T1027.013

NtResetEvent

Setzt ein Event-Objekt auf nicht-signalisiert zurück und liefert den vorherigen Signalzustand.

Prototyp

NTSTATUS NtResetEvent(
  HANDLE  EventHandle,
  PLONG   PreviousState
);

Argumente

NameTypeDirDescription
EventHandleHANDLEinHandle auf das Event mit EVENT_MODIFY_STATE-Zugriff.
PreviousStatePLONGoutOptional; erhält den Signalzustand vor dem Reset (1 = signalisiert, 0 = nicht).

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070x15Ewin10-1507
Win10 16070x165win10-1607
Win10 17030x16Bwin10-1703
Win10 17090x16Ewin10-1709
Win10 18030x170win10-1803
Win10 18090x171win10-1809
Win10 19030x172win10-1903
Win10 19090x172win10-1909
Win10 20040x178win10-2004
Win10 20H20x178win10-20h2
Win10 21H10x178win10-21h1
Win10 21H20x17Awin10-21h2
Win10 22H20x17Awin10-22h2
Win11 21H20x182win11-21h2
Win11 22H20x185win11-22h2
Win11 23H20x185win11-23h2
Win11 24H20x187win11-24h2
Server 20160x165winserver-2016
Server 20190x171winserver-2019
Server 20220x180winserver-2022
Server 20250x187winserver-2025

Kernel-Modul

ntoskrnl.exeNtResetEvent

Verwandte APIs

ResetEventNtSetEventNtClearEventNtPulseEventNtWaitForSingleObject

Syscall-Stub

4C 8B D1            mov r10, rcx
B8 87 01 00 00      mov eax, 0x187
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

NtResetEvent ist die Umkehrung von NtSetEvent: Es setzt ein Event-Objekt in den nicht-signalisierten Zustand und liefert optional den *vorherigen* Zustand via `PreviousState` zurück. Der Unterschied zu NtClearEvent (das denselben Drop ausführt, aber den Vorzustand verwirft) liegt allein darin, ob der Caller den vorherigen Wert braucht — nützlich für Test-and-Clear-Semantik ohne einen zusätzlichen NtQueryEvent-Roundtrip. Die Kernel-Routine `KeResetEvent` liegt sowohl NtResetEvent als auch NtClearEvent zugrunde.

Häufige Malware-Nutzung

Verbreitet in *Sleep-Mask*- und *Event-getriebenen Idle-Loops* moderner Beacons. Typisches Muster: Das Implant signalisiert vor dem Schlafen ein Event via NtSetEvent und setzt es beim Aufwachen via NtResetEvent zurück, um für die nächste Iteration bereit zu sein. Cobalt Strikes benutzerdefinierte Sleep Mask, Sleepmask-rs und diverse Sliver-Post-Ex-Module nutzen NT-Event-Primitiven so, um den offensichtlichen Timing-Fingerabdruck von `NtDelayExecution` zu vermeiden. Auch in Worker-Thread-Schleifen anzutreffen, die auf einem Master-Signal gaten.

Erkennungs­möglichkeiten

NtResetEvent ist in legitimen Code *äußerst* häufig (jede CRITICAL_SECTION bei Contention, jeder Async-I/O-Completion-Teardown), liefert für sich also kein Signal. Entscheidend ist die Korrelation: Kurze sich wiederholende `NtCreateEvent → NtSetEvent → NtWait → NtResetEvent`-Zyklen aus einem einzelnen Thread mit RWX-Stackregion oder mit der Aufrufsequenz innerhalb eines heap-allokierten Buffers passen zu einer Sleep-Mask. ETW Threat Intelligence (`Microsoft-Windows-Threat-Intelligence`) surft einige Context-Switch- und Wait-Übergänge, die korreliert werden können; sonst Stack-Walking-Telemetrie nutzen.

Direkte Syscall-Beispiele

asmx64 direct stub

; Direct syscall stub for NtResetEvent (SSN 0x187 on Win11 24H2)
NtResetEvent PROC
    mov  r10, rcx          ; EventHandle
    mov  eax, 187h         ; SSN — verify per-build
    syscall
    ret
NtResetEvent ENDP

cTest-and-clear without round-trip

// Atomically clear hEvent and learn whether it was previously signaled.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtResetEvent)(HANDLE, PLONG);

BOOL ConsumeOneShot(HANDLE hEvent) {
    LONG prev = 0;
    pNtResetEvent fn = (pNtResetEvent)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtResetEvent");
    NTSTATUS s = fn(hEvent, &prev);
    return (s >= 0) && (prev != 0);
}

rustEvent-paced sleep mask skeleton

// Cargo: windows-sys = "0.59", ntapi = "0.4"
// Toy sleep-mask loop: park on event, decrypt-process-encrypt, reset, repeat.
use ntapi::ntpsapi::NtResetEvent;
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::Threading::WaitForSingleObject;

unsafe fn beacon_loop(wake: HANDLE) {
    loop {
        WaitForSingleObject(wake, u32::MAX);   // park
        // ... unmask payload, run task, remask payload ...
        let mut prev: i32 = 0;
        NtResetEvent(wake, &mut prev);          // rearm for next pulse
    }
}

MITRE ATT&CK-Mappings

Last verified: 2026-05-20