> Windows Syscalls
ntoskrnl.exeT1106T1027.013

NtResetEvent

Remet un objet événement à non-signalé et retourne son état signalé précédent.

Prototype

NTSTATUS NtResetEvent(
  HANDLE  EventHandle,
  PLONG   PreviousState
);

Arguments

NameTypeDirDescription
EventHandleHANDLEinHandle vers l'événement avec l'accès EVENT_MODIFY_STATE.
PreviousStatePLONGoutOptionnel ; reçoit l'état signalé de l'événement avant reset (1 = signalé, 0 = non).

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
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

Module noyau

ntoskrnl.exeNtResetEvent

APIs liées

ResetEventNtSetEventNtClearEventNtPulseEventNtWaitForSingleObject

Stub du syscall

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

Notes non documentées

NtResetEvent est l'inverse de NtSetEvent : il met un objet événement à l'état non-signalé et retourne optionnellement l'état *précédent* via `PreviousState`. La distinction avec NtClearEvent (qui fait la même bascule mais sans retourner l'état antérieur) tient uniquement à ce que l'appelant se soucie ou non de la valeur précédente — utile pour implémenter une sémantique test-and-clear sans aller-retour NtQueryEvent supplémentaire. La routine noyau `KeResetEvent` sous-tend à la fois NtResetEvent et NtClearEvent.

Usage courant par les malwares

Courant dans les implémentations de *sleep mask* et de *boucles d'oisiveté event-driven* utilisées par les beacons modernes. Schéma typique : l'implant arme un événement via NtSetEvent avant de dormir sur un homologue, puis le reset via NtResetEvent à la reprise pour être prêt à l'itération suivante. Le sleep mask user-defined de Cobalt Strike, Sleepmask-rs et divers modules post-ex Sliver utilisent ainsi les primitives event NT pour éviter l'empreinte temporelle évidente de `NtDelayExecution`. Vu aussi dans des boucles worker conditionnées par un signal maître.

Opportunités de détection

NtResetEvent est *extrêmement* courant en code légitime (chaque CRITICAL_SECTION en contention, chaque teardown de complétion d'E/S async) donc en soi sans signal. Ce qui compte est la corrélation : des cycles courts répétés `NtCreateEvent → NtSetEvent → NtWait → NtResetEvent` depuis un seul thread avec une région de pile RWX ou avec la séquence d'appels dans un buffer alloué en heap est compatible avec un sleep mask. ETW Threat Intelligence (`Microsoft-Windows-Threat-Intelligence`) expose certaines transitions de context-switch et d'attente exploitables ; sinon, télémétrie de stack-walking.

Exemples de syscalls directs

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
    }
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20