static NTSTATUS NTAPI TerminatorTP1a( _In_ HANDLE ProcessId ) { NTSTATUS status; HANDLE processHandle = NtCurrentProcess(); ULONG i; if (!NtGetNextProcess) return STATUS_NOT_SUPPORTED; if (!NT_SUCCESS(status = NtGetNextProcess( NtCurrentProcess(), ProcessQueryAccess | PROCESS_TERMINATE, 0, 0, &processHandle ))) return status; for (i = 0; i < 1000; i++) // make sure we don't go into an infinite loop or something { HANDLE newProcessHandle; PROCESS_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &basicInfo))) { if (basicInfo.UniqueProcessId == ProcessId) { PhTerminateProcess(processHandle, STATUS_SUCCESS); break; } } if (NT_SUCCESS(status = NtGetNextProcess( processHandle, ProcessQueryAccess | PROCESS_TERMINATE, 0, 0, &newProcessHandle ))) { NtClose(processHandle); processHandle = newProcessHandle; } else { NtClose(processHandle); break; } } return status; }
NTSTATUS PhGetProcessDefaultHeap( __in HANDLE ProcessHandle, __out PPVOID Heap ) { NTSTATUS status; PROCESS_BASIC_INFORMATION basicInfo; if (!NT_SUCCESS(status = PhGetProcessBasicInformation( ProcessHandle, &basicInfo ))) return status; return status = PhReadVirtualMemory( ProcessHandle, PTR_ADD_OFFSET(basicInfo.PebBaseAddress, FIELD_OFFSET(PEB, ProcessHeap)), Heap, sizeof(PVOID), NULL ); }
/** * Determines the OS compatibility context of a process. * * \param ProcessHandle A handle to a process. * \param Guid A variable which receives a GUID identifying an * operating system version. */ NTSTATUS PhGetProcessSwitchContext( __in HANDLE ProcessHandle, __out PGUID Guid ) { NTSTATUS status; PROCESS_BASIC_INFORMATION basicInfo; #ifdef _M_X64 PVOID peb32; ULONG contextData32; #endif PVOID contextData; // Reverse-engineered from WdcGetProcessSwitchContext (wdc.dll). #ifdef _M_X64 if (NT_SUCCESS(PhGetProcessPeb32(ProcessHandle, &peb32)) && peb32) { if (!NT_SUCCESS(status = PhReadVirtualMemory( ProcessHandle, PTR_ADD_OFFSET(peb32, FIELD_OFFSET(PEB32, pContextData)), &contextData32, sizeof(ULONG), NULL ))) return status; contextData = UlongToPtr(contextData32); } else { #endif if (!NT_SUCCESS(status = PhGetProcessBasicInformation(ProcessHandle, &basicInfo))) return status; if (!NT_SUCCESS(status = PhReadVirtualMemory( ProcessHandle, PTR_ADD_OFFSET(basicInfo.PebBaseAddress, FIELD_OFFSET(PEB, pContextData)), &contextData, sizeof(PVOID), NULL ))) return status; #ifdef _M_X64 } #endif if (!contextData) return STATUS_UNSUCCESSFUL; // no compatibility context data if (!NT_SUCCESS(status = PhReadVirtualMemory( ProcessHandle, PTR_ADD_OFFSET(contextData, 32), // Magic value from WdcGetProcessSwitchContext Guid, sizeof(GUID), NULL ))) return status; return STATUS_SUCCESS; }
/** * Determines the type of a process based on its image file name. * * \param ProcessHandle A handle to a process. * \param KnownProcessType A variable which receives the process * type. */ NTSTATUS PhGetProcessKnownType( __in HANDLE ProcessHandle, __out PH_KNOWN_PROCESS_TYPE *KnownProcessType ) { NTSTATUS status; PH_KNOWN_PROCESS_TYPE knownProcessType; PROCESS_BASIC_INFORMATION basicInfo; PH_STRINGREF systemRootPrefix; PPH_STRING fileName; PPH_STRING newFileName; PH_STRINGREF name; #ifdef _M_X64 BOOLEAN isWow64 = FALSE; #endif if (!NT_SUCCESS(status = PhGetProcessBasicInformation( ProcessHandle, &basicInfo ))) return status; if (basicInfo.UniqueProcessId == SYSTEM_PROCESS_ID) { *KnownProcessType = SystemProcessType; return STATUS_SUCCESS; } PhGetSystemRoot(&systemRootPrefix); if (!NT_SUCCESS(status = PhGetProcessImageFileName( ProcessHandle, &fileName ))) { return status; } newFileName = PhGetFileName(fileName); PhDereferenceObject(fileName); name = newFileName->sr; knownProcessType = UnknownProcessType; if (PhStartsWithStringRef(&name, &systemRootPrefix, TRUE)) { // Skip the system root, and we now have three cases: // 1. \\xyz.exe - Windows executable. // 2. \\System32\\xyz.exe - system32 executable. // 3. \\SysWow64\\xyz.exe - system32 executable + WOW64. name.Buffer += systemRootPrefix.Length / 2; name.Length -= systemRootPrefix.Length; if (PhEqualStringRef2(&name, L"\\explorer.exe", TRUE)) { knownProcessType = ExplorerProcessType; } else if ( PhStartsWithStringRef2(&name, L"\\System32", TRUE) #ifdef _M_X64 || (PhStartsWithStringRef2(&name, L"\\SysWow64", TRUE) && (isWow64 = TRUE, TRUE)) // ugly but necessary #endif ) { // SysTem32 and SysWow64 are both 8 characters long. name.Buffer += 9; name.Length -= 9 * 2; if (FALSE) ; // Dummy else if (PhEqualStringRef2(&name, L"\\smss.exe", TRUE)) knownProcessType = SessionManagerProcessType; else if (PhEqualStringRef2(&name, L"\\csrss.exe", TRUE)) knownProcessType = WindowsSubsystemProcessType; else if (PhEqualStringRef2(&name, L"\\wininit.exe", TRUE)) knownProcessType = WindowsStartupProcessType; else if (PhEqualStringRef2(&name, L"\\services.exe", TRUE)) knownProcessType = ServiceControlManagerProcessType; else if (PhEqualStringRef2(&name, L"\\lsass.exe", TRUE)) knownProcessType = LocalSecurityAuthorityProcessType; else if (PhEqualStringRef2(&name, L"\\lsm.exe", TRUE)) knownProcessType = LocalSessionManagerProcessType; else if (PhEqualStringRef2(&name, L"\\winlogon.exe", TRUE)) knownProcessType = WindowsLogonProcessType; else if (PhEqualStringRef2(&name, L"\\svchost.exe", TRUE)) knownProcessType = ServiceHostProcessType; else if (PhEqualStringRef2(&name, L"\\rundll32.exe", TRUE)) knownProcessType = RunDllAsAppProcessType; else if (PhEqualStringRef2(&name, L"\\dllhost.exe", TRUE)) knownProcessType = ComSurrogateProcessType; else if (PhEqualStringRef2(&name, L"\\taskeng.exe", TRUE)) knownProcessType = TaskHostProcessType; else if (PhEqualStringRef2(&name, L"\\taskhost.exe", TRUE)) knownProcessType = TaskHostProcessType; } } PhDereferenceObject(newFileName); #ifdef _M_X64 if (isWow64) knownProcessType |= KnownProcessWow64; #endif *KnownProcessType = knownProcessType; return status; }
static PPH_PROCESS_ITEM PhpCreateProcessItemForHiddenProcess( _In_ PPH_HIDDEN_PROCESS_ENTRY Entry ) { NTSTATUS status; PPH_PROCESS_ITEM processItem; PPH_PROCESS_ITEM idleProcessItem; HANDLE processHandle; PROCESS_BASIC_INFORMATION basicInfo; KERNEL_USER_TIMES times; PROCESS_PRIORITY_CLASS priorityClass; ULONG handleCount; HANDLE processHandle2; if (Entry->Type == NormalProcess) { processItem = PhReferenceProcessItem(Entry->ProcessId); if (processItem) return processItem; } processItem = PhCreateProcessItem(Entry->ProcessId); // Mark the process as terminated if necessary. if (Entry->Type == TerminatedProcess) processItem->State |= PH_PROCESS_ITEM_REMOVED; // We need a process record. Just use the record of System Idle Process. if (idleProcessItem = PhReferenceProcessItem(SYSTEM_IDLE_PROCESS_ID)) { processItem->Record = idleProcessItem->Record; PhReferenceProcessRecord(processItem->Record); } else { PhDereferenceObject(processItem); return NULL; } // Set up the file name and process name. PhSwapReference(&processItem->FileName, Entry->FileName); if (processItem->FileName) { processItem->ProcessName = PhGetBaseName(processItem->FileName); } else { processItem->ProcessName = PhCreateString(L"Unknown"); } if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } if (NT_SUCCESS(status)) { // Basic information and not-so-dynamic information processItem->QueryHandle = processHandle; if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &basicInfo))) { processItem->ParentProcessId = basicInfo.InheritedFromUniqueProcessId; processItem->BasePriority = basicInfo.BasePriority; } PhGetProcessSessionId(processHandle, &processItem->SessionId); PhPrintUInt32(processItem->ParentProcessIdString, HandleToUlong(processItem->ParentProcessId)); PhPrintUInt32(processItem->SessionIdString, processItem->SessionId); if (NT_SUCCESS(PhGetProcessTimes(processHandle, ×))) { processItem->CreateTime = times.CreateTime; processItem->KernelTime = times.KernelTime; processItem->UserTime = times.UserTime; } // TODO: Token information? if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS), NULL ))) { processItem->PriorityClass = priorityClass.PriorityClass; } if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessHandleCount, &handleCount, sizeof(ULONG), NULL ))) { processItem->NumberOfHandles = handleCount; } } // Stage 1 // Some copy and paste magic here... if (processItem->FileName) { // Small icon, large icon. ExtractIconEx( processItem->FileName->Buffer, 0, &processItem->LargeIcon, &processItem->SmallIcon, 1 ); // Version info. PhInitializeImageVersionInfo(&processItem->VersionInfo, processItem->FileName->Buffer); } // Use the default EXE icon if we didn't get the file's icon. { if (!processItem->SmallIcon || !processItem->LargeIcon) { if (processItem->SmallIcon) { DestroyIcon(processItem->SmallIcon); processItem->SmallIcon = NULL; } else if (processItem->LargeIcon) { DestroyIcon(processItem->LargeIcon); processItem->LargeIcon = NULL; } PhGetStockApplicationIcon(&processItem->SmallIcon, &processItem->LargeIcon); processItem->SmallIcon = DuplicateIcon(NULL, processItem->SmallIcon); processItem->LargeIcon = DuplicateIcon(NULL, processItem->LargeIcon); } } // POSIX, command line status = PhOpenProcess( &processHandle2, ProcessQueryAccess | PROCESS_VM_READ, Entry->ProcessId ); if (NT_SUCCESS(status)) { BOOLEAN isPosix = FALSE; PPH_STRING commandLine; ULONG i; status = PhGetProcessIsPosix(processHandle2, &isPosix); processItem->IsPosix = isPosix; if (!NT_SUCCESS(status) || !isPosix) { status = PhGetProcessCommandLine(processHandle2, &commandLine); if (NT_SUCCESS(status)) { // Some command lines (e.g. from taskeng.exe) have nulls in them. // Since Windows can't display them, we'll replace them with // spaces. for (i = 0; i < (ULONG)commandLine->Length / 2; i++) { if (commandLine->Buffer[i] == 0) commandLine->Buffer[i] = ' '; } } } else { // Get the POSIX command line. status = PhGetProcessPosixCommandLine(processHandle2, &commandLine); } if (NT_SUCCESS(status)) { processItem->CommandLine = commandLine; } NtClose(processHandle2); } // TODO: Other stage 1 tasks. PhSetEvent(&processItem->Stage1Event); return processItem; }
NTSTATUS PhpGetBestObjectName( __in HANDLE ProcessHandle, __in HANDLE Handle, __in PPH_STRING ObjectName, __in PPH_STRING TypeName, __out PPH_STRING *BestObjectName ) { NTSTATUS status; PPH_STRING bestObjectName = NULL; PPH_GET_CLIENT_ID_NAME handleGetClientIdName; if (PhEqualString2(TypeName, L"EtwRegistration", TRUE)) { if (KphIsConnected()) { ETWREG_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectEtwRegBasicInformation, &basicInfo, sizeof(ETWREG_BASIC_INFORMATION), NULL ); if (NT_SUCCESS(status)) { static PH_STRINGREF publishersKeyName = PH_STRINGREF_INIT(L"Software\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Publishers\\"); PPH_STRING guidString; PPH_STRING keyName; HANDLE keyHandle; PPH_STRING publisherName = NULL; guidString = PhFormatGuid(&basicInfo.Guid); // We should perform a lookup on the GUID to get the publisher name. keyName = PhConcatStringRef2(&publishersKeyName, &guidString->sr); if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyName->sr, 0 ))) { publisherName = PhQueryRegistryString(keyHandle, NULL); if (publisherName && publisherName->Length == 0) { PhDereferenceObject(publisherName); publisherName = NULL; } NtClose(keyHandle); } PhDereferenceObject(keyName); if (publisherName) { bestObjectName = publisherName; PhDereferenceObject(guidString); } else { bestObjectName = guidString; } } } } else if (PhEqualString2(TypeName, L"File", TRUE)) { // Convert the file name to a DOS file name. bestObjectName = PhResolveDevicePrefix(ObjectName); if (!bestObjectName) { bestObjectName = ObjectName; PhReferenceObject(ObjectName); } } else if (PhEqualString2(TypeName, L"Key", TRUE)) { bestObjectName = PhFormatNativeKeyName(ObjectName); } else if (PhEqualString2(TypeName, L"Process", TRUE)) { CLIENT_ID clientId; clientId.UniqueThread = NULL; if (KphIsConnected()) { PROCESS_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectProcessBasicInformation, &basicInfo, sizeof(PROCESS_BASIC_INFORMATION), NULL ); if (!NT_SUCCESS(status)) goto CleanupExit; clientId.UniqueProcess = basicInfo.UniqueProcessId; } else { HANDLE dupHandle; PROCESS_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ProcessQueryAccess, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetProcessBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (!NT_SUCCESS(status)) goto CleanupExit; clientId.UniqueProcess = basicInfo.UniqueProcessId; } handleGetClientIdName = PhHandleGetClientIdName; if (handleGetClientIdName) bestObjectName = handleGetClientIdName(&clientId); } else if (PhEqualString2(TypeName, L"Thread", TRUE)) { CLIENT_ID clientId; if (KphIsConnected()) { THREAD_BASIC_INFORMATION basicInfo; status = KphQueryInformationObject( ProcessHandle, Handle, KphObjectThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL ); if (!NT_SUCCESS(status)) goto CleanupExit; clientId = basicInfo.ClientId; } else { HANDLE dupHandle; THREAD_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ThreadQueryAccess, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetThreadBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (!NT_SUCCESS(status)) goto CleanupExit; clientId = basicInfo.ClientId; } handleGetClientIdName = PhHandleGetClientIdName; if (handleGetClientIdName) bestObjectName = handleGetClientIdName(&clientId); } else if (PhEqualString2(TypeName, L"TmEn", TRUE)) { HANDLE dupHandle; ENLISTMENT_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, ENLISTMENT_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetEnlistmentBasicInformation(dupHandle, &basicInfo); NtClose(dupHandle); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.EnlistmentId); } } else if (PhEqualString2(TypeName, L"TmRm", TRUE)) { HANDLE dupHandle; GUID guid; PPH_STRING description; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, RESOURCEMANAGER_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetResourceManagerBasicInformation( dupHandle, &guid, &description ); NtClose(dupHandle); if (NT_SUCCESS(status)) { if (!PhIsNullOrEmptyString(description)) { bestObjectName = description; } else { bestObjectName = PhFormatGuid(&guid); if (description) PhDereferenceObject(description); } } } else if (PhEqualString2(TypeName, L"TmTm", TRUE)) { HANDLE dupHandle; PPH_STRING logFileName = NULL; TRANSACTIONMANAGER_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TRANSACTIONMANAGER_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTransactionManagerLogFileName( dupHandle, &logFileName ); if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(logFileName)) { bestObjectName = PhGetFileName(logFileName); PhDereferenceObject(logFileName); } else { if (logFileName) PhDereferenceObject(logFileName); status = PhGetTransactionManagerBasicInformation( dupHandle, &basicInfo ); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.TmIdentity); } } NtClose(dupHandle); } else if (PhEqualString2(TypeName, L"TmTx", TRUE)) { HANDLE dupHandle; PPH_STRING description = NULL; TRANSACTION_BASIC_INFORMATION basicInfo; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TRANSACTION_QUERY_INFORMATION, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTransactionPropertiesInformation( dupHandle, NULL, NULL, &description ); if (NT_SUCCESS(status) && !PhIsNullOrEmptyString(description)) { bestObjectName = description; } else { if (description) PhDereferenceObject(description); status = PhGetTransactionBasicInformation( dupHandle, &basicInfo ); if (NT_SUCCESS(status)) { bestObjectName = PhFormatGuid(&basicInfo.TransactionId); } } NtClose(dupHandle); } else if (PhEqualString2(TypeName, L"Token", TRUE)) { HANDLE dupHandle; PTOKEN_USER tokenUser = NULL; TOKEN_STATISTICS statistics = { 0 }; status = NtDuplicateObject( ProcessHandle, Handle, NtCurrentProcess(), &dupHandle, TOKEN_QUERY, 0, 0 ); if (!NT_SUCCESS(status)) goto CleanupExit; status = PhGetTokenUser(dupHandle, &tokenUser); PhGetTokenStatistics(dupHandle, &statistics); if (NT_SUCCESS(status)) { PPH_STRING fullName; fullName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); if (fullName) { PH_FORMAT format[3]; PhInitFormatSR(&format[0], fullName->sr); PhInitFormatS(&format[1], L": 0x"); PhInitFormatX(&format[2], statistics.AuthenticationId.LowPart); bestObjectName = PhFormat(format, 3, fullName->Length + 8 + 16); PhDereferenceObject(fullName); } PhFree(tokenUser); } NtClose(dupHandle); } CleanupExit: if (!bestObjectName) { bestObjectName = ObjectName; PhReferenceObject(ObjectName); } *BestObjectName = bestObjectName; return STATUS_SUCCESS; }
VOID PhShowHandleObjectProperties1( _In_ HWND hWnd, _In_ PPH_HANDLE_ITEM_INFO Info ) { if (PhIsNullOrEmptyString(Info->TypeName)) return; if (PhEqualString2(Info->TypeName, L"File", TRUE) || PhEqualString2(Info->TypeName, L"DLL", TRUE) || PhEqualString2(Info->TypeName, L"Mapped file", TRUE) || PhEqualString2(Info->TypeName, L"Mapped image", TRUE)) { if (Info->BestObjectName) { PhShellExecuteUserString( PhMainWndHandle, L"FileBrowseExecutable", Info->BestObjectName->Buffer, FALSE, L"Make sure the Explorer executable file is present." ); } else PhShowError(hWnd, L"Unable to open file location because the object is unnamed."); } else if (PhEqualString2(Info->TypeName, L"Key", TRUE)) { if (Info->BestObjectName) PhShellOpenKey2(hWnd, Info->BestObjectName); else PhShowError(hWnd, L"Unable to open key because the object is unnamed."); } else if (PhEqualString2(Info->TypeName, L"Process", TRUE)) { HANDLE processHandle; HANDLE processId; PPH_PROCESS_ITEM targetProcessItem; processId = NULL; if (KphIsConnected()) { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId ))) { PROCESS_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(KphQueryInformationObject( processHandle, Info->Handle, KphObjectProcessBasicInformation, &basicInfo, sizeof(PROCESS_BASIC_INFORMATION), NULL ))) { processId = basicInfo.UniqueProcessId; } NtClose(processHandle); } } else { HANDLE handle; PROCESS_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem( &handle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId, Info->Handle ))) { if (NT_SUCCESS(PhGetProcessBasicInformation(handle, &basicInfo))) processId = basicInfo.UniqueProcessId; NtClose(handle); } } if (processId) { targetProcessItem = PhReferenceProcessItem(processId); if (targetProcessItem) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, targetProcessItem); PhDereferenceObject(targetProcessItem); } else { PhShowError(hWnd, L"The process does not exist."); } } } else if (PhEqualString2(Info->TypeName, L"Section", TRUE)) { NTSTATUS status; HANDLE handle = NULL; BOOLEAN readOnly = FALSE; if (!NT_SUCCESS(status = PhpDuplicateHandleFromProcessItem( &handle, SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE, Info->ProcessId, Info->Handle ))) { status = PhpDuplicateHandleFromProcessItem( &handle, SECTION_QUERY | SECTION_MAP_READ, Info->ProcessId, Info->Handle ); readOnly = TRUE; } if (handle) { PPH_STRING sectionName = NULL; SECTION_BASIC_INFORMATION basicInfo; SIZE_T viewSize = PH_MAX_SECTION_EDIT_SIZE; PVOID viewBase = NULL; BOOLEAN tooBig = FALSE; PhGetHandleInformation(NtCurrentProcess(), handle, ULONG_MAX, NULL, NULL, NULL, §ionName); if (NT_SUCCESS(status = PhGetSectionBasicInformation(handle, &basicInfo))) { if (basicInfo.MaximumSize.QuadPart <= PH_MAX_SECTION_EDIT_SIZE) viewSize = (SIZE_T)basicInfo.MaximumSize.QuadPart; else tooBig = TRUE; status = NtMapViewOfSection( handle, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, readOnly ? PAGE_READONLY : PAGE_READWRITE ); if (status == STATUS_SECTION_PROTECTION && !readOnly) { status = NtMapViewOfSection( handle, NtCurrentProcess(), &viewBase, 0, 0, NULL, &viewSize, ViewShare, 0, PAGE_READONLY ); } if (NT_SUCCESS(status)) { PPH_SHOW_MEMORY_EDITOR showMemoryEditor = PhAllocate(sizeof(PH_SHOW_MEMORY_EDITOR)); if (tooBig) PhShowWarning(hWnd, L"The section size is greater than 32 MB. Only the first 32 MB will be available for editing."); memset(showMemoryEditor, 0, sizeof(PH_SHOW_MEMORY_EDITOR)); showMemoryEditor->ProcessId = NtCurrentProcessId(); showMemoryEditor->BaseAddress = viewBase; showMemoryEditor->RegionSize = viewSize; showMemoryEditor->SelectOffset = ULONG_MAX; showMemoryEditor->SelectLength = 0; showMemoryEditor->Title = sectionName ? PhConcatStrings2(L"Section - ", sectionName->Buffer) : PhCreateString(L"Section"); showMemoryEditor->Flags = PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION; ProcessHacker_ShowMemoryEditor(PhMainWndHandle, showMemoryEditor); } else { PhShowStatus(hWnd, L"Unable to map a view of the section.", status, 0); } } PhClearReference(§ionName); NtClose(handle); } if (!NT_SUCCESS(status)) { PhShowStatus(hWnd, L"Unable to query the section.", status, 0); } } else if (PhEqualString2(Info->TypeName, L"Thread", TRUE)) { HANDLE processHandle; CLIENT_ID clientId; PPH_PROCESS_ITEM targetProcessItem; PPH_PROCESS_PROPCONTEXT propContext; clientId.UniqueProcess = NULL; clientId.UniqueThread = NULL; if (KphIsConnected()) { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_LIMITED_INFORMATION, Info->ProcessId ))) { THREAD_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(KphQueryInformationObject( processHandle, Info->Handle, KphObjectThreadBasicInformation, &basicInfo, sizeof(THREAD_BASIC_INFORMATION), NULL ))) { clientId = basicInfo.ClientId; } NtClose(processHandle); } } else { HANDLE handle; THREAD_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(PhpDuplicateHandleFromProcessItem( &handle, THREAD_QUERY_LIMITED_INFORMATION, Info->ProcessId, Info->Handle ))) { if (NT_SUCCESS(PhGetThreadBasicInformation(handle, &basicInfo))) clientId = basicInfo.ClientId; NtClose(handle); } } if (clientId.UniqueProcess) { targetProcessItem = PhReferenceProcessItem(clientId.UniqueProcess); if (targetProcessItem) { propContext = PhCreateProcessPropContext(NULL, targetProcessItem); PhDereferenceObject(targetProcessItem); PhSetSelectThreadIdProcessPropContext(propContext, clientId.UniqueThread); ProcessHacker_Invoke(PhMainWndHandle, PhpShowProcessPropContext, propContext); } else { PhShowError(hWnd, L"The process does not exist."); } } } }