> Windows Syscalls
ntoskrnl.exeT1057T1055.003T1106

NtGetNextThread

Liefert ein Handle auf den nächsten Thread eines Zielprozesses durch Durchlaufen der Kernel-Thread-Liste.

Prototyp

NTSTATUS NtGetNextThread(
  HANDLE      ProcessHandle,
  HANDLE      ThreadHandle,
  ACCESS_MASK DesiredAccess,
  ULONG       HandleAttributes,
  ULONG       Flags,
  PHANDLE     NewThreadHandle
);

Argumente

NameTypeDirDescription
ProcessHandleHANDLEinHandle auf den Prozess, dessen Threads aufgezählt werden. Erfordert PROCESS_QUERY_INFORMATION.
ThreadHandleHANDLEinHandle auf den zuvor zurückgegebenen Thread. NULL startet die Aufzählung.
DesiredAccessACCESS_MASKinZugriffsmaske für das neue Thread-Handle, z. B. THREAD_GET_CONTEXT | THREAD_SET_CONTEXT.
HandleAttributesULONGinHandle-Attributflags. Üblicherweise 0.
FlagsULONGinReserviert. 0 übergeben.
NewThreadHandlePHANDLEoutEmpfängt das neue Thread-Handle. STATUS_NO_MORE_ENTRIES markiert das Listenende.

Syscall-IDs pro Windows-Version

Windows-VersionSyscall-IDBuild
Win10 15070xE9win10-1507
Win10 16070xECwin10-1607
Win10 17030xEFwin10-1703
Win10 17090xF0win10-1709
Win10 18030xF1win10-1803
Win10 18090xF2win10-1809
Win10 19030xF3win10-1903
Win10 19090xF3win10-1909
Win10 20040xF8win10-2004
Win10 20H20xF8win10-20h2
Win10 21H10xF8win10-21h1
Win10 21H20xF9win10-21h2
Win10 22H20xF9win10-22h2
Win11 21H20xFEwin11-21h2
Win11 22H20xFFwin11-22h2
Win11 23H20xFFwin11-23h2
Win11 24H20x101win11-24h2
Server 20160xECwinserver-2016
Server 20190xF2winserver-2019
Server 20220xFDwinserver-2022
Server 20250x101winserver-2025

Kernel-Modul

ntoskrnl.exeNtGetNextThread

Verwandte APIs

NtGetNextProcessNtOpenThreadNtGetContextThreadNtSetContextThreadThread32FirstThread32Next

Syscall-Stub

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

NtGetNextThread iteriert das ThreadListHead des in ProcessHandle geöffneten EPROCESS. Sie ist das Thread-Pendant zu NtGetNextProcess und hat ebenfalls keinen dokumentierten Win32-Wrapper — `Thread32First`/`Thread32Next` laufen über die Toolhelp-Snapshot-Mechanik. Jeder Aufruf liefert ein neues Kernel-Handle, das der Aufrufer schließen muss (außer wenn STATUS_NO_MORE_ENTRIES den Lauf beendet). Die Funktion akzeptiert `PROCESS_QUERY_LIMITED_INFORMATION`, wenn der Aufrufer keine stärkeren Rechte am Prozess braucht, doch der gewünschte *Thread*-Zugriff muss von Anfang an angefordert werden — das Handle ist nicht ohne Weiteres aufrüstbar.

Häufige Malware-Nutzung

Wird zusammen mit NtGetNextProcess verwendet, um jeden Thread im System ohne Toolhelp32 zu enumerieren. Die PoolParty-Injection-Familie (die Thread-Pool-Internals missbraucht) iteriert die Worker-Threads des Pools mit genau diesem API-Paar, um einen Ziel-TP_WORKER-Thread zum Hijack zu finden. Auch von verdeckten Thread-Hijacking-Implants genutzt, die einen Opfer-Thread auswählen, dessen Kontext mit NtGetContextThread schnappen, RIP modifizieren und fortsetzen — alles ohne OpenThread per TID. `Thread32First/Next` zu meiden ist relevant, weil Toolhelp eine `_THSnapshot`-Section anlegt, die für Handle-Table-Inspektoren sichtbar ist.

Erkennungs­möglichkeiten

Wie NtGetNextProcess hat dieser Syscall geringes Hintergrundrauschen — die meisten legitimen Prozessenumeratoren nutzen PSAPI oder Toolhelp. Eine Häufung von NtGetNextThread-Aufrufen aus einem einzelnen Nicht-Systemprozess ist verdächtig. Threat-Hunting-Queries, die ETW Microsoft-Windows-Kernel-Process (Thread-Erzeugung) mit dem *Fehlen* erwarteter Toolhelp-Section-Erzeugungen kombinieren, können dieses Muster aufdecken. Sysmon Event ID 8 (CreateRemoteThread) feuert beim nachfolgenden Hijack nur, wenn ein neuer Thread erzeugt wird, nicht bei Kontextwechsel-Hijacks — das hochwertige Signal ist daher NtSetContextThread gegen einen fremden Thread unmittelbar nach der Enumeration.

Direkte Syscall-Beispiele

cStealth thread enumeration of a target process

// Walk every thread of a given process without Toolhelp32.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *PNT_GET_NEXT_THREAD)(HANDLE, HANDLE, ACCESS_MASK, ULONG, ULONG, PHANDLE);

void EnumerateThreads(HANDLE hProcess) {
    HMODULE nt = GetModuleHandleA("ntdll.dll");
    PNT_GET_NEXT_THREAD pNtGetNextThread = (PNT_GET_NEXT_THREAD)GetProcAddress(nt, "NtGetNextThread");

    HANDLE hThread = NULL;
    HANDLE hNext   = NULL;
    while (pNtGetNextThread(hProcess, hThread, THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME,
                            0, 0, &hNext) == 0) {
        if (hThread) CloseHandle(hThread);
        hThread = hNext;
        // ... inspect TEB / GetThreadContext / hijack candidate ...
    }
    if (hThread) CloseHandle(hThread);
}

asmx64 direct stub (Win11 24H2, SSN 0x101)

NtGetNextThread PROC
    mov  r10, rcx
    mov  eax, 101h
    syscall
    ret
NtGetNextThread ENDP

MITRE ATT&CK-Mappings

Last verified: 2026-05-20