Skip to content

Instantly share code, notes, and snippets.

@kawaii-ghost
Last active June 15, 2025 00:34
Show Gist options
  • Save kawaii-ghost/b1b003cd38bf89305773f9d897380801 to your computer and use it in GitHub Desktop.
Save kawaii-ghost/b1b003cd38bf89305773f9d897380801 to your computer and use it in GitHub Desktop.
NtWaitForAlertByThreadId demonstration
#include <cstdio>
#include <Veil.h>
NTSTATUS NTAPI print(PVOID arg);
#define NTHREAD 8
struct _THREAD_ARG {
LONG volatile g_Counter;
HANDLE ThreadId;
} typedef THREAD_ARG;
int main()
{
THREAD_ARG ThreadArg = {.g_Counter = 0, .ThreadId = NtCurrentTeb()->ClientId.UniqueThread};
for (size_t i = 0; i < NTHREAD; i++) {
PTEB Teb;
PS_ATTRIBUTE_LIST AttrList
{
sizeof(AttrList),
{{.Attribute = PsAttributeTebAddress | PS_ATTRIBUTE_THREAD, .Size = sizeof(Teb), .ValuePtr = &Teb}}
};
InterlockedIncrement(&ThreadArg.g_Counter);
HANDLE Thread;
NtCreateThreadEx(&Thread,
STANDARD_RIGHTS_REQUIRED,
nullptr,
NtCurrentProcess(),
print,
(PVOID)&ThreadArg,
THREAD_CREATE_FLAGS_NONE,
0,
0,
0,
&AttrList);
Teb->DbgSsReserved[1] = Thread;
}
while (ThreadArg.g_Counter != 0) {
NtWaitForAlertByThreadId((PVOID)&ThreadArg.g_Counter, nullptr);
}
}
NTSTATUS NTAPI print(PVOID arg)
{
THREAD_ARG *ThreadArg = (THREAD_ARG *)arg;
DWORD Tid = HandleToUlong(NtCurrentTeb()->ClientId.UniqueThread);
printf("Hello from thread %ld\n", Tid);
LARGE_INTEGER Time = {.QuadPart = 1 * 1000 * -10000LL};
RtlDelayExecution(FALSE, &Time);
printf("Goodbye thread %ld\n", Tid);
if (InterlockedDecrement(&ThreadArg->g_Counter) == 0) {
NtAlertThreadByThreadId(ThreadArg->ThreadId);
}
return STATUS_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment