> Windows Syscalls
ntoskrnl.exeT1027.011T1106T1029

NtCreateTimer

Crea un objeto timer del kernel que puede armarse después con NtSetTimer.

Prototipo

NTSTATUS NtCreateTimer(
  PHANDLE            TimerHandle,
  ACCESS_MASK        DesiredAccess,
  POBJECT_ATTRIBUTES ObjectAttributes,
  TIMER_TYPE         TimerType
);

Argumentos

NameTypeDirDescription
TimerHandlePHANDLEoutRecibe el handle al objeto timer recién creado.
DesiredAccessACCESS_MASKinMáscara de acceso, típicamente TIMER_ALL_ACCESS o TIMER_MODIFY_STATE | SYNCHRONIZE.
ObjectAttributesPOBJECT_ATTRIBUTESinAtributos de objeto opcionales; NULL para anónimo, nombre bajo \BaseNamedObjects para uso IPC.
TimerTypeTIMER_TYPEinNotificationTimer (broadcast, permanece señalado) o SynchronizationTimer (auto-reset).

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070xB4win10-1507
Win10 16070xB7win10-1607
Win10 17030xBAwin10-1703
Win10 17090xBBwin10-1709
Win10 18030xBCwin10-1803
Win10 18090xBDwin10-1809
Win10 19030xBEwin10-1903
Win10 19090xBEwin10-1909
Win10 20040xC2win10-2004
Win10 20H20xC2win10-20h2
Win10 21H10xC2win10-21h1
Win10 21H20xC3win10-21h2
Win10 22H20xC3win10-22h2
Win11 21H20xC8win11-21h2
Win11 22H20xC9win11-22h2
Win11 23H20xC9win11-23h2
Win11 24H20xCBwin11-24h2
Server 20160xB7winserver-2016
Server 20190xBDwinserver-2019
Server 20220xC7winserver-2022
Server 20250xCBwinserver-2025

Módulo del kernel

ntoskrnl.exeNtCreateTimer

APIs relacionadas

CreateWaitableTimerWCreateWaitableTimerExWCreateTimerQueueCreateTimerQueueTimerNtCreateTimerExNtSetTimerNtCancelTimer

Stub del syscall

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

Asigna un objeto ejecutivo `KTIMER` vía `ExCreateTimer` / `ObCreateObject`. El objeto está *no armado* al crearse — no hace nada hasta que `NtSetTimer` proporcione un due time y opcionalmente una rutina APC. La SSN deriva entre builds (`0xB4` en 1507 → `0xCB` en Win11 24H2 / Server 2025), por lo que las implementaciones con syscalls directos deben resolver dinámicamente. `NotificationTimer` mantiene el objeto dispatcher señalado tras la expiración (todos los waiters liberados y siguen pasando), mientras que `SynchronizationTimer` se auto-reinicia tras liberar un waiter — esto es lo que usan las sleep masks.

Uso común por malware

La primera mitad del **motor sleep-mask Ekko** (Austin Hudson, 2022) — y el diseño copiado al completo por Foliage, Cronos, Zilean y la mayoría de loaders crypter modernos derivados. Se crea un timer, luego `NtSetTimer` lo arma con `TimerApcRoutine = RtlCaptureContext`/`SetEvent`/`VirtualProtect` como etapas de cadena, y el implante hace una espera alertable. Cada expiración del timer encola un APC, el APC ejecuta una etapa ROP que recifra la memoria del implante y rearma — produciendo un beacon cuyo código es RWX → RW → cifrado en cada ciclo, derrotando escáneres de memoria ingenuos. NtCreateTimer solo es benigno; la *tríada* (timer + event + espera alertable en memoria privada) es el IOC.

Oportunidades de detección

No hay evento Sysmon dedicado para creación de timer. ETW `Microsoft-Windows-Kernel-Object` con el keyword `Timer` expone la creación de objeto; correlacionar handles timer mantenidos por un hilo cuyo RIP en el momento de `NtSetTimer` está en memoria no respaldada / RWX es la señal de alta fidelidad. La mayoría de los EDR que vencen a Ekko escanean la pila del hilo suspendido y caminan hacia atrás por los frames KiUserApcDispatcher en el momento en que se entrega un special user APC — capturan la etapa de cifrado en vuelo más que la creación del timer.

Ejemplos de syscalls directos

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtCreateTimer (SSN 0xCB on Win11 24H2 / Server 2025)
NtCreateTimer PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 0CBh         ; SSN — drifts; resolve dynamically for portability
    syscall
    ret
NtCreateTimer ENDP

cEkko-style sleep-mask timer setup

// Step 1 of the sleep-mask triad: a synchronization timer the APC chain will arm.
HANDLE             hTimer = NULL;
OBJECT_ATTRIBUTES  oa     = { sizeof(oa), 0 };
NTSTATUS st = NtCreateTimer(&hTimer,
                            TIMER_ALL_ACCESS,
                            &oa,
                            SynchronizationTimer);
if (!NT_SUCCESS(st)) return st;
// hTimer will be armed by NtSetTimer with TimerApcRoutine pointing at the ROP gadgets.

rustwindows-sys CreateWaitableTimerW wrapper

// Cargo: windows-sys = "0.59" (Win32_System_Threading)
use windows_sys::Win32::System::Threading::CreateWaitableTimerW;
use std::ptr::null;

unsafe fn make_timer() -> *mut core::ffi::c_void {
    // bManualReset = 0 → SynchronizationTimer kernel-side.
    CreateWaitableTimerW(null(), 0, null())
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20