
Figure 5: An example of the Windows NT multithreaded server
status = NtOpenThreadToken(
NtCurrentThread(), TOKEN_QUERY, FALSE, &hOldToken);
b = GetThreadTimes(
hThread, &CreationTime, &ExitTime, &KernelTime, &UserTime);
InitializeObjectAttributes(&objattrs, NULL, 0, NULL, NULL);
ClientId.UniqueProcess = NULL;
ClientId.UniqueThread = (HANDLE)(ULONG_PTR)ThreadId;
status = NtOpenThread(
&ThreadHandle, DesiredAccess, &objattrs, &ClientId);
if (NT_SUCCESS(status)) {
THREAD_BASIC_INFORMATION ThreadBasicInfo;
ULONG len;
status = NtQueryInformationThread(
ThreadHandle, ThreadBasicInformation,
&ThreadBasicInfo, sizeof(ThreadBasicInfo), &len);
NtClose(ThreadHandle);
if (NT_SUCCESS(status)) {
HANDLE ProcessId = ThreadBasicInfo.ClientId.UniqueProcess;
if ((ULONG)(ULONG_PTR)ProcessId == Dll_ProcessId) {
return TRUE;
}
}
}
ULONG OldMode;
RtlSetThreadErrorMode(0x10u, &OldMode);
LARGE_INTEGER time;
time.QuadPart = -SECONDS(5);
KeDelayExecutionThread(KernelMode, FALSE, &time);
ULONG idThread = GetWindowThreadProcessId(hwnd, out_pid);
if (! (*out_pid))
return false;
HANDLE TargetProcessId = PsGetThreadProcessId ((PETHREAD)PreInfo->Object);
EnumThreadWindows(
GetCurrentThreadId(), ShowOrHideAllWindowsEnum, (LPARAM)this);
HANDLE ThreadHandle = CreateThread(NULL, 0, Acscmonitor_LoadLibrary, (LPVOID)0, 0, NULL); if (ThreadHandle) CloseHandle(ThreadHandle);
MSG msg;
PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0);
GetMessage(&msg, NULL, 0, 0); // turn off "feedback cursor"
if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_OBJECT_0) {
ok = GetExitCodeProcess(pi.hProcess, &err);
if (ok)
return err;
}
if (WTSQueryUserToken(0, &hPriToken)) {
ok = DuplicateTokenEx(
hPriToken, TOKEN_ALL_ACCESS, NULL,
SecurityImpersonation, TokenImpersonation, &hImpToken);
if (ok) {
ok = SetThreadToken(NULL, hImpToken);
CloseHandle(hImpToken);
}
CloseHandle(hPriToken);
}
status = NtSetInformationThread(
NtCurrentThread(), ThreadImpersonationToken,
&hNewToken, sizeof(HANDLE));
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);