VOID PhShowHiddenProcessesDialog( VOID ) { if (!KphIsConnected()) { PhShowWarning( PhMainWndHandle, L"Hidden process detection cannot function properly without KProcessHacker. " L"Make sure Process Hacker is running with administrative privileges." ); } if (!PhHiddenProcessesWindowHandle) { PhHiddenProcessesWindowHandle = CreateDialog( PhInstanceHandle, MAKEINTRESOURCE(IDD_HIDDENPROCESSES), PhMainWndHandle, PhpHiddenProcessesDlgProc ); } if (!IsWindowVisible(PhHiddenProcessesWindowHandle)) ShowWindow(PhHiddenProcessesWindowHandle, SW_SHOW); else SetForegroundWindow(PhHiddenProcessesWindowHandle); }
INT WINAPI wWinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR lpCmdLine, _In_ INT nCmdShow ) { LONG result; #ifdef DEBUG PHP_BASE_THREAD_DBG dbg; #endif CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); #ifndef DEBUG SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); #endif PhInstanceHandle = (HINSTANCE)NtCurrentPeb()->ImageBaseAddress; if (!NT_SUCCESS(PhInitializePhLib())) return 1; if (!PhInitializeAppSystem()) return 1; PhInitializeCommonControls(); if (PhCurrentTokenQueryHandle) { PTOKEN_USER tokenUser; if (NT_SUCCESS(PhGetTokenUser(PhCurrentTokenQueryHandle, &tokenUser))) { PhCurrentUserName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL); PhFree(tokenUser); } } PhLocalSystemName = PhGetSidFullName(&PhSeLocalSystemSid, TRUE, NULL); // There has been a report of the above call failing. if (!PhLocalSystemName) PhLocalSystemName = PhCreateString(L"NT AUTHORITY\\SYSTEM"); PhApplicationFileName = PhGetApplicationFileName(); PhApplicationDirectory = PhGetApplicationDirectory(); // Just in case if (!PhApplicationFileName) PhApplicationFileName = PhCreateString(L"ProcessHacker.exe"); if (!PhApplicationDirectory) PhApplicationDirectory = PhReferenceEmptyString(); PhpProcessStartupParameters(); PhSettingsInitialization(); PhpEnablePrivileges(); if (PhStartupParameters.RunAsServiceMode) { RtlExitUserProcess(PhRunAsServiceStart(PhStartupParameters.RunAsServiceMode)); } PhpInitializeSettings(); // Activate a previous instance if required. if (PhGetIntegerSetting(L"AllowOnlyOneInstance") && !PhStartupParameters.NewInstance && !PhStartupParameters.ShowOptions && !PhStartupParameters.CommandMode && !PhStartupParameters.PhSvc) { PhActivatePreviousInstance(); } if (PhGetIntegerSetting(L"EnableKph") && !PhStartupParameters.NoKph && !PhIsExecutingInWow64()) PhInitializeKph(); if (PhStartupParameters.CommandMode && PhStartupParameters.CommandType && PhStartupParameters.CommandAction) { NTSTATUS status; status = PhCommandModeStart(); if (!NT_SUCCESS(status) && !PhStartupParameters.Silent) { PhShowStatus(NULL, L"Unable to execute the command", status, 0); } RtlExitUserProcess(status); } #ifdef DEBUG dbg.ClientId = NtCurrentTeb()->ClientId; dbg.StartAddress = wWinMain; dbg.Parameter = NULL; InsertTailList(&PhDbgThreadListHead, &dbg.ListEntry); TlsSetValue(PhDbgThreadDbgTlsIndex, &dbg); #endif PhInitializeAutoPool(&BaseAutoPool); PhEmInitialization(); PhGuiSupportInitialization(); PhTreeNewInitialization(); PhGraphControlInitialization(); PhHexEditInitialization(); PhColorBoxInitialization(); PhSmallIconSize.X = GetSystemMetrics(SM_CXSMICON); PhSmallIconSize.Y = GetSystemMetrics(SM_CYSMICON); PhLargeIconSize.X = GetSystemMetrics(SM_CXICON); PhLargeIconSize.Y = GetSystemMetrics(SM_CYICON); if (PhStartupParameters.ShowOptions) { // Elevated options dialog for changing the value of Replace Task Manager with Process Hacker. PhShowOptionsDialog(PhStartupParameters.WindowHandle); RtlExitUserProcess(STATUS_SUCCESS); } #ifndef DEBUG if (PhIsExecutingInWow64() && !PhStartupParameters.PhSvc) { PhShowWarning( NULL, L"You are attempting to run the 32-bit version of Process Hacker on 64-bit Windows. " L"Most features will not work correctly.\n\n" L"Please run the 64-bit version of Process Hacker instead." ); } #endif PhPluginsEnabled = PhGetIntegerSetting(L"EnablePlugins") && !PhStartupParameters.NoPlugins; if (PhPluginsEnabled) { PhPluginsInitialization(); PhLoadPlugins(); } if (PhStartupParameters.PhSvc) { MSG message; // Turn the feedback cursor off. PostMessage(NULL, WM_NULL, 0, 0); GetMessage(&message, NULL, 0, 0); RtlExitUserProcess(PhSvcMain(NULL, NULL, NULL)); } // Create a mutant for the installer. { HANDLE mutantHandle; OBJECT_ATTRIBUTES oa; UNICODE_STRING mutantName; RtlInitUnicodeString(&mutantName, L"\\BaseNamedObjects\\ProcessHacker2Mutant"); InitializeObjectAttributes( &oa, &mutantName, 0, NULL, NULL ); NtCreateMutant(&mutantHandle, MUTANT_ALL_ACCESS, &oa, FALSE); } // Set priority. { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; if (PhStartupParameters.PriorityClass != 0) priorityClass.PriorityClass = (UCHAR)PhStartupParameters.PriorityClass; NtSetInformationProcess(NtCurrentProcess(), ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); } if (!PhMainWndInitialization(nCmdShow)) { PhShowError(NULL, L"Unable to initialize the main window."); return 1; } PhDrainAutoPool(&BaseAutoPool); result = PhMainMessageLoop(); RtlExitUserProcess(result); }
static INT_PTR CALLBACK PhpFindObjectsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhFindObjectsListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_FILTER), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_REGEX), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&WindowLayoutManager, lvHandle, NULL, PH_ANCHOR_ALL); MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 150; MinimumSize.bottom = 100; MapDialogRect(hwndDlg, &MinimumSize); PhRegisterDialog(hwndDlg); PhLoadWindowPlacementFromSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSetListViewStyle(lvHandle, TRUE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Process"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 100, L"Type"); PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 200, L"Name"); PhAddListViewColumn(lvHandle, 3, 3, 3, LVCFMT_LEFT, 80, L"Handle"); PhSetExtendedListView(lvHandle); ExtendedListView_SetSortFast(lvHandle, TRUE); ExtendedListView_SetCompareFunction(lvHandle, 0, PhpObjectProcessCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 1, PhpObjectTypeCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 2, PhpObjectNameCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 3, PhpObjectHandleCompareFunction); PhLoadListViewColumnsFromSetting(L"FindObjListViewColumns", lvHandle); Button_SetCheck(GetDlgItem(hwndDlg, IDC_REGEX), PhGetIntegerSetting(L"FindObjRegex") ? BST_CHECKED : BST_UNCHECKED); } break; case WM_DESTROY: { PhSetIntegerSetting(L"FindObjRegex", Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED); PhSaveWindowPlacementToSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"FindObjListViewColumns", PhFindObjectsListViewHandle); } break; case WM_SHOWWINDOW: { SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_FILTER), TRUE); Edit_SetSel(GetDlgItem(hwndDlg, IDC_FILTER), 0, -1); } break; case WM_CLOSE: { ShowWindow(hwndDlg, SW_HIDE); // IMPORTANT // Set the result to 0 so the default dialog message // handler doesn't invoke IDCANCEL, which will send // WM_CLOSE, creating an infinite loop. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0); } return TRUE; case WM_SETCURSOR: { if (SearchThreadHandle) { SetCursor(LoadCursor(NULL, IDC_WAIT)); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, TRUE); return TRUE; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDOK: { // Don't continue if the user requested cancellation. if (SearchStop) break; if (!SearchThreadHandle) { ULONG i; PhMoveReference(&SearchString, PhGetWindowText(GetDlgItem(hwndDlg, IDC_FILTER))); if (SearchRegexCompiledExpression) { pcre2_code_free(SearchRegexCompiledExpression); SearchRegexCompiledExpression = NULL; } if (SearchRegexMatchData) { pcre2_match_data_free(SearchRegexMatchData); SearchRegexMatchData = NULL; } if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_REGEX)) == BST_CHECKED) { int errorCode; PCRE2_SIZE errorOffset; SearchRegexCompiledExpression = pcre2_compile( SearchString->Buffer, SearchString->Length / sizeof(WCHAR), PCRE2_CASELESS | PCRE2_DOTALL, &errorCode, &errorOffset, NULL ); if (!SearchRegexCompiledExpression) { PhShowError(hwndDlg, L"Unable to compile the regular expression: \"%s\" at position %zu.", PhGetStringOrDefault(PH_AUTO(PhPcre2GetErrorMessage(errorCode)), L"Unknown error"), errorOffset ); break; } SearchRegexMatchData = pcre2_match_data_create_from_pattern(SearchRegexCompiledExpression, NULL); } // Clean up previous results. ListView_DeleteAllItems(PhFindObjectsListViewHandle); if (SearchResults) { for (i = 0; i < SearchResults->Count; i++) { PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i]; PhDereferenceObject(searchResult->TypeName); PhDereferenceObject(searchResult->Name); if (searchResult->ProcessName) PhDereferenceObject(searchResult->ProcessName); PhFree(searchResult); } PhDereferenceObject(SearchResults); } // Start the search. SearchResults = PhCreateList(128); SearchResultsAddIndex = 0; SearchThreadHandle = PhCreateThread(0, PhpFindObjectsThreadStart, NULL); if (!SearchThreadHandle) { PhClearReference(&SearchResults); break; } SetDlgItemText(hwndDlg, IDOK, L"Cancel"); SetCursor(LoadCursor(NULL, IDC_WAIT)); } else { SearchStop = TRUE; EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); } } break; case IDCANCEL: { SendMessage(hwndDlg, WM_CLOSE, 0, 0); } break; case ID_OBJECT_CLOSE: { PPHP_OBJECT_SEARCH_RESULT *results; ULONG numberOfResults; ULONG i; PhGetSelectedListViewItemParams( PhFindObjectsListViewHandle, &results, &numberOfResults ); if (numberOfResults != 0 && PhShowConfirmMessage( hwndDlg, L"close", numberOfResults == 1 ? L"the selected handle" : L"the selected handles", L"Closing handles may cause system instability and data corruption.", FALSE )) { for (i = 0; i < numberOfResults; i++) { NTSTATUS status; HANDLE processHandle; if (results[i]->ResultType != HandleSearchResult) continue; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, results[i]->ProcessId ))) { if (NT_SUCCESS(status = PhDuplicateObject( processHandle, results[i]->Handle, NULL, NULL, 0, 0, DUPLICATE_CLOSE_SOURCE ))) { PhRemoveListViewItem(PhFindObjectsListViewHandle, PhFindListViewItemByParam(PhFindObjectsListViewHandle, 0, results[i])); } NtClose(processHandle); } if (!NT_SUCCESS(status)) { if (!PhShowContinueStatus(hwndDlg, PhaFormatString(L"Unable to close \"%s\"", results[i]->Name->Buffer)->Buffer, status, 0 )) break; } } } PhFree(results); } break; case ID_HANDLE_OBJECTPROPERTIES1: case ID_HANDLE_OBJECTPROPERTIES2: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PH_HANDLE_ITEM_INFO info; info.ProcessId = result->ProcessId; info.Handle = result->Handle; info.TypeName = result->TypeName; info.BestObjectName = result->Name; if (LOWORD(wParam) == ID_HANDLE_OBJECTPROPERTIES1) PhShowHandleObjectProperties1(hwndDlg, &info); else PhShowHandleObjectProperties2(hwndDlg, &info); } } break; case ID_OBJECT_GOTOOWNINGPROCESS: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PPH_PROCESS_NODE processNode; if (processNode = PhFindProcessNode(result->ProcessId)) { ProcessHacker_SelectTabPage(PhMainWndHandle, 0); ProcessHacker_SelectProcessNode(PhMainWndHandle, processNode); ProcessHacker_ToggleVisible(PhMainWndHandle, TRUE); } } } break; case ID_OBJECT_PROPERTIES: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { if (result->ResultType == HandleSearchResult) { PPH_HANDLE_ITEM handleItem; handleItem = PhCreateHandleItem(&result->Info); handleItem->BestObjectName = handleItem->ObjectName = result->Name; PhReferenceObjectEx(result->Name, 2); handleItem->TypeName = result->TypeName; PhReferenceObject(result->TypeName); PhShowHandleProperties( hwndDlg, result->ProcessId, handleItem ); PhDereferenceObject(handleItem); } else { // DLL or Mapped File. Just show file properties. PhShellProperties(hwndDlg, result->Name->Buffer); } } } break; case ID_OBJECT_COPY: { PhCopyListView(PhFindObjectsListViewHandle); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case NM_DBLCLK: { if (header->hwndFrom == PhFindObjectsListViewHandle) { SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_PROPERTIES, 0); } } break; case LVN_KEYDOWN: { if (header->hwndFrom == PhFindObjectsListViewHandle) { LPNMLVKEYDOWN keyDown = (LPNMLVKEYDOWN)header; switch (keyDown->wVKey) { case 'C': if (GetKeyState(VK_CONTROL) < 0) SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_COPY, 0); break; case 'A': if (GetKeyState(VK_CONTROL) < 0) PhSetStateAllListViewItems(PhFindObjectsListViewHandle, LVIS_SELECTED, LVIS_SELECTED); break; case VK_DELETE: SendMessage(hwndDlg, WM_COMMAND, ID_OBJECT_CLOSE, 0); break; } } } break; } } break; case WM_CONTEXTMENU: { if ((HWND)wParam == PhFindObjectsListViewHandle) { POINT point; PPHP_OBJECT_SEARCH_RESULT *results; ULONG numberOfResults; point.x = (SHORT)LOWORD(lParam); point.y = (SHORT)HIWORD(lParam); if (point.x == -1 && point.y == -1) PhGetListViewContextMenuPoint((HWND)wParam, &point); PhGetSelectedListViewItemParams(PhFindObjectsListViewHandle, &results, &numberOfResults); if (numberOfResults != 0) { PPH_EMENU menu; menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PhInstanceHandle, MAKEINTRESOURCE(IDR_FINDOBJ), 0); PhSetFlagsEMenuItem(menu, ID_OBJECT_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT); PhpInitializeFindObjMenu(menu, results, numberOfResults); PhShowEMenu( menu, hwndDlg, PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, point.x, point.y ); PhDestroyEMenu(menu); } PhFree(results); } } break; case WM_SIZE: { PhLayoutManagerLayout(&WindowLayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_PH_SEARCH_UPDATE: { HWND lvHandle; ULONG i; lvHandle = GetDlgItem(hwndDlg, IDC_RESULTS); ExtendedListView_SetRedraw(lvHandle, FALSE); PhAcquireQueuedLockExclusive(&SearchResultsLock); for (i = SearchResultsAddIndex; i < SearchResults->Count; i++) { PPHP_OBJECT_SEARCH_RESULT searchResult = SearchResults->Items[i]; CLIENT_ID clientId; PPH_PROCESS_ITEM processItem; PPH_STRING clientIdName; INT lvItemIndex; clientId.UniqueProcess = searchResult->ProcessId; clientId.UniqueThread = NULL; processItem = PhReferenceProcessItem(clientId.UniqueProcess); clientIdName = PhGetClientIdNameEx(&clientId, processItem ? processItem->ProcessName : NULL); lvItemIndex = PhAddListViewItem( lvHandle, MAXINT, clientIdName->Buffer, searchResult ); PhDereferenceObject(clientIdName); if (processItem) { PhSetReference(&searchResult->ProcessName, processItem->ProcessName); PhDereferenceObject(processItem); } else { searchResult->ProcessName = NULL; } PhSetListViewSubItem(lvHandle, lvItemIndex, 1, searchResult->TypeName->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, searchResult->Name->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, searchResult->HandleString); } SearchResultsAddIndex = i; PhReleaseQueuedLockExclusive(&SearchResultsLock); ExtendedListView_SetRedraw(lvHandle, TRUE); } break; case WM_PH_SEARCH_FINISHED: { NTSTATUS handleSearchStatus = (NTSTATUS)wParam; // Add any un-added items. SendMessage(hwndDlg, WM_PH_SEARCH_UPDATE, 0, 0); NtWaitForSingleObject(SearchThreadHandle, FALSE, NULL); NtClose(SearchThreadHandle); SearchThreadHandle = NULL; SearchStop = FALSE; ExtendedListView_SortItems(GetDlgItem(hwndDlg, IDC_RESULTS)); SetDlgItemText(hwndDlg, IDOK, L"Find"); EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE); SetCursor(LoadCursor(NULL, IDC_ARROW)); if (handleSearchStatus == STATUS_INSUFFICIENT_RESOURCES) { PhShowWarning( hwndDlg, L"Unable to search for handles because the total number of handles on the system is too large. " L"Please check if there are any processes with an extremely large number of handles open." ); } } break; } return FALSE; }
INT_PTR CALLBACK EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
INT_PTR CALLBACK EspServiceTriggersDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_TRIGGERS_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_TRIGGERS_CONTEXT)); memset(context, 0, sizeof(SERVICE_TRIGGERS_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_TRIGGERS_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND triggersLv; context->ServiceItem = serviceItem; context->TriggersLv = triggersLv = GetDlgItem(hwndDlg, IDC_TRIGGERS); context->TriggerContext = EsCreateServiceTriggerContext( context->ServiceItem, hwndDlg, triggersLv ); status = EspLoadTriggerInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service trigger information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } } break; case WM_DESTROY: { EsDestroyServiceTriggerContext(context->TriggerContext); PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_NEW: if (context->TriggerContext) EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_NEW); break; case IDC_EDIT: if (context->TriggerContext) EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT); break; case IDC_DELETE: if (context->TriggerContext) EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_DELETE); break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { ULONG win32Result = 0; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); if (!EsSaveServiceTriggerInfo(context->TriggerContext, &win32Result)) { if (win32Result == ERROR_CANCELLED || (PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service trigger information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY)) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->TriggersLv && context->TriggerContext) { EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_SELECTIONCHANGED); } } break; case NM_DBLCLK: { if (header->hwndFrom == context->TriggersLv && context->TriggerContext) { EsHandleEventServiceTrigger(context->TriggerContext, ES_TRIGGER_EVENT_EDIT); } } break; } } break; } return FALSE; }
INT_PTR CALLBACK EspServiceRecoveryDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_RECOVERY_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_RECOVERY_CONTEXT)); memset(context, 0, sizeof(SERVICE_RECOVERY_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_RECOVERY_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; context->ServiceItem = serviceItem; EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE)); EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_SECONDFAILURE)); EspAddServiceActionStrings(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES)); status = EspLoadRecoveryInfo(hwndDlg, context); if (status == STATUS_SOME_NOT_MAPPED) { if (context->NumberOfActions > 3) { PhShowWarning( hwndDlg, L"The service has %lu failure actions configured, but this program only supports editing 3. " L"If you save the recovery information using this program, the additional failure actions will be lost.", context->NumberOfActions ); } } else if (!NT_SUCCESS(status)) { SetDlgItemText(hwndDlg, IDC_RESETFAILCOUNT, L"0"); if (WindowsVersion >= WINDOWS_VISTA) { context->EnableFlagCheckBox = TRUE; EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS), TRUE); } PhShowWarning(hwndDlg, L"Unable to query service recovery information: %s", ((PPH_STRING)PhAutoDereferenceObject(PhGetNtMessage(status)))->Buffer); } EspFixControls(hwndDlg, context); context->Ready = TRUE; } break; case WM_DESTROY: { PhClearReference(&context->RebootMessage); PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_FIRSTFAILURE: case IDC_SECONDFAILURE: case IDC_SUBSEQUENTFAILURES: { if (HIWORD(wParam) == CBN_SELCHANGE) { EspFixControls(hwndDlg, context); } } break; case IDC_RESTARTCOMPUTEROPTIONS: { DialogBoxParam( PluginInstance->DllBase, MAKEINTRESOURCE(IDD_RESTARTCOMP), hwndDlg, RestartComputerDlgProc, (LPARAM)context ); } break; case IDC_BROWSE: { static PH_FILETYPE_FILTER filters[] = { { L"Executable files (*.exe;*.cmd;*.bat)", L"*.exe;*.cmd;*.bat" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_STRING fileName; fileDialog = PhCreateOpenFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); fileName = PhaGetDlgItemText(hwndDlg, IDC_RUNPROGRAM); PhSetFileDialogFileName(fileDialog, fileName->Buffer); if (PhShowFileDialog(hwndDlg, fileDialog)) { fileName = PhGetFileDialogFileName(fileDialog); SetDlgItemText(hwndDlg, IDC_RUNPROGRAM, fileName->Buffer); PhDereferenceObject(fileName); } PhFreeFileDialog(fileDialog); } break; case IDC_ENABLEFORERRORSTOPS: { context->Dirty = TRUE; } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) context->Dirty = TRUE; } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { NTSTATUS status; PPH_SERVICE_ITEM serviceItem = context->ServiceItem; SC_HANDLE serviceHandle; ULONG restartServiceAfter; SERVICE_FAILURE_ACTIONS failureActions; SC_ACTION actions[3]; ULONG i; BOOLEAN enableRestart = FALSE; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); if (!context->Dirty) { return TRUE; } // Build the failure actions structure. failureActions.dwResetPeriod = GetDlgItemInt(hwndDlg, IDC_RESETFAILCOUNT, NULL, FALSE) * 60 * 60 * 24; failureActions.lpRebootMsg = PhGetStringOrEmpty(context->RebootMessage); failureActions.lpCommand = PhaGetDlgItemText(hwndDlg, IDC_RUNPROGRAM)->Buffer; failureActions.cActions = 3; failureActions.lpsaActions = actions; actions[0].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE)); actions[1].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_SECONDFAILURE)); actions[2].Type = ComboBoxToServiceAction(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES)); restartServiceAfter = GetDlgItemInt(hwndDlg, IDC_RESTARTSERVICEAFTER, NULL, FALSE) * 1000 * 60; for (i = 0; i < 3; i++) { switch (actions[i].Type) { case SC_ACTION_RESTART: actions[i].Delay = restartServiceAfter; enableRestart = TRUE; break; case SC_ACTION_REBOOT: actions[i].Delay = context->RebootAfter; break; case SC_ACTION_RUN_COMMAND: actions[i].Delay = 0; break; } } // Try to save the changes. serviceHandle = PhOpenService( serviceItem->Name->Buffer, SERVICE_CHANGE_CONFIG | (enableRestart ? SERVICE_START : 0) // SC_ACTION_RESTART requires SERVICE_START ); if (serviceHandle) { if (ChangeServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS, &failureActions )) { if (context->EnableFlagCheckBox) { SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; failureActionsFlag.fFailureActionsOnNonCrashFailures = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS)) == BST_CHECKED; ChangeServiceConfig2( serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, &failureActionsFlag ); } CloseServiceHandle(serviceHandle); } else { CloseServiceHandle(serviceHandle); goto ErrorCase; } } else { if (GetLastError() == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { if (NT_SUCCESS(status = PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_FAILURE_ACTIONS, &failureActions ))) { if (context->EnableFlagCheckBox) { SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag; failureActionsFlag.fFailureActionsOnNonCrashFailures = Button_GetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS)) == BST_CHECKED; PhSvcCallChangeServiceConfig2( serviceItem->Name->Buffer, SERVICE_CONFIG_FAILURE_ACTIONS_FLAG, &failureActionsFlag ); } } PhUiDisconnectFromPhSvc(); if (!NT_SUCCESS(status)) { SetLastError(PhNtStatusToDosError(status)); goto ErrorCase; } } else { // User cancelled elevation. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } else { goto ErrorCase; } } return TRUE; ErrorCase: if (PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service recovery information: %s", ((PPH_STRING)PhAutoDereferenceObject(PhGetWin32Message(GetLastError())))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } return TRUE; } } break; } return FALSE; }
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."); } } } }