> Windows Syscalls
ntoskrnl.exeT1055T1106

NtSetInformationWorkerFactory

Définit une classe de configuration sur une worker factory — y compris, dans certaines variantes PoolParty, la StartRoutine exécutée par les threads de travail.

Prototype

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

Arguments

NameTypeDirDescription
WorkerFactoryHandleHANDLEinHandle vers la worker factory. Nécessite l'accès WORKER_FACTORY_SET_INFORMATION.
WorkerFactoryInformationClassWORKERFACTORYINFOCLASSinSélecteur de classe — WorkerFactoryBasicInformation, WorkerFactoryThreadMinimum/Maximum, WorkerFactoryThreadCpuSets, WorkerFactoryAdjustThreadGoal, etc.
WorkerFactoryInformationPVOIDinBuffer dont la mise en page dépend de la classe — ex. une structure WORKER_FACTORY_BASIC_INFORMATION ou un seul ULONG.
WorkerFactoryInformationLengthULONGinTaille en octets du buffer d'information. Une longueur incohérente renvoie STATUS_INFO_LENGTH_MISMATCH.

IDs de syscalls par version de Windows

Version 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

Module noyau

ntoskrnl.exeNtSetInformationWorkerFactory

APIs liées

SetThreadpoolThreadMinimumSetThreadpoolThreadMaximumNtCreateWorkerFactoryNtQueryInformationWorkerFactoryNtShutdownWorkerFactory

Stub du 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

Notes non documentées

L'énumération `WORKERFACTORYINFOCLASS` (définie dans phnt/ntexapi.h) sélectionne quel champ de la structure noyau `EWORKER_FACTORY` est modifié. La plupart des classes — min/max de threads, ensembles CPU, ajustements de timeout — sont des boutons de dimensionnement banals du threadpool. Deux sont intéressantes : `WorkerFactoryBasicInformation` expose (et, en Set, peut réécrire) les champs `StartRoutine` et `StartParameter`, et `WorkerFactoryThreadFlags` peut marquer les workers comme longs ou courts, modifiant l'agressivité avec laquelle le noyau les récupère.

Usage courant par les malwares

Les variantes PoolParty « Start Routine Overwrite » scindent l'opération en deux : d'abord appeler NtCreateWorkerFactory avec une StartRoutine bénigne (ntdll!TppWorkerThread est le choix évident — la factory devient indiscernable d'une légitime sur un cliché bref), puis appeler NtSetInformationWorkerFactory avec `WorkerFactoryBasicInformation` pour réécrire StartRoutine vers le pointeur de shellcode juste avant de poster le travail. Le schéma en deux étapes met en échec les détections inter-processus simples qui n'inspectent la StartRoutine qu'à la création. Le même syscall sert à mettre les minimums de threads à zéro dans certains gadgets d'évasion de sleep qui utilisent le threadpool pour imiter le comportement au repos d'un processus inoffensif.

Opportunités de détection

Les écritures WorkerFactoryBasicInformation sont rares en code normal — le threadpool ntdll fixe la StartRoutine à la création et n'y touche plus jamais. Un callback noyau qui compare `EWORKER_FACTORY.StartRoutine` avant/après ce syscall et signale tout changement est très fiable. L'invocation inter-processus amplifie le signal : le réglage légitime du threadpool est toujours intra-processus. Microsoft-Windows-Threading ETW émet certaines classes mais pas toutes ; une couverture fiable demande ObRegisterCallbacks sur le type d'objet WorkerFactory ou un minifilter qui observe le syscall en noyau.

Exemples de syscalls directs

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

Mappings MITRE ATT&CK

Last verified: 2026-05-20