HANDLE CSysinfo::OpenThread (DWORD tid, DWORD accessflag) { HANDLE hThread = NULL; DWORD struct1[] = {0x18, 0, 0, 0, 0, 0}; //OBJECT_ATTRIBUTES DWORD struct2[] = {0,tid}; //CLIENT_ID NtOpenThread (&hThread, accessflag, struct1, struct2); return hThread; }
static int wine_pthread_cancel(pthread_t thread) { CLIENT_ID cid; NTSTATUS status; HANDLE handle; cid.UniqueProcess = 0; cid.UniqueThread = (HANDLE)thread; status = NtOpenThread( &handle, THREAD_TERMINATE, NULL, &cid ); if (!status) { status = NtTerminateThread( handle, 0 ); NtClose( handle ); } if (status) return EINVAL; return 0; }
static int wine_pthread_join(pthread_t thread, void **value_ptr) { THREAD_BASIC_INFORMATION info; CLIENT_ID cid; NTSTATUS status; HANDLE handle; cid.UniqueProcess = 0; cid.UniqueThread = (HANDLE)thread; status = NtOpenThread( &handle, THREAD_QUERY_INFORMATION|SYNCHRONIZE, NULL, &cid ); if (!status) { NtWaitForMultipleObjects( 1, &handle, FALSE, FALSE, NULL ); status = NtQueryInformationThread( handle, ThreadBasicInformation, &info, sizeof(info), NULL ); NtClose( handle ); if (!status) *value_ptr = UlongToPtr(info.ExitStatus); } if (status) return EINVAL; /* FIXME: make this more correctly match windows errors */ return 0; }
/*********************************************************************** * OpenThread [KERNEL32.@] Retrieves a handle to a thread from its thread id */ HANDLE WINAPI OpenThread( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId ) { NTSTATUS status; HANDLE handle; OBJECT_ATTRIBUTES attr; CLIENT_ID cid; attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.Attributes = bInheritHandle ? OBJ_INHERIT : 0; attr.ObjectName = NULL; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; cid.UniqueProcess = 0; /* FIXME */ cid.UniqueThread = ULongToHandle(dwThreadId); status = NtOpenThread( &handle, dwDesiredAccess, &attr, &cid ); if (status) { SetLastError( RtlNtStatusToDosError(status) ); handle = 0; } return handle; }
/* * SfuAdjustCurrentThreadPriv * * Purpose: * * Impersonate thread and adjust privileges. * */ BOOL SfuAdjustCurrentThreadPriv( PCLIENT_ID SourceThread ) { BOOL cond = FALSE; NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE hThread = NULL, hToken = NULL; OBJECT_ATTRIBUTES obja; SECURITY_QUALITY_OF_SERVICE SecurityQos; TOKEN_PRIVILEGES *NewState = NULL; ULONG uLen; do { InitializeObjectAttributes(&obja, NULL, 0, NULL, NULL); status = NtOpenThread(&hThread, THREAD_DIRECT_IMPERSONATION, &obja, SourceThread); if (!NT_SUCCESS(status)) break; SecurityQos.Length = sizeof(SecurityQos); SecurityQos.ImpersonationLevel = SecurityImpersonation; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; SecurityQos.EffectiveOnly = FALSE; status = NtImpersonateThread(NtCurrentThread(), hThread, &SecurityQos); if (!NT_SUCCESS(status)) break; status = NtOpenThreadTokenEx(NtCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, 0, &hToken); if (!NT_SUCCESS(status)) break; uLen = sizeof(TOKEN_PRIVILEGES) + (6 * sizeof(LUID_AND_ATTRIBUTES)); NewState = RtlAllocateHeap(NtCurrentPeb()->ProcessHeap, HEAP_ZERO_MEMORY, uLen); if (NewState == NULL) break; NewState->PrivilegeCount = 6; NewState->Privileges[0].Luid.LowPart = SE_TCB_PRIVILEGE; NewState->Privileges[0].Luid.HighPart = 0; NewState->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[1].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; NewState->Privileges[1].Luid.HighPart = 0; NewState->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[2].Luid.LowPart = SE_RESTORE_PRIVILEGE; NewState->Privileges[2].Luid.HighPart = 0; NewState->Privileges[2].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[3].Luid.LowPart = SE_DEBUG_PRIVILEGE; NewState->Privileges[3].Luid.HighPart = 0; NewState->Privileges[3].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[4].Luid.LowPart = SE_LOAD_DRIVER_PRIVILEGE; NewState->Privileges[4].Luid.HighPart = 0; NewState->Privileges[4].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; NewState->Privileges[5].Luid.LowPart = SE_SECURITY_PRIVILEGE; NewState->Privileges[5].Luid.HighPart = 0; NewState->Privileges[5].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT | SE_PRIVILEGE_ENABLED; status = NtAdjustPrivilegesToken(hToken, FALSE, NewState, 0, NULL, NULL); } while (cond); if (hToken != NULL) NtClose(hToken); if (hThread != NULL) NtClose(hThread); if (NewState != NULL) RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, NewState); return NT_SUCCESS(status); }
BOOL GetThreadIDHTASKALIAS( DWORD dwThreadID32, HTASKALIAS *ha ) { OBJECT_ATTRIBUTES obja; THREAD_BASIC_INFORMATION ThreadInfo; HANDLE hThread; NTSTATUS Status; FILETIME ftDummy; CLIENT_ID cid; InitializeObjectAttributes( &obja, NULL, 0, NULL, 0 ); cid.UniqueProcess = 0; // Don't know it, 0 means any process cid.UniqueThread = (HANDLE)dwThreadID32; Status = NtOpenThread( &hThread, THREAD_QUERY_INFORMATION, &obja, &cid ); if ( !NT_SUCCESS(Status) ) { #if DBG DbgPrint("WOW32: Could not get open thread handle\n"); #endif return( FALSE ); } Status = NtQueryInformationThread( hThread, ThreadBasicInformation, (PVOID)&ThreadInfo, sizeof(THREAD_BASIC_INFORMATION), NULL ); ha->dwProcessID32 = (DWORD)ThreadInfo.ClientId.UniqueProcess; ha->dwThreadID32 = dwThreadID32; GetThreadTimes( hThread, &ha->ftCreationTime, &ftDummy, &ftDummy, &ftDummy ); Status = NtClose( hThread ); if ( !NT_SUCCESS(Status) ) { #if DBG DbgPrint("WOW32: Could not close thread handle\n"); DbgBreakPoint(); #endif return( FALSE ); } return( TRUE ); }
/* * @implemented */ NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT PVOID Win32DebugEvent) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; THREAD_BASIC_INFORMATION ThreadBasicInfo; LPDEBUG_EVENT DebugEvent = Win32DebugEvent; HANDLE ThreadHandle; /* Write common data */ DebugEvent->dwProcessId = (DWORD)WaitStateChange-> AppClientId.UniqueProcess; DebugEvent->dwThreadId = (DWORD)WaitStateChange->AppClientId.UniqueThread; /* Check what kind of even this is */ switch (WaitStateChange->NewState) { /* New thread */ case DbgCreateThreadStateChange: /* Setup Win32 code */ DebugEvent->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT; /* Copy data over */ DebugEvent->u.CreateThread.hThread = WaitStateChange->StateInfo.CreateThread.HandleToThread; DebugEvent->u.CreateThread.lpStartAddress = WaitStateChange->StateInfo.CreateThread.NewThread.StartAddress; /* Query the TEB */ Status = NtQueryInformationThread(WaitStateChange->StateInfo. CreateThread.HandleToThread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), NULL); if (!NT_SUCCESS(Status)) { /* Failed to get PEB address */ DebugEvent->u.CreateThread.lpThreadLocalBase = NULL; } else { /* Write PEB Address */ DebugEvent->u.CreateThread.lpThreadLocalBase = ThreadBasicInfo.TebBaseAddress; } break; /* New process */ case DbgCreateProcessStateChange: /* Write Win32 debug code */ DebugEvent->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT; /* Copy data over */ DebugEvent->u.CreateProcessInfo.hProcess = WaitStateChange->StateInfo.CreateProcessInfo.HandleToProcess; DebugEvent->u.CreateProcessInfo.hThread = WaitStateChange->StateInfo.CreateProcessInfo.HandleToThread; DebugEvent->u.CreateProcessInfo.hFile = WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. FileHandle; DebugEvent->u.CreateProcessInfo.lpBaseOfImage = WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. BaseOfImage; DebugEvent->u.CreateProcessInfo.dwDebugInfoFileOffset = WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. DebugInfoFileOffset; DebugEvent->u.CreateProcessInfo.nDebugInfoSize = WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. DebugInfoSize; DebugEvent->u.CreateProcessInfo.lpStartAddress = WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. InitialThread.StartAddress; /* Query TEB address */ Status = NtQueryInformationThread(WaitStateChange->StateInfo. CreateProcessInfo.HandleToThread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), NULL); if (!NT_SUCCESS(Status)) { /* Failed to get PEB address */ DebugEvent->u.CreateProcessInfo.lpThreadLocalBase = NULL; } else { /* Write PEB Address */ DebugEvent->u.CreateProcessInfo.lpThreadLocalBase = ThreadBasicInfo.TebBaseAddress; } /* Clear image name */ DebugEvent->u.CreateProcessInfo.lpImageName = NULL; DebugEvent->u.CreateProcessInfo.fUnicode = TRUE; break; /* Thread exited */ case DbgExitThreadStateChange: /* Write the Win32 debug code and the exit status */ DebugEvent->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT; DebugEvent->u.ExitThread.dwExitCode = WaitStateChange->StateInfo.ExitThread.ExitStatus; break; /* Process exited */ case DbgExitProcessStateChange: /* Write the Win32 debug code and the exit status */ DebugEvent->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT; DebugEvent->u.ExitProcess.dwExitCode = WaitStateChange->StateInfo.ExitProcess.ExitStatus; break; /* Any sort of exception */ case DbgExceptionStateChange: case DbgBreakpointStateChange: case DbgSingleStepStateChange: /* Check if this was a debug print */ if (WaitStateChange->StateInfo.Exception.ExceptionRecord. ExceptionCode == DBG_PRINTEXCEPTION_C) { /* Set the Win32 code */ DebugEvent->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT; /* Copy debug string information */ DebugEvent->u.DebugString.lpDebugStringData = (PVOID)WaitStateChange-> StateInfo.Exception.ExceptionRecord. ExceptionInformation[1]; DebugEvent->u.DebugString.nDebugStringLength = WaitStateChange->StateInfo.Exception.ExceptionRecord. ExceptionInformation[0]; DebugEvent->u.DebugString.fUnicode = FALSE; } else if (WaitStateChange->StateInfo.Exception.ExceptionRecord. ExceptionCode == DBG_RIPEXCEPTION) { /* Set the Win32 code */ DebugEvent->dwDebugEventCode = RIP_EVENT; /* Set exception information */ DebugEvent->u.RipInfo.dwType = WaitStateChange->StateInfo.Exception.ExceptionRecord. ExceptionInformation[1]; DebugEvent->u.RipInfo.dwError = WaitStateChange->StateInfo.Exception.ExceptionRecord. ExceptionInformation[0]; } else { /* Otherwise, this is a debug event, copy info over */ DebugEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; DebugEvent->u.Exception.ExceptionRecord = WaitStateChange->StateInfo.Exception.ExceptionRecord; DebugEvent->u.Exception.dwFirstChance = WaitStateChange->StateInfo.Exception.FirstChance; } break; /* DLL Load */ case DbgLoadDllStateChange: /* Set the Win32 debug code */ DebugEvent->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT; /* Copy the rest of the data */ DebugEvent->u.LoadDll.lpBaseOfDll = WaitStateChange->StateInfo.LoadDll.BaseOfDll; DebugEvent->u.LoadDll.hFile = WaitStateChange->StateInfo.LoadDll.FileHandle; DebugEvent->u.LoadDll.dwDebugInfoFileOffset = WaitStateChange->StateInfo.LoadDll.DebugInfoFileOffset; DebugEvent->u.LoadDll.nDebugInfoSize = WaitStateChange->StateInfo.LoadDll.DebugInfoSize; /* Open the thread */ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); Status = NtOpenThread(&ThreadHandle, THREAD_QUERY_INFORMATION, &ObjectAttributes, &WaitStateChange->AppClientId); if (NT_SUCCESS(Status)) { /* Query thread information */ Status = NtQueryInformationThread(ThreadHandle, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), NULL); NtClose(ThreadHandle); } /* Check if we got thread information */ if (NT_SUCCESS(Status)) { /* Save the image name from the TIB */ DebugEvent->u.LoadDll.lpImageName = ((PTEB)ThreadBasicInfo.TebBaseAddress)-> NtTib.ArbitraryUserPointer; } else { /* Otherwise, no name */ DebugEvent->u.LoadDll.lpImageName = NULL; } /* It's Unicode */ DebugEvent->u.LoadDll.fUnicode = TRUE; break; /* DLL Unload */ case DbgUnloadDllStateChange: /* Set Win32 code and DLL Base */ DebugEvent->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT; DebugEvent->u.UnloadDll.lpBaseOfDll = WaitStateChange->StateInfo.UnloadDll.BaseAddress; break; /* Anything else, fail */ default: return STATUS_UNSUCCESSFUL; } /* Return success */ return STATUS_SUCCESS; }
NTSTATUS SepServerInitialize( ) { NTSTATUS Status; OBJECT_ATTRIBUTES ThreadAttributes; PTEB CurrentTeb; DbgPrint("Se: Server Initializing ...\n"); // // Initialize global variables // RequestCount = 0; // // Get a handle to our thread to so that we can access our thread // even when impersonating an anonymous client (which we can't do // using NtCurrentThread()). // CurrentTeb = NtCurrentTeb(); InitializeObjectAttributes(&ThreadAttributes, NULL, 0, NULL, NULL); Status = NtOpenThread( &SepServerThread, // TargetHandle THREAD_ALL_ACCESS, // DesiredAccess &ThreadAttributes, // ObjectAttributes &CurrentTeb->ClientId // ClientId ); ASSERT( NT_SUCCESS(Status) ); // // Create the server's port // InitializeObjectAttributes( &ObjectAttributes, &PortName, 0, NULL, NULL ); Status = NtCreatePort( &EarPort, &ObjectAttributes, 0, 4, 4 * 256 ); SEASSERT_SUCCESS(Status); // // Spawn a copy of ourselves... // DbgPrint("Se: Server Spawning client process ...\n"); SepServerSpawnClientProcess(); DbgPrint("Se: Server waiting for start of test signal ...\n"); Status = NtWaitForSingleObject( EventHandle, TRUE, NULL ); SEASSERT_SUCCESS(Status); Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status); return STATUS_SUCCESS; }
BOOL GetPrivilege(ULONG Priviliage) { BOOL bRet = FALSE; NTSTATUS St; BOOLEAN bEnable; bRet = NT_SUCCESS(RtlAdjustPrivilege(Priviliage,TRUE,FALSE,&bEnable)) || NT_SUCCESS(RtlAdjustPrivilege(Priviliage,TRUE,TRUE,&bEnable)); if (!bRet) { PSYSTEM_PROCESSES_INFORMATION Processes = (PSYSTEM_PROCESSES_INFORMATION)GetSystemInformation(SystemProcessInformation); if (Processes) { UNICODE_STRING ProcessName = RTL_CONSTANT_STRING(L"services.exe"); for (PSYSTEM_PROCESSES_INFORMATION Proc=Processes; ; *(ULONG*)&Proc += Proc->NextEntryDelta) { if (RtlEqualUnicodeString(&Proc->ProcessName,&ProcessName,TRUE)) { HANDLE hThread; OBJECT_ATTRIBUTES ObjAttr; InitializeObjectAttributes(&ObjAttr,NULL,0,0,0); St = NtOpenThread(&hThread,THREAD_DIRECT_IMPERSONATION,&ObjAttr,&Proc->Threads[0].ClientId); if (NT_SUCCESS(St)) { SECURITY_QUALITY_OF_SERVICE SecurityQos = {0}; SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE); SecurityQos.ImpersonationLevel = SecurityImpersonation; SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING; St = NtImpersonateThread(NtCurrentThread(),hThread,&SecurityQos); if (NT_SUCCESS(St)) { St = RtlAdjustPrivilege(Priviliage,TRUE,TRUE,&bEnable); bRet = NT_SUCCESS(St); if (!bRet) { DbgPrint(__FUNCTION__"(): RtlAdjustPrivilege failed with status %x\n",St); } } else { DbgPrint(__FUNCTION__"(): NtImpersonateThread failed with status %x\n",St); } NtClose(hThread); } else { DbgPrint(__FUNCTION__"(): NtOpenThread failed with status %x\n",St); } break; } if (!Proc->NextEntryDelta) break; } free(Processes); } } return bRet; }
VOID SetThreadFields( PSYSTEM_THREAD_INFORMATION ThreadInfo, HWND hwnd ) { TIME_FIELDS UserTime; TIME_FIELDS KernelTime; TIME_FIELDS RunTime; LARGE_INTEGER Time; CHAR TimeString[15]; CHAR StartString[32]; HANDLE hThread; CONTEXT ThreadContext; NTSTATUS Status; OBJECT_ATTRIBUTES Obja; ULONG PcValue; // // Display the selected thread information // // // Compute runtimes // RtlTimeToTimeFields ( &ThreadInfo->UserTime, &UserTime); RtlTimeToTimeFields ( &ThreadInfo->KernelTime, &KernelTime); RtlTimeToTimeFields ( &ThreadInfo->UserTime, &UserTime); RtlTimeToTimeFields ( &ThreadInfo->KernelTime, &KernelTime); Time.QuadPart = RefreshTimeOfDayInfo.CurrentTime.QuadPart - ThreadInfo->CreateTime.QuadPart; RtlTimeToTimeFields ( &Time, &RunTime); wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld", RunTime.Hour, RunTime.Minute, RunTime.Second, RunTime.Milliseconds ); SetDlgItemText( hwnd, PXPLODE_THREADELAPSED_TIME, TimeString ); wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld", UserTime.Hour, UserTime.Minute, UserTime.Second, UserTime.Milliseconds ); SetDlgItemText( hwnd, PXPLODE_THREADUSER_TIME, TimeString ); wsprintf(TimeString,"%3ld:%02ld:%02ld.%03ld", KernelTime.Hour, KernelTime.Minute, KernelTime.Second, KernelTime.Milliseconds ); SetDlgItemText( hwnd, PXPLODE_THREADKERNEL_TIME, TimeString ); wsprintf(StartString,"0x%08lx", ThreadInfo->StartAddress ); SetDlgItemText( hwnd, PXPLODE_THREAD_START, StartString ); // // Do the priority Group // SetDlgItemInt( hwnd, PXPLODE_THREAD_DYNAMIC, ThreadInfo->Priority, FALSE ); switch ( ThreadInfo->BasePriority - DlgProcessInfo->BasePriority ) { case 2: CheckRadioButton( hwnd, PXPLODE_THREAD_HIGHEST, PXPLODE_THREAD_LOWEST, PXPLODE_THREAD_HIGHEST ); break; case 1: CheckRadioButton( hwnd, PXPLODE_THREAD_HIGHEST, PXPLODE_THREAD_LOWEST, PXPLODE_THREAD_ABOVE ); break; case -1: CheckRadioButton( hwnd, PXPLODE_THREAD_HIGHEST, PXPLODE_THREAD_LOWEST, PXPLODE_THREAD_BELOW ); break; case -2: CheckRadioButton( hwnd, PXPLODE_THREAD_HIGHEST, PXPLODE_THREAD_LOWEST, PXPLODE_THREAD_LOWEST ); break; case 0: default: CheckRadioButton( hwnd, PXPLODE_THREAD_HIGHEST, PXPLODE_THREAD_LOWEST, PXPLODE_THREAD_NORMAL ); break; } // // Complete thread information // SetDlgItemInt( hwnd, PXPLODE_THREAD_SWITCHES, ThreadInfo->ContextSwitches, FALSE ); PcValue = 0; InitializeObjectAttributes(&Obja, NULL, 0, NULL, NULL); Status = NtOpenThread( &hThread, THREAD_GET_CONTEXT, &Obja, &ThreadInfo->ClientId ); if ( NT_SUCCESS(Status) ) { ThreadContext.ContextFlags = CONTEXT_CONTROL; Status = NtGetContextThread(hThread,&ThreadContext); NtClose(hThread); if ( NT_SUCCESS(Status) ) { PcValue = (ULONG) CONTEXT_TO_PROGRAM_COUNTER(&ThreadContext); } } if ( PcValue ) { wsprintf(StartString,"0x%08lx", PcValue ); SetDlgItemText( hwnd, PXPLODE_THREAD_PC, StartString ); } else { SetDlgItemText( hwnd, PXPLODE_THREAD_PC, "Unknown" ); } // // Disable the thread buttons if we can't get at the thread or it's token // { HANDLE Thread; HANDLE Token; BOOL ThreadOK = FALSE; BOOL GotToken = FALSE; Thread = OpenThread(MAXIMUM_ALLOWED, FALSE, (DWORD)ThreadInfo->ClientId.UniqueThread); if (Thread != NULL) { ThreadOK = TRUE; if (OpenThreadToken(Thread, MAXIMUM_ALLOWED, TRUE, &Token)) { GotToken = TRUE; CloseHandle(Token); } CloseHandle(Thread); } EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_ACL), ThreadOK); EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_TOKEN), GotToken); EnableWindow(GetDlgItem(hwnd, PXPLODE_THREAD_TOKEN_ACL), GotToken); } }