> Windows Syscalls
ntoskrnl.exeT1055T1106

NtSetInformationWorkerFactory

Establece una clase de configuración en una worker factory — incluyendo, en algunas variantes de PoolParty, la StartRoutine que ejecutarán los hilos de trabajo.

Prototipo

NTSTATUS NtSetInformationWorkerFactory(
  HANDLE                     WorkerFactoryHandle,
  WORKERFACTORYINFOCLASS     WorkerFactoryInformationClass,
  PVOID                      WorkerFactoryInformation,
  ULONG                      WorkerFactoryInformationLength
);

Argumentos

NameTypeDirDescription
WorkerFactoryHandleHANDLEinHandle a la worker factory. Requiere acceso WORKER_FACTORY_SET_INFORMATION.
WorkerFactoryInformationClassWORKERFACTORYINFOCLASSinSelector de clase — WorkerFactoryBasicInformation, WorkerFactoryThreadMinimum/Maximum, WorkerFactoryThreadCpuSets, WorkerFactoryAdjustThreadGoal, etc.
WorkerFactoryInformationPVOIDinBuffer cuyo diseño depende de la clase — p. ej. una estructura WORKER_FACTORY_BASIC_INFORMATION o un único ULONG.
WorkerFactoryInformationLengthULONGinTamaño en bytes del buffer de información. Una longitud incoherente devuelve STATUS_INFO_LENGTH_MISMATCH.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x183win10-1507
Win10 16070x18Cwin10-1607
Win10 17030x192win10-1703
Win10 17090x195win10-1709
Win10 18030x197win10-1803
Win10 18090x198win10-1809
Win10 19030x199win10-1903
Win10 19090x199win10-1909
Win10 20040x19Fwin10-2004
Win10 20H20x19Fwin10-20h2
Win10 21H10x19Fwin10-21h1
Win10 21H20x1A1win10-21h2
Win10 22H20x1A1win10-22h2
Win11 21H20x1AAwin11-21h2
Win11 22H20x1AEwin11-22h2
Win11 23H20x1AEwin11-23h2
Win11 24H20x1B1win11-24h2
Server 20160x18Cwinserver-2016
Server 20190x198winserver-2019
Server 20220x1A7winserver-2022
Server 20250x1B1winserver-2025

Módulo del kernel

ntoskrnl.exeNtSetInformationWorkerFactory

APIs relacionadas

SetThreadpoolThreadMinimumSetThreadpoolThreadMaximumNtCreateWorkerFactoryNtQueryInformationWorkerFactoryNtShutdownWorkerFactory

Stub del syscall

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

El enum `WORKERFACTORYINFOCLASS` (definido en phnt/ntexapi.h) selecciona qué campo de la estructura del kernel `EWORKER_FACTORY` se toca. La mayoría de las clases — mínimo/máximo de hilos, conjuntos de CPU, ajustes de timeout — son perillas mundanas de dimensionado del threadpool. Dos son interesantes: `WorkerFactoryBasicInformation` expone (y, al Set, puede sobrescribir) los campos `StartRoutine` y `StartParameter`, y `WorkerFactoryThreadFlags` puede marcar workers como largos o cortos, cambiando con qué agresividad el kernel los recoge.

Uso común por malware

Las variantes PoolParty 'Start Routine Overwrite' parten la operación en dos: primero llaman NtCreateWorkerFactory con una StartRoutine benigna (ntdll!TppWorkerThread es la opción obvia — hace que la factory parezca idéntica a una legítima en una instantánea breve), luego llaman NtSetInformationWorkerFactory con `WorkerFactoryBasicInformation` para sobrescribir StartRoutine con el puntero al shellcode justo antes de postear trabajo. El patrón en dos pasos derrota a las detecciones inter-proceso simples que solo inspeccionan la StartRoutine en el momento de creación. El mismo syscall se usa para bajar los mínimos de hilos a cero en algunos gadgets de evasión de sleep que abusan del threadpool para imitar el comportamiento en reposo de un proceso benigno.

Oportunidades de detección

Las escrituras de WorkerFactoryBasicInformation son raras en código normal — el threadpool de ntdll fija la StartRoutine en la creación y no la vuelve a tocar. Un callback de kernel que compare `EWORKER_FACTORY.StartRoutine` antes y después de este syscall y marque cualquier cambio en el campo es de alta fidelidad. La invocación inter-proceso amplifica la señal: el ajuste legítimo del threadpool es siempre intra-proceso. Microsoft-Windows-Threading ETW emite algunas clases pero no todas; la cobertura fiable requiere ObRegisterCallbacks sobre el tipo de objeto WorkerFactory o un minifilter que observe el syscall en kernel.

Ejemplos de syscalls directos

cPoolParty StartRoutine overwrite

// Step 2 of the 'overwrite' variant — flip the entry point to shellcode
// after the factory was created with a benign decoy routine.
typedef struct _WORKER_FACTORY_BASIC_INFORMATION {
    LARGE_INTEGER Timeout;
    LARGE_INTEGER RetryTimeout;
    LARGE_INTEGER IdleTimeout;
    BOOLEAN       Paused;
    BOOLEAN       TimerSet;
    BOOLEAN       QueuedToExWorker;
    BOOLEAN       MayCreate;
    BOOLEAN       CreateInProgress;
    BOOLEAN       InsertedIntoQueue;
    BOOLEAN       Shutdown;
    ULONG         BindingCount;
    ULONG         ThreadMinimum;
    ULONG         ThreadMaximum;
    ULONG         PendingWorkerCount;
    ULONG         WaitingWorkerCount;
    ULONG         TotalWorkerCount;
    ULONG         ReleaseCount;
    LONGLONG      InfiniteWaitGoal;
    PVOID         StartRoutine;
    PVOID         StartParameter;
    HANDLE        ProcessId;
    SIZE_T        StackReserve;
    SIZE_T        StackCommit;
    NTSTATUS      LastThreadCreationStatus;
} WORKER_FACTORY_BASIC_INFORMATION;

WORKER_FACTORY_BASIC_INFORMATION info = {0};
NtQueryInformationWorkerFactory(hWf, WorkerFactoryBasicInformation,
                                &info, sizeof(info), NULL);
info.StartRoutine  = pRemoteShellcode;   // hijack
info.StartParameter = NULL;
NtSetInformationWorkerFactory(hWf, WorkerFactoryBasicInformation,
                              &info, sizeof(info));

asmx64 direct stub (Win11 24H2 SSN 0x1B1)

NtSetInformationWorkerFactory PROC
    mov  r10, rcx
    mov  eax, 1B1h     ; Win11 24H2 / Server 2025
    syscall
    ret
NtSetInformationWorkerFactory ENDP

Mapeos MITRE ATT&CK

Last verified: 2026-05-20