NtCancelTimer2
Bricht ein zuvor bewaffnetes Timer2-Objekt ab und meldet, ob es noch ausstand.
Prototyp
NTSTATUS NtCancelTimer2( HANDLE TimerHandle, PT2_CANCEL_PARAMETERS Parameters );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| TimerHandle | HANDLE | in | Handle auf ein zuvor mit NtSetTimer2 bewaffnetes Timer2-Objekt. |
| Parameters | PT2_CANCEL_PARAMETERS | in/out | Optionale Struktur: Eingabe Version, Ausgabe meldet, ob der Timer noch ausstand. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x8F | win10-1507 |
| Win10 1607 | 0x8F | win10-1607 |
| Win10 1703 | 0x90 | win10-1703 |
| Win10 1709 | 0x91 | win10-1709 |
| Win10 1803 | 0x92 | win10-1803 |
| Win10 1809 | 0x92 | win10-1809 |
| Win10 1903 | 0x92 | win10-1903 |
| Win10 1909 | 0x92 | win10-1909 |
| Win10 2004 | 0x94 | win10-2004 |
| Win10 20H2 | 0x94 | win10-20h2 |
| Win10 21H1 | 0x94 | win10-21h1 |
| Win10 21H2 | 0x94 | win10-21h2 |
| Win10 22H2 | 0x94 | win10-22h2 |
| Win11 21H2 | 0x94 | win11-21h2 |
| Win11 22H2 | 0x94 | win11-22h2 |
| Win11 23H2 | 0x94 | win11-23h2 |
| Win11 24H2 | 0x96 | win11-24h2 |
| Server 2016 | 0x8F | winserver-2016 |
| Server 2019 | 0x92 | winserver-2019 |
| Server 2022 | 0x94 | winserver-2022 |
| Server 2025 | 0x96 | winserver-2025 |
Kernel-Modul
Verwandte APIs
Syscall-Stub
4C 8B D1 mov r10, rcx B8 96 00 00 00 mov eax, 0x96 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
Gegenstück zu `NtSetTimer2`. Intern entfernt `ExpCancelTimer2` den `EX_TIMER` aus der Per-PRCB-Second-Generation-Queue über `KeCancelTimer2`. War der Timer noch ausstehend, gibt der Kernel `STATUS_SUCCESS` zurück und füllt `Parameters` mit dem vorherigen Zustand; ist er bereits abgelaufen und der Callback wurde gestartet oder ist im Flug, erhält man eine Semantik wie `STATUS_TIMER_RESUME_IGNORED` — der Aufruf kann einen bereits an einen Thread eingereihten APC nicht zurücknehmen. Bemerkenswert: `NtCancelTimer2` ist über Builds hinweg sehr stabil (`0x8F` auf 1507 → `0x96` auf Win11 24H2): die ursprüngliche 1507-SSN überlebte bis zur Win11-24H2-Syscall-Tabellen-Umsortierung, weil der Index die sortierte alphabetische Position relativ zu Einfügungen/Entfernungen widerspiegelt — und jahrelang wurde sehr wenig *vor* `Cancel*` eingefügt.
Häufige Malware-Nutzung
Wird als symmetrischer Teardown für Timer2-basierte Sleep-Masks (Cronos, Zilean) genutzt: kurz bevor das Implant beendet wird oder einen temporären Mask-Zyklus abbaut, entwaffnet `NtCancelTimer2` den Timer, damit der alertable Wait sauber endet. Manche Kits nutzen ihn auch defensiv — hat ein EDR begonnen, Threadpool-Timer-Listen zu durchlaufen, *entfernt* das frühe Abbrechen das Objekt aus der Liste, bevor der Scan den Callback-Pointer mit privatem RWX korrelieren kann. Geringes Malware-Signal für sich allein.
Erkennungsmöglichkeiten
Es gibt kein Sysmon-Event für Timer2-Abbruch, und der Aufruf für sich ist harmlos. Untersuchungen betrachten ihn nur als Teil einer *Sequenz*: `NtCreateTimer2(HIGH_RESOLUTION) → NtSetTimer2(Period ≈ 50 ms, Callback in RWX) → NtWaitForSingleObjectEx(Alertable=TRUE) → NtCancelTimer2`, eng wiederholt, ist der kanonische Timer2-Sleep-Mask-Fingerabdruck. EDRs mit Kernel-Komponenten (CrowdStrike Falcon, Defender for Endpoint via MAPS) inspizieren `EX_TIMER`-Listen direkt, statt sich für diesen Aufruf auf Syscall-Hooks zu verlassen.
Direkte Syscall-Beispiele
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtCancelTimer2 (SSN 0x96 on Win11 24H2 / Server 2025)
NtCancelTimer2 PROC
mov r10, rcx ; syscall convention
mov eax, 96h ; SSN — drifts; resolve dynamically for portability
syscall
ret
NtCancelTimer2 ENDPcSleep-mask teardown
// Sleep-mask cycle teardown: disarm the timer and close the handle.
typedef struct _T2_CANCEL_PARAMETERS {
ULONG Version;
ULONG Reserved;
} T2_CANCEL_PARAMETERS, *PT2_CANCEL_PARAMETERS;
T2_CANCEL_PARAMETERS cp = { 0 };
NTSTATUS st = NtCancelTimer2(hTimer, &cp);
// If st == STATUS_SUCCESS the timer was still armed; otherwise the APC already fired.
NtClose(hTimer);MITRE ATT&CK-Mappings
Last verified: 2026-05-20