NTSTATUS PhpEnumHiddenProcessesCsrHandles( _In_ PPH_ENUM_HIDDEN_PROCESSES_CALLBACK Callback, _In_opt_ PVOID Context ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; PPH_LIST pids; CSR_HANDLES_CONTEXT context; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; pids = PhCreateList(40); process = PH_FIRST_PROCESS(processes); do { PhAddItemList(pids, process->UniqueProcessId); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); context.Callback = Callback; context.Context = Context; context.Pids = pids; status = PhEnumCsrProcessHandles(PhpCsrProcessHandlesCallback, &context); PhDereferenceObject(pids); return status; }
static NTSTATUS NTAPI TerminatorTT2( _In_ HANDLE ProcessId ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; CONTEXT context; PVOID exitProcess; exitProcess = GetExitProcessFunction(); if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; process = PhFindProcessInformation(processes, ProcessId); if (!process) { PhFree(processes); return STATUS_INVALID_CID; } for (i = 0; i < process->NumberOfThreads; i++) { HANDLE threadHandle; if (NT_SUCCESS(PhOpenThread( &threadHandle, THREAD_GET_CONTEXT | THREAD_SET_CONTEXT, process->Threads[i].ClientId.UniqueThread ))) { #ifdef _M_IX86 context.ContextFlags = CONTEXT_CONTROL; PhGetThreadContext(threadHandle, &context); context.Eip = (ULONG)exitProcess; PhSetThreadContext(threadHandle, &context); #else context.ContextFlags = CONTEXT_CONTROL; PhGetThreadContext(threadHandle, &context); context.Rip = (ULONG64)exitProcess; PhSetThreadContext(threadHandle, &context); #endif NtClose(threadHandle); } } PhFree(processes); return STATUS_SUCCESS; }
VOID PhThreadProviderInitialUpdate( __in PPH_THREAD_PROVIDER ThreadProvider ) { PVOID processes; if (NT_SUCCESS(PhEnumProcesses(&processes))) { PhpThreadProviderUpdate(ThreadProvider, processes); PhFree(processes); } }
NTSTATUS PhpOpenCsrProcesses( _Out_ PHANDLE *ProcessHandles, _Out_ PULONG NumberOfProcessHandles ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; PPH_LIST processHandleList; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; processHandleList = PhCreateList(8); process = PH_FIRST_PROCESS(processes); do { HANDLE processHandle; PH_KNOWN_PROCESS_TYPE knownProcessType; if (NT_SUCCESS(PhOpenProcess( &processHandle, ProcessQueryAccess | PROCESS_DUP_HANDLE, process->UniqueProcessId ))) { if (NT_SUCCESS(PhGetProcessKnownType( processHandle, &knownProcessType )) && (knownProcessType & KnownProcessTypeMask) == WindowsSubsystemProcessType) { PhAddItemList(processHandleList, processHandle); } else { NtClose(processHandle); } } } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); *ProcessHandles = PhAllocateCopy(processHandleList->Items, processHandleList->Count * sizeof(HANDLE)); *NumberOfProcessHandles = processHandleList->Count; PhDereferenceObject(processHandleList); return status; }
static BOOLEAN PhpWaitUntilThreadIsWaiting( _In_ HANDLE ThreadHandle ) { ULONG attempts; BOOLEAN isWaiting = FALSE; THREAD_BASIC_INFORMATION basicInfo; if (!NT_SUCCESS(PhGetThreadBasicInformation(ThreadHandle, &basicInfo))) return FALSE; for (attempts = 0; attempts < 20; attempts++) { PVOID processes; PSYSTEM_PROCESS_INFORMATION processInfo; ULONG i; PhDelayExecution(100); if (!NT_SUCCESS(PhEnumProcesses(&processes))) break; processInfo = PhFindProcessInformation(processes, basicInfo.ClientId.UniqueProcess); if (processInfo) { for (i = 0; i < processInfo->NumberOfThreads; i++) { if ( processInfo->Threads[i].ClientId.UniqueThread == basicInfo.ClientId.UniqueThread && processInfo->Threads[i].ThreadState == Waiting && (processInfo->Threads[i].WaitReason == UserRequest || processInfo->Threads[i].WaitReason == Executive) ) { isWaiting = TRUE; break; } } } PhFree(processes); if (isWaiting) break; PhDelayExecution(500); } return isWaiting; }
static NTSTATUS NTAPI TerminatorTTGeneric( _In_ HANDLE ProcessId, _In_ BOOLEAN UseKph, _In_ BOOLEAN UseKphDangerous ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; if ((UseKph || UseKphDangerous) && !KphIsConnected()) return STATUS_NOT_SUPPORTED; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; process = PhFindProcessInformation(processes, ProcessId); if (!process) { PhFree(processes); return STATUS_INVALID_CID; } for (i = 0; i < process->NumberOfThreads; i++) { HANDLE threadHandle; if (NT_SUCCESS(PhOpenThread( &threadHandle, THREAD_TERMINATE, process->Threads[i].ClientId.UniqueThread ))) { if (UseKphDangerous) KphTerminateThreadUnsafe(threadHandle, STATUS_SUCCESS); else if (UseKph) KphTerminateThread(threadHandle, STATUS_SUCCESS); else NtTerminateThread(threadHandle, STATUS_SUCCESS); NtClose(threadHandle); } } PhFree(processes); return STATUS_SUCCESS; }
VOID EtUpdateProcessInformation( VOID ) { PhAcquireQueuedLockExclusive(&EtpProcessInformationLock); if (EtpProcessInformation) { PhFree(EtpProcessInformation); EtpProcessInformation = NULL; } PhEnumProcesses(&EtpProcessInformation); PhReleaseQueuedLockExclusive(&EtpProcessInformationLock); }
BOOLEAN IsProcessSuspended( _In_ HANDLE ProcessId ) { PVOID processes; PSYSTEM_PROCESS_INFORMATION process; if (NT_SUCCESS(PhEnumProcesses(&processes))) { if (process = PhFindProcessInformation(processes, ProcessId)) return PhGetProcessIsSuspended(process); PhFree(processes); } return FALSE; }
static VOID PhpRefreshProcessList( _In_ HWND hwndDlg, _In_ PCHOOSE_PROCESS_DIALOG_CONTEXT Context ) { NTSTATUS status; HWND lvHandle; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; lvHandle = Context->ListViewHandle; ListView_DeleteAllItems(lvHandle); ImageList_RemoveAll(Context->ImageList); if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) { PhShowStatus(hwndDlg, L"Unable to enumerate processes", status, 0); return; } ExtendedListView_SetRedraw(lvHandle, FALSE); process = PH_FIRST_PROCESS(processes); do { INT lvItemIndex; PPH_STRING name; HANDLE processHandle; PPH_STRING fileName = NULL; HICON icon = NULL; WCHAR processIdString[PH_INT32_STR_LEN_1]; PPH_STRING userName = NULL; INT imageIndex; if (process->UniqueProcessId != SYSTEM_IDLE_PROCESS_ID) name = PhCreateStringFromUnicodeString(&process->ImageName); else name = PhCreateString(SYSTEM_IDLE_PROCESS_NAME); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, name->Buffer, process->UniqueProcessId); PhDereferenceObject(name); if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess, process->UniqueProcessId))) { HANDLE tokenHandle; PTOKEN_USER user; if (!WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID) PhGetProcessImageFileName(processHandle, &fileName); if (NT_SUCCESS(PhOpenProcessToken(&tokenHandle, TOKEN_QUERY, processHandle))) { if (NT_SUCCESS(PhGetTokenUser(tokenHandle, &user))) { userName = PhGetSidFullName(user->User.Sid, TRUE, NULL); PhFree(user); } NtClose(tokenHandle); } NtClose(processHandle); } if (process->UniqueProcessId == SYSTEM_IDLE_PROCESS_ID && !userName && PhLocalSystemName) PhSetReference(&userName, PhLocalSystemName); if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID && process->UniqueProcessId != SYSTEM_PROCESS_ID) PhGetProcessImageFileNameByProcessId(process->UniqueProcessId, &fileName); if (process->UniqueProcessId == SYSTEM_PROCESS_ID) fileName = PhGetKernelFileName(); if (fileName) PhMoveReference(&fileName, PhGetFileName(fileName)); icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", FALSE); // Icon if (icon) { imageIndex = ImageList_AddIcon(Context->ImageList, icon); PhSetListViewItemImageIndex(Context->ListViewHandle, lvItemIndex, imageIndex); DestroyIcon(icon); } // PID PhPrintUInt32(processIdString, HandleToUlong(process->UniqueProcessId)); PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 1, processIdString); // User Name PhSetListViewSubItem(Context->ListViewHandle, lvItemIndex, 2, PhGetString(userName)); if (userName) PhDereferenceObject(userName); if (fileName) PhDereferenceObject(fileName); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); ExtendedListView_SortItems(lvHandle); ExtendedListView_SetRedraw(lvHandle, TRUE); }
static NTSTATUS PhpFindObjectsThreadStart( _In_ PVOID Parameter ) { NTSTATUS status = STATUS_SUCCESS; PSYSTEM_HANDLE_INFORMATION_EX handles; PPH_HASHTABLE processHandleHashtable; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; // Refuse to search with no filter. if (SearchString->Length == 0) goto Exit; // Try to get a search pointer from the search string. UseSearchPointer = PhStringToInteger64(&SearchString->sr, 0, &SearchPointer); _wcsupr(SearchString->Buffer); if (NT_SUCCESS(status = PhEnumHandlesEx(&handles))) { static PH_INITONCE initOnce = PH_INITONCE_INIT; static ULONG fileObjectTypeIndex = -1; BOOLEAN useWorkQueue = FALSE; PH_WORK_QUEUE workQueue; processHandleHashtable = PhCreateSimpleHashtable(8); if (!KphIsConnected() && WindowsVersion >= WINDOWS_VISTA) { useWorkQueue = TRUE; PhInitializeWorkQueue(&workQueue, 1, 20, 1000); if (PhBeginInitOnce(&initOnce)) { UNICODE_STRING fileTypeName; RtlInitUnicodeString(&fileTypeName, L"File"); fileObjectTypeIndex = PhGetObjectTypeNumber(&fileTypeName); PhEndInitOnce(&initOnce); } } for (i = 0; i < handles->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; PVOID *processHandlePtr; HANDLE processHandle; if (SearchStop) break; // Open a handle to the process if we don't already have one. processHandlePtr = PhFindItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId ); if (processHandlePtr) { processHandle = (HANDLE)*processHandlePtr; } else { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, (HANDLE)handleInfo->UniqueProcessId ))) { PhAddItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId, processHandle ); } else { continue; } } if (useWorkQueue && handleInfo->ObjectTypeIndex == (USHORT)fileObjectTypeIndex) { PSEARCH_HANDLE_CONTEXT searchHandleContext; searchHandleContext = PhAllocate(sizeof(SEARCH_HANDLE_CONTEXT)); searchHandleContext->NeedToFree = TRUE; searchHandleContext->HandleInfo = handleInfo; searchHandleContext->ProcessHandle = processHandle; PhQueueItemWorkQueue(&workQueue, SearchHandleFunction, searchHandleContext); } else { SEARCH_HANDLE_CONTEXT searchHandleContext; searchHandleContext.NeedToFree = FALSE; searchHandleContext.HandleInfo = handleInfo; searchHandleContext.ProcessHandle = processHandle; SearchHandleFunction(&searchHandleContext); } } if (useWorkQueue) { PhWaitForWorkQueue(&workQueue); PhDeleteWorkQueue(&workQueue); } { PPH_KEY_VALUE_PAIR entry; i = 0; while (PhEnumHashtable(processHandleHashtable, &entry, &i)) NtClose((HANDLE)entry->Value); } PhDereferenceObject(processHandleHashtable); PhFree(handles); } if (NT_SUCCESS(PhEnumProcesses(&processes))) { process = PH_FIRST_PROCESS(processes); do { PhEnumGenericModules( process->UniqueProcessId, NULL, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, (PVOID)process->UniqueProcessId ); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); } Exit: PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_FINISHED, status, 0); return STATUS_SUCCESS; }
NTSTATUS PhCommandModeStart( VOID ) { static PH_COMMAND_LINE_OPTION options[] = { { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType } }; NTSTATUS status; PPH_STRING commandLine; if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine))) return status; PhParseCommandLine( &commandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpCommandModeOptionCallback, NULL ); PhDereferenceObject(commandLine); if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE)) { SIZE_T i; SIZE_T processIdLength; HANDLE processId; HANDLE processHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; processIdLength = PhStartupParameters.CommandObject->Length / 2; for (i = 0; i < processIdLength; i++) { if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i])) break; } if (i == processIdLength) { ULONG64 processId64; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64)) return STATUS_INVALID_PARAMETER; processId = (HANDLE)processId64; } else { PVOID processes; PSYSTEM_PROCESS_INFORMATION process; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr))) { PhFree(processes); return STATUS_NOT_FOUND; } processId = process->UniqueProcessId; PhFree(processes); } if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId))) { status = NtTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtSuspendProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtResumeProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE)) { UCHAR priority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE)) priority = PROCESS_PRIORITY_CLASS_IDLE; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) priority = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) priority = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE)) priority = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = priority; status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE)) { ULONG ioPriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE)) ioPriority = 0; else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE)) ioPriority = 1; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) ioPriority = 2; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) ioPriority = 3; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = PhSetProcessIoPriority(processHandle, ioPriority); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE)) { ULONG64 pagePriority64; ULONG pagePriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64); pagePriority = (ULONG)pagePriority64; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = NtSetInformationProcess( processHandle, ProcessPagePriority, &pagePriority, sizeof(ULONG) ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhInjectDllProcess( processHandle, PhStartupParameters.CommandValue->Buffer, &timeout ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { PVOID baseAddress; if (NT_SUCCESS(status = PhpGetDllBaseRemote( processHandle, &PhStartupParameters.CommandValue->sr, &baseAddress ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhUnloadDllProcess( processHandle, baseAddress, &timeout ); } NtClose(processHandle); } } } else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE)) { SC_HANDLE serviceHandle; SERVICE_STATUS serviceStatus; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_START ))) return PhGetLastWin32ErrorAsNtStatus(); if (!StartService(serviceHandle, 0, NULL)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_STOP ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, DELETE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!DeleteService(serviceHandle)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } } else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE)) { ULONG64 threadId64; HANDLE threadId; HANDLE threadHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64)) return STATUS_INVALID_PARAMETER; threadId = (HANDLE)threadId64; if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId))) { status = NtTerminateThread(threadHandle, STATUS_SUCCESS); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtSuspendThread(threadHandle, NULL); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtResumeThread(threadHandle, NULL); NtClose(threadHandle); } } } return status; }
static NTSTATUS PhpFindObjectsThreadStart( __in PVOID Parameter ) { PSYSTEM_HANDLE_INFORMATION_EX handles; PPH_HASHTABLE processHandleHashtable; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; // Refuse to search with no filter. if (SearchString->Length == 0) goto Exit; // Try to get a search pointer from the search string. UseSearchPointer = PhStringToInteger64(&SearchString->sr, 0, &SearchPointer); PhUpperString(SearchString); if (NT_SUCCESS(PhEnumHandlesEx(&handles))) { processHandleHashtable = PhCreateSimpleHashtable(8); for (i = 0; i < handles->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; PPVOID processHandlePtr; HANDLE processHandle; PPH_STRING typeName; PPH_STRING bestObjectName; if (SearchStop) break; // Open a handle to the process if we don't already have one. processHandlePtr = PhFindItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId ); if (processHandlePtr) { processHandle = (HANDLE)*processHandlePtr; } else { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, (HANDLE)handleInfo->UniqueProcessId ))) { PhAddItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId, processHandle ); } else { continue; } } // Get handle information. if (NT_SUCCESS(PhGetHandleInformation( processHandle, (HANDLE)handleInfo->HandleValue, handleInfo->ObjectTypeIndex, NULL, &typeName, NULL, &bestObjectName ))) { PPH_STRING upperBestObjectName; upperBestObjectName = PhDuplicateString(bestObjectName); PhUpperString(upperBestObjectName); if ( PhFindStringInString(upperBestObjectName, 0, SearchString->Buffer) != -1 || (UseSearchPointer && handleInfo->Object == (PVOID)SearchPointer) ) { PPHP_OBJECT_SEARCH_RESULT searchResult; searchResult = PhAllocate(sizeof(PHP_OBJECT_SEARCH_RESULT)); searchResult->ProcessId = (HANDLE)handleInfo->UniqueProcessId; searchResult->ResultType = HandleSearchResult; searchResult->Handle = (HANDLE)handleInfo->HandleValue; searchResult->TypeName = typeName; searchResult->Name = bestObjectName; PhPrintPointer(searchResult->HandleString, (PVOID)searchResult->Handle); searchResult->Info = *handleInfo; PhAcquireQueuedLockExclusive(&SearchResultsLock); PhAddItemList(SearchResults, searchResult); // Update the search results in batches of 40. if (SearchResults->Count % 40 == 0) PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_UPDATE, 0, 0); PhReleaseQueuedLockExclusive(&SearchResultsLock); } else { PhDereferenceObject(typeName); PhDereferenceObject(bestObjectName); } PhDereferenceObject(upperBestObjectName); } } { PPH_KEY_VALUE_PAIR entry; i = 0; while (PhEnumHashtable(processHandleHashtable, &entry, &i)) NtClose((HANDLE)entry->Value); } PhDereferenceObject(processHandleHashtable); PhFree(handles); } if (NT_SUCCESS(PhEnumProcesses(&processes))) { process = PH_FIRST_PROCESS(processes); do { PhEnumGenericModules( process->UniqueProcessId, NULL, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, (PVOID)process->UniqueProcessId ); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); } Exit: PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_FINISHED, 0, 0); return STATUS_SUCCESS; }
NTSTATUS PhpEnumHiddenProcessesBruteForce( _In_ PPH_ENUM_HIDDEN_PROCESSES_CALLBACK Callback, _In_opt_ PVOID Context ) { NTSTATUS status; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; PPH_LIST pids; ULONG pid; BOOLEAN stop = FALSE; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; pids = PhCreateList(40); process = PH_FIRST_PROCESS(processes); do { PhAddItemList(pids, process->UniqueProcessId); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); for (pid = 8; pid <= 65536; pid += 4) { NTSTATUS status2; HANDLE processHandle; PH_HIDDEN_PROCESS_ENTRY entry; KERNEL_USER_TIMES times; PPH_STRING fileName; status2 = PhOpenProcess( &processHandle, ProcessQueryAccess, UlongToHandle(pid) ); if (NT_SUCCESS(status2)) { entry.ProcessId = UlongToHandle(pid); if (NT_SUCCESS(status2 = PhGetProcessTimes( processHandle, × )) && NT_SUCCESS(status2 = PhGetProcessImageFileName( processHandle, &fileName ))) { entry.FileName = PhGetFileName(fileName); PhDereferenceObject(fileName); if (times.ExitTime.QuadPart != 0) entry.Type = TerminatedProcess; else if (PhFindItemList(pids, UlongToHandle(pid)) != -1) entry.Type = NormalProcess; else entry.Type = HiddenProcess; if (!Callback(&entry, Context)) stop = TRUE; PhDereferenceObject(entry.FileName); } NtClose(processHandle); } // Use an alternative method if we don't have sufficient access. if (status2 == STATUS_ACCESS_DENIED && WindowsVersion >= WINDOWS_VISTA) { if (NT_SUCCESS(status2 = PhGetProcessImageFileNameByProcessId(UlongToHandle(pid), &fileName))) { entry.ProcessId = UlongToHandle(pid); entry.FileName = PhGetFileName(fileName); PhDereferenceObject(fileName); if (PhFindItemList(pids, UlongToHandle(pid)) != -1) entry.Type = NormalProcess; else entry.Type = HiddenProcess; if (!Callback(&entry, Context)) stop = TRUE; PhDereferenceObject(entry.FileName); } } if (status2 == STATUS_INVALID_CID || status2 == STATUS_INVALID_PARAMETER) status2 = STATUS_SUCCESS; if (!NT_SUCCESS(status2)) { entry.ProcessId = UlongToHandle(pid); entry.FileName = NULL; entry.Type = UnknownProcess; if (!Callback(&entry, Context)) stop = TRUE; } if (stop) break; } PhDereferenceObject(pids); return status; }
__callback PPH_STRING PhStdGetClientIdName( __in PCLIENT_ID ClientId ) { static PH_QUEUED_LOCK cachedProcessesLock = PH_QUEUED_LOCK_INIT; static PVOID processes = NULL; static ULONG lastProcessesTickCount = 0; PPH_STRING name; ULONG tickCount; PSYSTEM_PROCESS_INFORMATION processInfo; // Get a new process list only if 2 seconds have passed // since the last update. tickCount = GetTickCount(); if (tickCount - lastProcessesTickCount >= 2000) { PhAcquireQueuedLockExclusive(&cachedProcessesLock); // Re-check the tick count. if (tickCount - lastProcessesTickCount >= 2000) { if (processes) { PhFree(processes); processes = NULL; } if (!NT_SUCCESS(PhEnumProcesses(&processes))) { PhReleaseQueuedLockExclusive(&cachedProcessesLock); return PhCreateString(L"(Error querying processes)"); } lastProcessesTickCount = tickCount; } PhReleaseQueuedLockExclusive(&cachedProcessesLock); } // Get a lock on the process list and get a name for the client ID. PhAcquireQueuedLockShared(&cachedProcessesLock); if (!processes) { PhReleaseQueuedLockShared(&cachedProcessesLock); return NULL; } processInfo = PhFindProcessInformation(processes, ClientId->UniqueProcess); if (ClientId->UniqueThread) { if (processInfo) { name = PhFormatString( L"%.*s (%u): %u", processInfo->ImageName.Length / 2, processInfo->ImageName.Buffer, (ULONG)ClientId->UniqueProcess, (ULONG)ClientId->UniqueThread ); } else { name = PhFormatString(L"Non-existent process (%u): %u", (ULONG)ClientId->UniqueProcess, (ULONG)ClientId->UniqueThread); } } else { if (processInfo) { name = PhFormatString( L"%.*s (%u)", processInfo->ImageName.Length / 2, processInfo->ImageName.Buffer, (ULONG)ClientId->UniqueProcess ); } else { name = PhFormatString(L"Non-existent process (%u)", (ULONG)ClientId->UniqueProcess); } } PhReleaseQueuedLockShared(&cachedProcessesLock); return name; }
static BOOLEAN PhpRunTerminatorTest( _In_ HWND WindowHandle, _In_ INT Index ) { NTSTATUS status; PTEST_ITEM testItem; PPH_PROCESS_ITEM processItem; HWND lvHandle; PVOID processes; BOOLEAN success = FALSE; LARGE_INTEGER interval; processItem = (PPH_PROCESS_ITEM)GetProp(WindowHandle, L"ProcessItem"); lvHandle = GetDlgItem(WindowHandle, IDC_TERMINATOR_LIST); if (!PhGetListViewItemParam( lvHandle, Index, &testItem )) return FALSE; if (WSTR_EQUAL(testItem->Id, L"TT4")) { if (!PhShowConfirmMessage( WindowHandle, L"run", L"the TT4 test", L"The TT4 test may cause the system to crash.", TRUE )) return FALSE; } status = testItem->TestProc(processItem->ProcessId); interval.QuadPart = -1000 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); if (status == STATUS_NOT_SUPPORTED) { PPH_STRING concat; concat = PhConcatStrings2(L"(Not available) ", testItem->Description); PhSetListViewSubItem(lvHandle, Index, 1, concat->Buffer); PhDereferenceObject(concat); } if (!NT_SUCCESS(PhEnumProcesses(&processes))) return FALSE; // Check if the process exists. if (!PhFindProcessInformation(processes, processItem->ProcessId)) { PhSetListViewItemImageIndex(lvHandle, Index, TICK_INDEX); SetDlgItemText(WindowHandle, IDC_TERMINATOR_TEXT, L"The process was terminated."); success = TRUE; } else { PhSetListViewItemImageIndex(lvHandle, Index, CROSS_INDEX); } PhFree(processes); UpdateWindow(WindowHandle); return success; }