> Windows Syscalls
ntoskrnl.exeT1055.004T1497T1106

NtWaitForMultipleObjects

Espera hasta MAXIMUM_WAIT_OBJECTS objetos dispatcher con semántica WaitAny o WaitAll.

Prototipo

NTSTATUS NtWaitForMultipleObjects(
  ULONG          Count,
  PHANDLE        Handles,
  WAIT_TYPE      WaitType,
  BOOLEAN        Alertable,
  PLARGE_INTEGER Timeout
);

Argumentos

NameTypeDirDescription
CountULONGinNúmero de handles en el arreglo Handles; debe ser 1..MAXIMUM_WAIT_OBJECTS (64).
HandlesPHANDLEinPuntero a un arreglo de handles a objetos dispatcher esperables, cada uno con acceso SYNCHRONIZE.
WaitTypeWAIT_TYPEinWaitAll requiere que todos los objetos se señalen; WaitAny retorna al primero.
AlertableBOOLEANinTRUE permite que los APC de usuario encolados se ejecuten y aborten la espera con STATUS_USER_APC.
TimeoutPLARGE_INTEGERinTimeout opcional en unidades de 100 ns; negativo = relativo, positivo = absoluto, NULL = INFINITE.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x5Bwin10-1507
Win10 16070x5Bwin10-1607
Win10 17030x5Bwin10-1703
Win10 17090x5Bwin10-1709
Win10 18030x5Bwin10-1803
Win10 18090x5Bwin10-1809
Win10 19030x5Bwin10-1903
Win10 19090x5Bwin10-1909
Win10 20040x5Bwin10-2004
Win10 20H20x5Bwin10-20h2
Win10 21H10x5Bwin10-21h1
Win10 21H20x5Bwin10-21h2
Win10 22H20x5Bwin10-22h2
Win11 21H20x5Bwin11-21h2
Win11 22H20x5Bwin11-22h2
Win11 23H20x5Bwin11-23h2
Win11 24H20x5Bwin11-24h2
Server 20160x5Bwinserver-2016
Server 20190x5Bwinserver-2019
Server 20220x5Bwinserver-2022
Server 20250x5Bwinserver-2025

Módulo del kernel

ntoskrnl.exeNtWaitForMultipleObjects

APIs relacionadas

WaitForMultipleObjectsWaitForMultipleObjectsExMsgWaitForMultipleObjectsExNtWaitForSingleObjectNtSignalAndWaitForSingleObject

Stub del syscall

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

Notas no documentadas

Despacha a través de `KeWaitForMultipleObjects` dentro de ntoskrnl.exe. La SSN `0x5B` es estable en todas las builds Win10/11. Con `WaitAny`, el valor de retorno `STATUS_WAIT_0..STATUS_WAIT_63` identifica qué handle señaló; con `WaitAll`, el kernel debe verificar atómicamente el estado de cada objeto, por lo que `WaitAll` es comparativamente costoso y `MAXIMUM_WAIT_OBJECTS` está limitado a 64 — el dispatcher rastrea waiters mediante un bloque de tamaño fijo. Como `NtWaitForSingleObject`, el flag `Alertable` abre el hilo a la entrega de APCs de usuario (devolviendo `STATUS_USER_APC`).

Uso común por malware

Usado por implantes que mantienen múltiples fuentes de despertar simultáneas — típicamente *(evento timer)* + *(evento kill-switch)* + *(evento red-lista)* — para que el beacon reaccione tanto al tiempo transcurrido como a un push del canal de control. Las variantes sleep-mask (Cronos, Zilean) esperan sobre el evento de etapa de cifrado más un evento de cancelación para que el C2 pueda interrumpir un ciclo de sleep en marcha. Algunos droppers esperan sobre múltiples handles de hilo para esperar el fin de etapas de descifrado paralelas (WaitAll). Menos común, un WaitAny alertable sobre arreglos de handles confeccionados sirve como punto de recepción de APC más flexible.

Oportunidades de detección

Mismas advertencias que `NtWaitForSingleObject`: demasiado común para alertar en crudo. Señales útiles: `WaitAny` alertable sobre un conjunto de handles que incluye un evento nombrado privado mantenido por un proceso cuyo código reside en memoria no respaldada; o un hilo que rutinariamente espera sobre >1 handle siendo uno de ellos un objeto kernel de capa de transporte (\Device\Afd, named pipe, evento nombrado) más un timer event sintetizado. Correlacionar contenido de tabla de handles en modo kernel con RIPs de hilos respaldados por módulo al entrar al sleep.

Ejemplos de syscalls directos

asmx64 direct stub

; Direct syscall stub for NtWaitForMultipleObjects (SSN 0x5B, stable across Win10/11)
NtWaitForMultipleObjects PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 5Bh          ; SSN
    syscall
    ret
NtWaitForMultipleObjects ENDP

cAlertable WaitAny on event + kill-switch

// Beacon wakes on either the sleep-timer event or an out-of-band cancel.
HANDLE waits[2] = { hSleepEvent, hCancelEvent };
NTSTATUS st = NtWaitForMultipleObjects(2, waits, WaitAny, TRUE, NULL);
if (st == STATUS_WAIT_0)       { /* normal beacon tick */ }
else if (st == STATUS_WAIT_1)  { /* operator told us to shut down */ }
else if (st == STATUS_USER_APC){ /* APC fired mid-wait */ }

cWaitAll on parallel decryption threads

// Spin up N threads to decrypt stage payload, then synchronize before execution.
HANDLE workers[4];
for (int i = 0; i < 4; i++)
    workers[i] = create_decrypt_worker(stage_slice(i));
NtWaitForMultipleObjects(4, workers, WaitAll, FALSE, NULL);
// All slices decrypted; safe to jump into stage.

Mapeos MITRE ATT&CK

Last verified: 2026-05-20