NtAlertResumeThread
Reanuda un hilo suspendido y lo alerta a la vez para entregar cualquier APC pendiente.
Prototipo
NTSTATUS NtAlertResumeThread( HANDLE ThreadHandle, PULONG PreviousSuspendCount );
Argumentos
| Name | Type | Dir | Description |
|---|---|---|---|
| ThreadHandle | HANDLE | in | Handle al hilo objetivo; debe tener acceso THREAD_SUSPEND_RESUME. |
| PreviousSuspendCount | PULONG | out | Opcional. Recibe el contador de suspensiones antes del decremento; NULL para descartar. |
IDs de syscalls por versión de Windows
| Versión de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x6C | win10-1507 |
| Win10 1607 | 0x6C | win10-1607 |
| Win10 1703 | 0x6D | win10-1703 |
| Win10 1709 | 0x6D | win10-1709 |
| Win10 1803 | 0x6D | win10-1803 |
| Win10 1809 | 0x6D | win10-1809 |
| Win10 1903 | 0x6D | win10-1903 |
| Win10 1909 | 0x6D | win10-1909 |
| Win10 2004 | 0x6E | win10-2004 |
| Win10 20H2 | 0x6E | win10-20h2 |
| Win10 21H1 | 0x6E | win10-21h1 |
| Win10 21H2 | 0x6E | win10-21h2 |
| Win10 22H2 | 0x6E | win10-22h2 |
| Win11 21H2 | 0x6E | win11-21h2 |
| Win11 22H2 | 0x6E | win11-22h2 |
| Win11 23H2 | 0x6E | win11-23h2 |
| Win11 24H2 | 0x6F | win11-24h2 |
| Server 2016 | 0x6C | winserver-2016 |
| Server 2019 | 0x6D | winserver-2019 |
| Server 2022 | 0x6E | winserver-2022 |
| Server 2025 | 0x6F | winserver-2025 |
Módulo del kernel
APIs relacionadas
Stub del syscall
4C 8B D1 mov r10, rcx B8 6F 00 00 00 mov eax, 0x6F 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
Funcionalmente, `NtAlertResumeThread` es la fusión de `NtAlertThread` + `NtResumeThread` en un solo viaje al kernel. El kernel decrementa el contador de suspensión *y* activa el flag de alerta, así que cuando el hilo llegue al siguiente punto alertable — o ya tenga una APC en cola — la APC se entrega de inmediato. No tiene equivalente directo en Win32; `ResumeThread` no activa el bit de alerta. Documentado en phnt; ausente del SDK público.
Uso común por malware
Usado en cadenas de inyección APC donde el atacante quiere ambas mitades de forma atómica — despertar el hilo y garantizar que la APC dispare al instante. Muchas variantes de Early Bird y Atom Bombing prefieren `NtAlertResumeThread` sobre `NtResumeThread + NtTestAlert` porque elimina una ventana TOCTOU en la que un EDR podría ver el hilo reanudado antes de que la APC se entregue. Es el primitivo canónico de reanudación en kits modernos de sleep mask (Ekko, Cronos) que suspenden el hilo del beacon para cifrar memoria y luego necesitan un despertar atómico que dispare la APC de descifrado.
Oportunidades de detección
Llamadas a `NtAlertResumeThread` desde un proceso hacia un hilo de otro proceso son ruidosas: el resume cross-process es raro en software normal y es un fuerte indicador de inyección cuando viene tras un `NtQueueApcThread` sobre el mismo hilo. Callbacks de kernel `PsSetCreateThreadNotifyRoutineEx` y ETW `Microsoft-Windows-Threat-Intelligence` capturan estas transiciones de estado de hilo remoto. Reglas en CarbonBlack y Elastic SIEM suelen marcar la secuencia cross-process `NtQueueApcThread → NtAlertResumeThread` como inyección APC.
Ejemplos de syscalls directos
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtAlertResumeThread (SSN 0x6F on Win11 24H2)
NtAlertResumeThread PROC
mov r10, rcx ; ThreadHandle
mov eax, 6Fh ; SSN
syscall
ret
NtAlertResumeThread ENDPcAPC injection: queue + alert-resume
// Resume a suspended remote thread and atomically deliver the APC.
extern "C" NTSTATUS NTAPI NtQueueApcThread(HANDLE, PVOID, PVOID, PVOID, PVOID);
extern "C" NTSTATUS NTAPI NtAlertResumeThread(HANDLE, PULONG);
void InjectViaApc(HANDLE hThread, PVOID pShellcodeRX) {
// 1. Queue user-APC pointing at our shellcode.
NtQueueApcThread(hThread, pShellcodeRX, NULL, NULL, NULL);
// 2. Atomically wake + alert; APC fires on next user-mode dispatch.
ULONG prev = 0;
NtAlertResumeThread(hThread, &prev);
}rustSleep-mask wakeup
use std::arch::asm;
#[unsafe(naked)]
pub unsafe extern "system" fn nt_alert_resume_thread(
_thread: *mut core::ffi::c_void,
_prev: *mut u32,
) -> i32 {
asm!(
"mov r10, rcx",
"mov eax, 0x6F", // Win11 24H2 — resolve dynamically in production
"syscall",
"ret",
options(noreturn),
);
}Mapeos MITRE ATT&CK
Last verified: 2026-05-20