[NTOS:PS] Implement Vista+ NtQueryInformationThread(ThreadHideFromDebugger) support (#8486)

https://ntquery.wordpress.com/2014/03/29/anti-debug-ntsetinformationthread/
indicates that starting Vista, `NtQueryInformationThread()` supports
querying the `ThreadHideFromDebugger` information.

This was noticed by contributor Mikhail Tyukin, while testing anti-cheat
protected NT6+ games written with Unity.

See also
https://ntdoc.m417z.com/threadinfoclass#threadhidefromdebugger-17
for the buffers descriptions.
This commit is contained in:
Hermès Bélusca-Maïto
2026-03-08 18:51:42 +01:00
parent 509d8afdf5
commit d61f7e5cd0
2 changed files with 54 additions and 6 deletions
+14 -6
View File
@@ -503,12 +503,20 @@ static const INFORMATION_CLASS_INFO PsThreadInfoClass[] =
),
/* ThreadHideFromDebugger */
IQS_SAME
(
CHAR,
ULONG,
ICIF_SET | ICIF_SET_SIZE_VARIABLE
),
{
#if (NTDDI_VERSION >= NTDDI_VISTA)
sizeof(BOOLEAN), /* Query support only on Vista and above */
#else
0,
#endif
sizeof(ULONG), // UCHAR
0, /* No size for Set */
sizeof(ULONG),
#if (NTDDI_VERSION >= NTDDI_VISTA)
ICIF_QUERY |
#endif
ICIF_SET
},
/* ThreadBreakOnTermination */
IQS_SAME
+40
View File
@@ -3243,6 +3243,46 @@ NtQueryInformationThread(
ObDereferenceObject(Thread);
break;
#if (NTDDI_VERSION >= NTDDI_VISTA)
case ThreadHideFromDebugger:
{
/* Set the return length */
Length = sizeof(BOOLEAN);
if (ThreadInformationLength != Length)
{
Status = STATUS_INFO_LENGTH_MISMATCH;
break;
}
/* Reference the thread */
Status = ObReferenceObjectByHandle(ThreadHandle,
Access,
PsThreadType,
PreviousMode,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status))
break;
/* Protect write with SEH */
_SEH2_TRY
{
*(PBOOLEAN)ThreadInformation = Thread->HideFromDebugger;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Dereference the thread */
ObDereferenceObject(Thread);
break;
}
#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
case ThreadBreakOnTermination:
/* Set the return length */