NtAlertResumeThread
Reprend un thread suspendu et l'alerte simultanément pour délivrer toute APC en attente.
Prototype
NTSTATUS NtAlertResumeThread( HANDLE ThreadHandle, PULONG PreviousSuspendCount );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| ThreadHandle | HANDLE | in | Handle vers le thread cible ; doit avoir l'accès THREAD_SUSPEND_RESUME. |
| PreviousSuspendCount | PULONG | out | Optionnel. Reçoit le compteur de suspensions avant décrément ; NULL pour l'ignorer. |
IDs de syscalls par version de Windows
| Version 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 |
Module noyau
APIs liées
Stub du 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
Notes non documentées
Fonctionnellement, `NtAlertResumeThread` est la fusion de `NtAlertThread` + `NtResumeThread` en un seul aller-retour. Le noyau décrémente le compteur de suspension *et* positionne le bit d'alerte, donc dès que le thread atteint un point alertable — ou s'il a déjà une APC en file — celle-ci est dispatchée immédiatement. Pas d'équivalent direct Win32 ; `ResumeThread` ne positionne pas le bit d'alerte. Documenté dans phnt ; absent du SDK public.
Usage courant par les malwares
Utilisé dans les chaînes d'injection APC où l'attaquant veut les deux moitiés de façon atomique — réveiller le thread et garantir que l'APC se déclenche dès le début de l'exécution. De nombreuses variantes Early Bird et Atom Bombing préfèrent `NtAlertResumeThread` à `NtResumeThread + NtTestAlert` car cela supprime une fenêtre TOCTOU où un EDR pourrait observer le thread repris avant la livraison de l'APC. C'est le primitif canonique de reprise dans les kits de sleep mask modernes (Ekko, Cronos) qui suspendent le thread du beacon pour chiffrer la mémoire et ont besoin d'un réveil atomique qui déclenche l'APC de déchiffrement.
Opportunités de détection
Les appels à `NtAlertResumeThread` depuis un processus visant un thread dans un autre processus sont bruyants : la reprise cross-process est rare dans le logiciel normal et est un fort indicateur d'injection lorsqu'elle suit un `NtQueueApcThread` sur le même thread. Les callbacks noyau `PsSetCreateThreadNotifyRoutineEx` et l'ETW `Microsoft-Windows-Threat-Intelligence` capturent ces transitions d'état de thread distant. Les règles de détection CarbonBlack et Elastic SIEM signalent couramment la séquence cross-process `NtQueueApcThread → NtAlertResumeThread` comme injection APC.
Exemples de syscalls directs
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),
);
}Mappings MITRE ATT&CK
Last verified: 2026-05-20