> Windows Syscalls
ntoskrnl.exeT1106

NtPulseEvent

Signale un événement, libère les threads en attente puis le réinitialise immédiatement à non-signalé.

Prototype

NTSTATUS NtPulseEvent(
  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 le pulse (1 = signalé, 0 = non).

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x127win10-1507
Win10 16070x12Dwin10-1607
Win10 17030x131win10-1703
Win10 17090x133win10-1709
Win10 18030x135win10-1803
Win10 18090x136win10-1809
Win10 19030x137win10-1903
Win10 19090x137win10-1909
Win10 20040x13Dwin10-2004
Win10 20H20x13Dwin10-20h2
Win10 21H10x13Dwin10-21h1
Win10 21H20x13Ewin10-21h2
Win10 22H20x13Ewin10-22h2
Win11 21H20x144win11-21h2
Win11 22H20x146win11-22h2
Win11 23H20x146win11-23h2
Win11 24H20x148win11-24h2
Server 20160x12Dwinserver-2016
Server 20190x136winserver-2019
Server 20220x143winserver-2022
Server 20250x148winserver-2025

Module noyau

ntoskrnl.exeNtPulseEvent

APIs liées

PulseEventNtSetEventNtResetEventNtClearEventNtWaitForSingleObject

Stub du syscall

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

NtPulseEvent réalise un *set puis reset* sur un objet événement comme une seule opération atomique. Pour un événement manual-reset il libère *tous* les threads en attente puis ramène immédiatement l'événement à non-signalé, si bien qu'un thread qui arrive une microseconde plus tard rate complètement le pulse. Pour un événement sync (auto-reset) il libère au plus un waiter. Microsoft déconseille depuis longtemps son usage côté user-mode car la fenêtre signalée est sujette aux courses : PulseEvent est largement un vestige du design original NT. Le noyau l'implémente encore (KePulseEvent) et ntoskrnl l'utilise en interne sur quelques chemins de signalisation en rafale.

Usage courant par les malwares

Majoritairement *légitime*. Certains implants et packers utilisent un signal pulse pour libérer un pool de threads workers en une seule rafale (p. ex. orchestrer un pool de décrypteurs). Comme la sémantique racy de PulseEvent impose que le wait soit déjà en place, les attaquants choisissent plus souvent NtSetEvent suivi de NtResetEvent ou un sémaphore compté. Pas un signal de détection significatif en soi.

Opportunités de détection

Pas un appel à fort signal. Microsoft-Windows-Kernel-EventTracing et les événements d'objet de synchronisation n'exposent pas PulseEvent séparément. Les hooks EDR sur `ntdll!NtPulseEvent` sont rares. À investiguer uniquement en conjonction avec d'autres anomalies — par exemple un pulse sur un événement dont le nom (visible via NtQueryObject) paraît suspect ou imite une primitive de synchronisation connue.

Exemples de syscalls directs

asmx64 direct stub

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

cRelease a burst of waiters

// Wake every thread currently parked on hEvent, then immediately drop signaled state.
#include <windows.h>
#include <winternl.h>

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

NTSTATUS PulseBurst(HANDLE hEvent) {
    LONG previous = 0;
    pNtPulseEvent fn = (pNtPulseEvent)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtPulseEvent");
    return fn(hEvent, &previous);
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20