NtTestAlert
Prüft, ob der aufrufende Thread einen anstehenden Alert hat, und stellt ggf. eingereihte User-Mode-APCs zu.
Prototyp
NTSTATUS NtTestAlert(VOID);
Argumente
| Name | Type | Dir | Description |
|---|
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x1A3 | win10-1507 |
| Win10 1607 | 0x1AC | win10-1607 |
| Win10 1703 | 0x1B2 | win10-1703 |
| Win10 1709 | 0x1B6 | win10-1709 |
| Win10 1803 | 0x1B8 | win10-1803 |
| Win10 1809 | 0x1B9 | win10-1809 |
| Win10 1903 | 0x1BA | win10-1903 |
| Win10 1909 | 0x1BA | win10-1909 |
| Win10 2004 | 0x1C0 | win10-2004 |
| Win10 20H2 | 0x1C0 | win10-20h2 |
| Win10 21H1 | 0x1C0 | win10-21h1 |
| Win10 21H2 | 0x1C2 | win10-21h2 |
| Win10 22H2 | 0x1C2 | win10-22h2 |
| Win11 21H2 | 0x1CC | win11-21h2 |
| Win11 22H2 | 0x1D0 | win11-22h2 |
| Win11 23H2 | 0x1D0 | win11-23h2 |
| Win11 24H2 | 0x1D3 | win11-24h2 |
| Server 2016 | 0x1AC | winserver-2016 |
| Server 2019 | 0x1B9 | winserver-2019 |
| Server 2022 | 0x1C8 | winserver-2022 |
| Server 2025 | 0x1D3 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 D3 01 00 00 mov eax, 0x1D3 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
Undokumentierte Hinweise
`NtTestAlert` zwingt den aufrufenden Thread an einen Alertable-Checkpoint: liefert `KeTestAlertThread` TRUE, leert der Kernel die User-APC-Queue sofort, indem er den Thread zu `KiUserApcDispatcher` springen lässt. Anders als `SleepEx(0, TRUE)` betritt er die Warte-Schleife nicht — er ist ein rein synchroner APC-Delivery-Punkt. Phnt definiert ihn; der öffentliche Win32-Header nicht. Der SSN driftet bei jedem Feature-Update (`0x1A3` auf Win10 1507 → `0x1D3` auf Win11 24H2), sodass dynamische Auflösung für portablen Shellcode Pflicht ist.
Häufige Malware-Nutzung
Die definierende Rolle ist **Early-Bird-APC-Injection**: einen Prozess suspendiert erzeugen, mit `NtQueueApcThread` eine User-APC am Initialthread einreihen und den Loader-Thread im frühen Init `NtTestAlert` ausführen lassen — die APC läuft, bevor irgendeine AV/EDR-DLL reif ist. Early-Bird-Varianten (FIN7, Turla, Conti-Familie und unzählige Open-Source-Loader) rufen `NtTestAlert` bewusst auf, um die APC-Auslieferung zu erzwingen, statt auf einen natürlichen Alertable-Punkt zu warten. Es ist außerdem die *Kickoff*-Primitive von Ekko-Style-Sleep-Masks: der Masking-Thread reiht eine APC-Kette am Beacon-Thread ein, suspendiert ihn, und der Beacon wacht über `NtTestAlert` → `KiUserApcDispatcher` in die ROP-Kette auf.
Erkennungsmöglichkeiten
Außerhalb von Debuggern, Systemdiensten und wenigen CRT-Init-Pfaden ist `NtTestAlert` in Nicht-Microsoft-Binaries kein häufiger Aufruf. Sysmon hat dafür kein dediziertes Event, aber EDR-Sammler mit Stack-Walking erkennen den Übergang `NtTestAlert → KiUserApcDispatcher → <Implant>`. Aussagekräftiger ist die *Kombination*: frisch erzeugter Prozess, dessen erster Thread `NtQueueApcThread` (von außerhalb) sieht, gefolgt von einem prozess-eigenen `NtTestAlert` und einem unmittelbaren Sprung in eine private RX-Region — das ist der Early-Bird-Fingerabdruck. Kernel-Callbacks per `PsSetCreateThreadNotifyRoutineEx` sind ein zuverlässigerer Anker.
Direkte Syscall-Beispiele
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtTestAlert (SSN 0x1D3 on Win11 24H2)
NtTestAlert PROC
mov r10, rcx ; syscall convention (no args, but stub still sets r10)
mov eax, 1D3h ; SSN — rebuild for each Windows version
syscall
ret
NtTestAlert ENDPcEarly Bird APC kickoff
// Within a newly-suspended target thread:
// 1) Queue APC pointing at shellcode
// 2) Resume thread; force-deliver via NtTestAlert from inside the thread context.
extern "C" NTSTATUS NTAPI NtQueueApcThread(HANDLE, PVOID, PVOID, PVOID, PVOID);
extern "C" NTSTATUS NTAPI NtTestAlert(VOID);
extern "C" NTSTATUS NTAPI NtResumeThread(HANDLE, PULONG);
void EarlyBird(HANDLE hThread, PVOID shellcode) {
NtQueueApcThread(hThread, (PVOID)shellcode, NULL, NULL, NULL);
NtResumeThread(hThread, NULL);
// Self-deliver any APCs queued on *this* thread immediately.
NtTestAlert();
}rustSleep-mask resume primitive
// Used to wake a beacon thread out of a self-suspended state into
// the APC chain that drives sleep-mask decryption.
use std::arch::asm;
#[unsafe(naked)]
pub unsafe extern "system" fn nt_test_alert() -> i32 {
asm!(
"mov r10, rcx",
"mov eax, 0x1D3", // Win11 24H2 — resolve dynamically in production
"syscall",
"ret",
options(noreturn),
);
}MITRE ATT&CK-Mappings
Last verified: 2026-05-20