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); }
VOID PhpRefreshGdiHandles( _In_ HWND hwndDlg, _In_ PGDI_HANDLES_CONTEXT Context ) { HWND lvHandle; ULONG i; PGDI_SHARED_MEMORY gdiShared; USHORT processId; PGDI_HANDLE_ENTRY handle; PPH_GDI_HANDLE_ITEM gdiHandleItem; lvHandle = GetDlgItem(hwndDlg, IDC_LIST); ExtendedListView_SetRedraw(lvHandle, FALSE); ListView_DeleteAllItems(lvHandle); for (i = 0; i < Context->List->Count; i++) { gdiHandleItem = Context->List->Items[i]; if (gdiHandleItem->Information) PhDereferenceObject(gdiHandleItem->Information); PhFree(Context->List->Items[i]); } PhClearList(Context->List); gdiShared = (PGDI_SHARED_MEMORY)NtCurrentPeb()->GdiSharedHandleTable; processId = (USHORT)Context->ProcessItem->ProcessId; for (i = 0; i < GDI_MAX_HANDLE_COUNT; i++) { PWSTR typeName; INT lvItemIndex; WCHAR pointer[PH_PTR_STR_LEN_1]; handle = &gdiShared->Handles[i]; if (handle->Owner.ProcessId != processId) continue; typeName = PhpGetGdiHandleTypeName(handle->Unique); if (!typeName) continue; gdiHandleItem = PhAllocate(sizeof(PH_GDI_HANDLE_ITEM)); gdiHandleItem->Entry = handle; gdiHandleItem->Handle = GDI_MAKE_HANDLE(i, handle->Unique); gdiHandleItem->Object = handle->Object; gdiHandleItem->TypeName = typeName; gdiHandleItem->Information = PhpGetGdiHandleInformation(gdiHandleItem->Handle); PhAddItemList(Context->List, gdiHandleItem); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, gdiHandleItem->TypeName, gdiHandleItem); PhPrintPointer(pointer, UlongToPtr(gdiHandleItem->Handle)); PhSetListViewSubItem(lvHandle, lvItemIndex, 1, pointer); PhPrintPointer(pointer, gdiHandleItem->Object); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, pointer); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, PhGetString(gdiHandleItem->Information)); } ExtendedListView_SortItems(lvHandle); ExtendedListView_SetRedraw(lvHandle, TRUE); }
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, 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); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(L"FindObjWindowPosition", L"FindObjWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"FindObjListViewColumns", PhFindObjectsListViewHandle); } break; case WM_SHOWWINDOW: { SetFocus(GetDlgItem(hwndDlg, IDC_FILTER)); 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; // Cleanup 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. SearchString = PhGetWindowText(GetDlgItem(hwndDlg, IDC_FILTER)); SearchResults = PhCreateList(128); SearchResultsAddIndex = 0; SearchThreadHandle = PhCreateThread(0, PhpFindObjectsThreadStart, NULL); if (!SearchThreadHandle) 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_OBJECT_PROCESSPROPERTIES: { PPHP_OBJECT_SEARCH_RESULT result = PhGetSelectedListViewItemParam(PhFindObjectsListViewHandle); if (result) { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(result->ProcessId)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } } } 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 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) { HMENU menu; HMENU subMenu; menu = LoadMenu(PhInstanceHandle, MAKEINTRESOURCE(IDR_FINDOBJ)); subMenu = GetSubMenu(menu, 0); SetMenuDefaultItem(subMenu, ID_OBJECT_PROPERTIES, FALSE); PhpInitializeFindObjMenu( subMenu, results, numberOfResults ); PhShowContextMenu( hwndDlg, PhFindObjectsListViewHandle, subMenu, point ); DestroyMenu(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) { searchResult->ProcessName = processItem->ProcessName; PhReferenceObject(searchResult->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: { // Add any un-added items. SendMessage(hwndDlg, WM_PH_SEARCH_UPDATE, 0, 0); PhDereferenceObject(SearchString); 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)); } break; } return FALSE; }
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 DnsCacheDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PhCenterWindow(hwndDlg, PhMainWndHandle); ListViewWndHandle = GetDlgItem(hwndDlg, IDC_DNSLIST); PhRegisterDialog(hwndDlg); PhSetListViewStyle(ListViewWndHandle, FALSE, TRUE); PhSetControlTheme(ListViewWndHandle, L"explorer"); PhAddListViewColumn(ListViewWndHandle, 0, 0, 0, LVCFMT_LEFT, 280, L"Host Name"); PhAddListViewColumn(ListViewWndHandle, 1, 1, 1, LVCFMT_LEFT, 70, L"Type"); PhAddListViewColumn(ListViewWndHandle, 2, 2, 2, LVCFMT_LEFT, 100, L"IP Address"); PhAddListViewColumn(ListViewWndHandle, 3, 3, 3, LVCFMT_LEFT, 50, L"TTL"); PhSetExtendedListView(ListViewWndHandle); PhInitializeLayoutManager(&LayoutManager, hwndDlg); PhAddLayoutItem(&LayoutManager, ListViewWndHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_REFRESH), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDC_DNS_CLEAR), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); PhLoadWindowPlacementFromSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg); PhLoadListViewColumnsFromSetting(SETTING_NAME_COLUMNS, ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); } break; case WM_DESTROY: { if (DnsApiHandle) { FreeLibrary(DnsApiHandle); DnsApiHandle = NULL; } PhSaveWindowPlacementToSetting(SETTING_NAME_WINDOW_POSITION, SETTING_NAME_WINDOW_SIZE, hwndDlg); PhSaveListViewColumnsToSetting(SETTING_NAME_COLUMNS, ListViewWndHandle); PhDeleteLayoutManager(&LayoutManager); } break; case WM_SIZE: PhLayoutManagerLayout(&LayoutManager); break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_DNS_CLEAR: { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"Flush", L"the dns cache", NULL, FALSE )) { if (DnsFlushResolverCache_I) DnsFlushResolverCache_I(); ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } } break; case IDC_DNS_REFRESH: { ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } break; case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; } } break; case WM_NOTIFY: { LPNMHDR hdr = (LPNMHDR)lParam; switch (hdr->code) { case NM_RCLICK: { if (hdr->hwndFrom == ListViewWndHandle) ShowStatusMenu(hwndDlg); } break; } } break; } return FALSE; }
INT_PTR CALLBACK PhpProcessHeapsDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { PPROCESS_HEAPS_CONTEXT context = NULL; if (uMsg != WM_INITDIALOG) { context = (PPROCESS_HEAPS_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); } else { context = (PPROCESS_HEAPS_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; ULONG i; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 100, L"Address"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 120, L"Used"); PhAddListViewColumn(lvHandle, 2, 2, 2, LVCFMT_LEFT, 120, L"Committed"); PhAddListViewColumn(lvHandle, 3, 3, 3, LVCFMT_LEFT, 80, L"Entries"); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhSetExtendedListView(lvHandle); ExtendedListView_SetContext(lvHandle, context); ExtendedListView_SetCompareFunction(lvHandle, 0, PhpHeapAddressCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 1, PhpHeapUsedCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 2, PhpHeapCommittedCompareFunction); ExtendedListView_SetCompareFunction(lvHandle, 3, PhpHeapEntriesCompareFunction); ExtendedListView_SetItemFontFunction(lvHandle, PhpHeapFontFunction); for (i = 0; i < context->ProcessHeaps->NumberOfHeaps; i++) { PRTL_HEAP_INFORMATION heapInfo = &context->ProcessHeaps->Heaps[i]; WCHAR addressString[PH_PTR_STR_LEN_1]; INT lvItemIndex; PPH_STRING usedString; PPH_STRING committedString; PPH_STRING numberOfEntriesString; PhPrintPointer(addressString, heapInfo->BaseAddress); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, addressString, heapInfo); usedString = PhFormatSize(heapInfo->BytesAllocated, -1); committedString = PhFormatSize(heapInfo->BytesCommitted, -1); numberOfEntriesString = PhFormatUInt64(heapInfo->NumberOfEntries, TRUE); PhSetListViewSubItem(lvHandle, lvItemIndex, 1, usedString->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, committedString->Buffer); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, numberOfEntriesString->Buffer); PhDereferenceObject(usedString); PhDereferenceObject(committedString); PhDereferenceObject(numberOfEntriesString); } ExtendedListView_SortItems(lvHandle); } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_SIZESINBYTES: { BOOLEAN sizesInBytes = Button_GetCheck(GetDlgItem(hwndDlg, IDC_SIZESINBYTES)) == BST_CHECKED; INT index = -1; ExtendedListView_SetRedraw(context->ListViewHandle, FALSE); while ((index = ListView_GetNextItem(context->ListViewHandle, index, LVNI_ALL)) != -1) { PRTL_HEAP_INFORMATION heapInfo; PPH_STRING usedString; PPH_STRING committedString; if (PhGetListViewItemParam(context->ListViewHandle, index, &heapInfo)) { usedString = PhFormatSize(heapInfo->BytesAllocated, sizesInBytes ? 0 : -1); committedString = PhFormatSize(heapInfo->BytesCommitted, sizesInBytes ? 0 : -1); PhSetListViewSubItem(context->ListViewHandle, index, 1, usedString->Buffer); PhSetListViewSubItem(context->ListViewHandle, index, 2, committedString->Buffer); PhDereferenceObject(usedString); PhDereferenceObject(committedString); } } ExtendedListView_SetRedraw(context->ListViewHandle, TRUE); } break; } } break; case WM_NOTIFY: { PhHandleListViewNotifyForCopy(lParam, context->ListViewHandle); } break; case WM_CONTEXTMENU: { if ((HWND)wParam == context->ListViewHandle) { POINT point; PRTL_HEAP_INFORMATION heapInfo; PPH_EMENU menu; INT selectedCount; PPH_EMENU_ITEM menuItem; point.x = (SHORT)LOWORD(lParam); point.y = (SHORT)HIWORD(lParam); if (point.x == -1 && point.y == -1) PhGetListViewContextMenuPoint((HWND)wParam, &point); selectedCount = ListView_GetSelectedCount(context->ListViewHandle); heapInfo = PhGetSelectedListViewItemParam(context->ListViewHandle); if (selectedCount != 0) { menu = PhCreateEMenu(); PhInsertEMenuItem(menu, PhCreateEMenuItem(selectedCount != 1 ? PH_EMENU_DISABLED : 0, 1, L"Destroy", NULL, NULL), -1); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 2, L"Copy\bCtrl+C", NULL, NULL), -1); menuItem = PhShowEMenu(menu, context->ListViewHandle, PH_EMENU_SHOW_LEFTRIGHT | PH_EMENU_SHOW_NONOTIFY, PH_ALIGN_LEFT | PH_ALIGN_TOP, point.x, point.y); if (menuItem) { switch (menuItem->Id) { case 1: if (PhUiDestroyHeap(hwndDlg, context->ProcessItem->ProcessId, heapInfo->BaseAddress)) ListView_DeleteItem(context->ListViewHandle, PhFindListViewItemByParam(context->ListViewHandle, -1, heapInfo)); break; case 2: PhCopyListView(context->ListViewHandle); break; } } PhDestroyEMenu(menu); } } } break; } REFLECT_MESSAGE_DLG(hwndDlg, context->ListViewHandle, uMsg, wParam, lParam); return FALSE; }
VOID ShowStatusMenu( _In_ HWND hwndDlg ) { PPH_STRING cacheEntryName; cacheEntryName = PhGetSelectedListViewItemText(ListViewWndHandle); if (cacheEntryName) { POINT cursorPos; PPH_EMENU menu; PPH_EMENU_ITEM selectedItem; GetCursorPos(&cursorPos); menu = PhCreateEMenu(); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 1, L"Remove", NULL, NULL), -1); PhInsertEMenuItem(menu, PhCreateEMenuItem(0, 2, L"Copy Host Name", NULL, NULL), -1); selectedItem = PhShowEMenu( menu, PhMainWndHandle, PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, cursorPos.x, cursorPos.y ); if (selectedItem && selectedItem->Id != -1) { switch (selectedItem->Id) { case 1: { INT lvItemIndex = PhFindListViewItemByFlags( ListViewWndHandle, -1, LVNI_SELECTED ); if (lvItemIndex != -1) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"remove", cacheEntryName->Buffer, NULL, FALSE )) { if (DnsFlushResolverCacheEntry_I(cacheEntryName->Buffer)) { ExtendedListView_SetRedraw(ListViewWndHandle, FALSE); ListView_DeleteAllItems(ListViewWndHandle); EnumDnsCacheTable(ListViewWndHandle); ExtendedListView_SetRedraw(ListViewWndHandle, TRUE); } } } } break; case 2: PhSetClipboardString(hwndDlg, &cacheEntryName->sr); break; } } PhDestroyEMenu(menu); PhDereferenceObject(cacheEntryName); } }
static VOID PhListTick( __in PPH_EXTLV_CONTEXT Context ) { HWND hwnd = Context->Handle; ULONG tickCount; BOOLEAN redrawDisabled = FALSE; PPH_LIST itemsToRemove = NULL; PH_HASHTABLE_ENUM_CONTEXT enumContext; PPH_TICK_ENTRY entry; if (!Context->TickHashtable) return; tickCount = GetTickCount(); // First pass PhBeginEnumHashtable(Context->TickHashtable, &enumContext); while (entry = PhNextEnumHashtable(&enumContext)) { LVITEM item; PH_ITEM_STATE itemState; if (PhRoundNumber(tickCount - entry->TickCount, PH_DURATION_MULT) < Context->HighlightingDuration) continue; item.mask = LVIF_STATE; item.iItem = ListView_MapIDToIndex(hwnd, entry->Id); item.iSubItem = 0; item.stateMask = LVIS_STATEIMAGEMASK; CallWindowProc(Context->OldWndProc, hwnd, LVM_GETITEM, 0, (LPARAM)&item); itemState = PH_GET_ITEM_STATE(item.state); if (itemState == NewItemState) { item.state = INDEXTOSTATEIMAGEMASK(NormalItemState); CallWindowProc(Context->OldWndProc, hwnd, LVM_SETITEM, 0, (LPARAM)&item); if (!itemsToRemove) itemsToRemove = PhCreateList(2); PhAddItemList(itemsToRemove, (PVOID)entry->Id); entry->TickCount = tickCount; } } // Second pass // This pass is specifically for deleting items. PhBeginEnumHashtable(Context->TickHashtable, &enumContext); while (entry = PhNextEnumHashtable(&enumContext)) { LVITEM item; PH_ITEM_STATE itemState; if (itemsToRemove) { if (PhFindItemList(itemsToRemove, (PVOID)entry->Id) != -1) continue; } if (PhRoundNumber(tickCount - entry->TickCount, PH_DURATION_MULT) < Context->HighlightingDuration) continue; item.mask = LVIF_STATE; item.iItem = ListView_MapIDToIndex(hwnd, entry->Id); item.iSubItem = 0; item.stateMask = LVIS_STATEIMAGEMASK; CallWindowProc(Context->OldWndProc, hwnd, LVM_GETITEM, 0, (LPARAM)&item); itemState = PH_GET_ITEM_STATE(item.state); if (itemState == RemovingItemState) { if (!redrawDisabled) { ExtendedListView_SetRedraw(hwnd, FALSE); redrawDisabled = TRUE; } CallWindowProc(Context->OldWndProc, hwnd, LVM_DELETEITEM, item.iItem, 0); if (!itemsToRemove) itemsToRemove = PhCreateList(2); PhAddItemList(itemsToRemove, (PVOID)entry->Id); entry->TickCount = tickCount; } } if (redrawDisabled) { ExtendedListView_SetRedraw(hwnd, TRUE); } if (itemsToRemove) { ULONG i; for (i = 0; i < itemsToRemove->Count; i++) { PH_TICK_ENTRY removeEntry; removeEntry.Id = (ULONG)itemsToRemove->Items[i]; PhRemoveEntryHashtable(Context->TickHashtable, &removeEntry); } PhDereferenceObject(itemsToRemove); } }
static BOOLEAN EtpUpdateWsWatch( _In_ HWND hwndDlg, _In_ PWS_WATCH_CONTEXT Context ) { NTSTATUS status; BOOLEAN result; ULONG returnLength; PPROCESS_WS_WATCH_INFORMATION_EX wsWatchInfo; // Query WS watch information. if (!Context->Buffer) return FALSE; status = NtQueryInformationProcess( Context->ProcessHandle, ProcessWorkingSetWatchEx, Context->Buffer, Context->BufferSize, &returnLength ); if (status == STATUS_UNSUCCESSFUL) { // WS Watch is not enabled. return FALSE; } if (status == STATUS_NO_MORE_ENTRIES) { // There were no new faults, but we still need to process symbol lookup results. result = TRUE; goto SkipBuffer; } if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH) { PhFree(Context->Buffer); Context->Buffer = PhAllocate(returnLength); Context->BufferSize = returnLength; status = NtQueryInformationProcess( Context->ProcessHandle, ProcessWorkingSetWatchEx, Context->Buffer, Context->BufferSize, &returnLength ); } if (!NT_SUCCESS(status)) { // Error related to the buffer size. Try again later. result = FALSE; goto SkipBuffer; } // Update the hashtable and list view. ExtendedListView_SetRedraw(Context->ListViewHandle, FALSE); wsWatchInfo = Context->Buffer; while (wsWatchInfo->BasicInfo.FaultingPc) { PPVOID entry; WCHAR buffer[PH_INT32_STR_LEN_1]; INT lvItemIndex; ULONG newCount; // Update the count in the entry for this instruction pointer, or add a new entry if it doesn't exist. entry = PhFindItemSimpleHashtable(Context->Hashtable, wsWatchInfo->BasicInfo.FaultingPc); if (entry) { newCount = PtrToUlong(*entry) + 1; *entry = UlongToPtr(newCount); lvItemIndex = PhFindListViewItemByParam(Context->ListViewHandle, -1, wsWatchInfo->BasicInfo.FaultingPc); } else { PPH_STRING basicSymbol; newCount = 1; PhAddItemSimpleHashtable(Context->Hashtable, wsWatchInfo->BasicInfo.FaultingPc, UlongToPtr(1)); // Get a basic symbol name (module+offset). basicSymbol = EtpGetBasicSymbol(Context->SymbolProvider, (ULONG64)wsWatchInfo->BasicInfo.FaultingPc); lvItemIndex = PhAddListViewItem(Context->ListViewHandle, MAXINT, basicSymbol->Buffer, wsWatchInfo->BasicInfo.FaultingPc); PhDereferenceObject(basicSymbol); // Queue a full symbol lookup. EtpQueueSymbolLookup(Context, wsWatchInfo->BasicInfo.FaultingPc); } // Update the count in the list view item. PhPrintUInt32(buffer, newCount); PhSetListViewSubItem( Context->ListViewHandle, lvItemIndex, 1, buffer ); wsWatchInfo++; } ExtendedListView_SetRedraw(Context->ListViewHandle, TRUE); result = TRUE; SkipBuffer: EtpProcessSymbolLookupResults(hwndDlg, Context); ExtendedListView_SortItems(Context->ListViewHandle); return result; }
BOOLEAN EtpRefreshUnloadedDlls( __in HWND hwndDlg, __in PUNLOADED_DLLS_CONTEXT Context ) { NTSTATUS status; PULONG elementSize; PULONG elementCount; PVOID eventTrace; HANDLE processHandle = NULL; ULONG eventTraceSize; ULONG capturedElementSize; ULONG capturedElementCount; PVOID capturedEventTracePointer; PVOID capturedEventTrace = NULL; ULONG i; PVOID currentEvent; HWND lvHandle; lvHandle = GetDlgItem(hwndDlg, IDC_LIST); ListView_DeleteAllItems(lvHandle); RtlGetUnloadEventTraceEx(&elementSize, &elementCount, &eventTrace); if (!NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_VM_READ, Context->ProcessItem->ProcessId))) goto CleanupExit; // We have the pointers for the unload event trace information. // Since ntdll is loaded at the same base address across all processes, // we can read the information in. if (!NT_SUCCESS(status = PhReadVirtualMemory( processHandle, elementSize, &capturedElementSize, sizeof(ULONG), NULL ))) goto CleanupExit; if (!NT_SUCCESS(status = PhReadVirtualMemory( processHandle, elementCount, &capturedElementCount, sizeof(ULONG), NULL ))) goto CleanupExit; if (!NT_SUCCESS(status = PhReadVirtualMemory( processHandle, eventTrace, &capturedEventTracePointer, sizeof(PVOID), NULL ))) goto CleanupExit; if (!capturedEventTracePointer) goto CleanupExit; // no events if (capturedElementCount > 0x4000) capturedElementCount = 0x4000; eventTraceSize = capturedElementSize * capturedElementCount; capturedEventTrace = PhAllocateSafe(eventTraceSize); if (!capturedEventTrace) { status = STATUS_NO_MEMORY; goto CleanupExit; } if (!NT_SUCCESS(status = PhReadVirtualMemory( processHandle, capturedEventTracePointer, capturedEventTrace, eventTraceSize, NULL ))) goto CleanupExit; currentEvent = capturedEventTrace; ExtendedListView_SetRedraw(lvHandle, FALSE); for (i = 0; i < capturedElementCount; i++) { PRTL_UNLOAD_EVENT_TRACE rtlEvent = currentEvent; INT lvItemIndex; WCHAR buffer[128]; PPH_STRING string; LARGE_INTEGER time; SYSTEMTIME systemTime; if (!rtlEvent->BaseAddress) break; PhPrintUInt32(buffer, rtlEvent->Sequence); lvItemIndex = PhAddListViewItem(lvHandle, MAXINT, buffer, rtlEvent); // Name if (PhCopyUnicodeStringZ(rtlEvent->ImageName, sizeof(rtlEvent->ImageName) / sizeof(WCHAR), buffer, sizeof(buffer) / sizeof(WCHAR), NULL)) { PhSetListViewSubItem(lvHandle, lvItemIndex, 1, buffer); } // Base Address PhPrintPointer(buffer, rtlEvent->BaseAddress); PhSetListViewSubItem(lvHandle, lvItemIndex, 2, buffer); // Size string = PhFormatSize(rtlEvent->SizeOfImage, -1); PhSetListViewSubItem(lvHandle, lvItemIndex, 3, string->Buffer); PhDereferenceObject(string); // Time Stamp RtlSecondsSince1970ToTime(rtlEvent->TimeDateStamp, &time); PhLargeIntegerToLocalSystemTime(&systemTime, &time); string = PhFormatDateTime(&systemTime); PhSetListViewSubItem(lvHandle, lvItemIndex, 4, string->Buffer); PhDereferenceObject(string); // Checksum PhPrintPointer(buffer, UlongToPtr(rtlEvent->CheckSum)); PhSetListViewSubItem(lvHandle, lvItemIndex, 5, buffer); currentEvent = PTR_ADD_OFFSET(currentEvent, capturedElementSize); } ExtendedListView_SortItems(lvHandle); ExtendedListView_SetRedraw(lvHandle, TRUE); if (Context->CapturedEventTrace) PhFree(Context->CapturedEventTrace); Context->CapturedEventTrace = capturedEventTrace; CleanupExit: if (processHandle) NtClose(processHandle); if (NT_SUCCESS(status)) { return TRUE; } else { PhShowStatus(hwndDlg, L"Unable to retrieve unload event trace information", status, 0); return FALSE; } }
static INT_PTR CALLBACK PhpHiddenProcessesDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); PhHiddenProcessesListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_PROCESSES); PhInitializeLayoutManager(&WindowLayoutManager, hwndDlg); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_INTRO), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_TOP | PH_ANCHOR_RIGHT | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, lvHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM | PH_LAYOUT_FORCE_INVALIDATE); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_METHOD), NULL, PH_ANCHOR_LEFT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_TERMINATE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDC_SCAN), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&WindowLayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); MinimumSize.left = 0; MinimumSize.top = 0; MinimumSize.right = 330; MinimumSize.bottom = 140; MapDialogRect(hwndDlg, &MinimumSize); PhRegisterDialog(hwndDlg); PhLoadWindowPlacementFromSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSetListViewStyle(lvHandle, TRUE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 320, L"Process"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 60, L"PID"); PhSetExtendedListView(lvHandle); PhLoadListViewColumnsFromSetting(L"HiddenProcessesListViewColumns", lvHandle); ExtendedListView_AddFallbackColumn(lvHandle, 0); ExtendedListView_AddFallbackColumn(lvHandle, 1); ExtendedListView_SetItemColorFunction(lvHandle, PhpHiddenProcessesColorFunction); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"Brute Force"); ComboBox_AddString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles"); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_METHOD), L"CSR Handles", FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_TERMINATE), FALSE); } break; case WM_DESTROY: { PhSaveWindowPlacementToSetting(L"HiddenProcessesWindowPosition", L"HiddenProcessesWindowSize", hwndDlg); PhSaveListViewColumnsToSetting(L"HiddenProcessesListViewColumns", PhHiddenProcessesListViewHandle); } break; case WM_CLOSE: { // Hide, don't close. ShowWindow(hwndDlg, SW_HIDE); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 0); } return TRUE; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: { SendMessage(hwndDlg, WM_CLOSE, 0, 0); } break; case IDC_SCAN: { NTSTATUS status; PPH_STRING method; method = PhGetWindowText(GetDlgItem(hwndDlg, IDC_METHOD)); PhAutoDereferenceObject(method); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->FileName) PhDereferenceObject(entry->FileName); PhFree(entry); } PhDereferenceObject(ProcessesList); } ListView_DeleteAllItems(PhHiddenProcessesListViewHandle); ProcessesList = PhCreateList(40); ProcessesMethod = PhEqualString2(method, L"Brute Force", TRUE) ? BruteForceScanMethod : CsrHandlesScanMethod; NumberOfHiddenProcesses = 0; NumberOfTerminatedProcesses = 0; ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, FALSE); status = PhEnumHiddenProcesses( ProcessesMethod, PhpHiddenProcessesCallback, NULL ); ExtendedListView_SortItems(PhHiddenProcessesListViewHandle); ExtendedListView_SetRedraw(PhHiddenProcessesListViewHandle, TRUE); if (NT_SUCCESS(status)) { SetDlgItemText(hwndDlg, IDC_DESCRIPTION, PhaFormatString(L"%u hidden process(es), %u terminated process(es).", NumberOfHiddenProcesses, NumberOfTerminatedProcesses)->Buffer ); InvalidateRect(GetDlgItem(hwndDlg, IDC_DESCRIPTION), NULL, TRUE); } else { PhShowStatus(hwndDlg, L"Unable to perform the scan", status, 0); } } break; case IDC_TERMINATE: { PPH_HIDDEN_PROCESS_ENTRY *entries; ULONG numberOfEntries; ULONG i; PhGetSelectedListViewItemParams(PhHiddenProcessesListViewHandle, &entries, &numberOfEntries); if (numberOfEntries != 0) { if (!PhGetIntegerSetting(L"EnableWarnings") || PhShowConfirmMessage( hwndDlg, L"terminate", L"the selected process(es)", L"Terminating a hidden process may cause the system to become unstable " L"or crash.", TRUE )) { NTSTATUS status; HANDLE processHandle; BOOLEAN refresh; refresh = FALSE; for (i = 0; i < numberOfEntries; i++) { if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, PROCESS_TERMINATE, entries[i]->ProcessId ); } if (NT_SUCCESS(status)) { status = PhTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); if (NT_SUCCESS(status)) refresh = TRUE; } else { PhShowStatus(hwndDlg, L"Unable to terminate the process", status, 0); } } if (refresh) { LARGE_INTEGER interval; // Sleep for a bit before continuing. It seems to help avoid // BSODs. interval.QuadPart = -250 * PH_TIMEOUT_MS; NtDelayExecution(FALSE, &interval); SendMessage(hwndDlg, WM_COMMAND, IDC_SCAN, 0); } } } PhFree(entries); } break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Text files (*.txt)", L"*.txt" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); PhSetFileDialogFileName(fileDialog, L"Hidden Processes.txt"); if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PhGetFileDialogFileName(fileDialog); PhAutoDereferenceObject(fileName); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { PhWriteStringAsUtf8FileStream(fileStream, &PhUnicodeByteOrderMark); PhWritePhTextHeader(fileStream); PhWriteStringAsUtf8FileStream2(fileStream, L"Method: "); PhWriteStringAsUtf8FileStream2(fileStream, ProcessesMethod == BruteForceScanMethod ? L"Brute Force\r\n" : L"CSR Handles\r\n"); PhWriteStringFormatAsUtf8FileStream( fileStream, L"Hidden: %u\r\nTerminated: %u\r\n\r\n", NumberOfHiddenProcesses, NumberOfTerminatedProcesses ); if (ProcessesList) { ULONG i; for (i = 0; i < ProcessesList->Count; i++) { PPH_HIDDEN_PROCESS_ENTRY entry = ProcessesList->Items[i]; if (entry->Type == HiddenProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[HIDDEN] "); else if (entry->Type == TerminatedProcess) PhWriteStringAsUtf8FileStream2(fileStream, L"[Terminated] "); else if (entry->Type != NormalProcess) continue; PhWriteStringFormatAsUtf8FileStream( fileStream, L"%s (%u)\r\n", entry->FileName->Buffer, HandleToUlong(entry->ProcessId) ); } } PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; PhHandleListViewNotifyBehaviors(lParam, PhHiddenProcessesListViewHandle, PH_LIST_VIEW_DEFAULT_1_BEHAVIORS); switch (header->code) { case LVN_ITEMCHANGED: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { EnableWindow( GetDlgItem(hwndDlg, IDC_TERMINATE), ListView_GetSelectedCount(PhHiddenProcessesListViewHandle) > 0 ); } } break; case NM_DBLCLK: { if (header->hwndFrom == PhHiddenProcessesListViewHandle) { PPH_HIDDEN_PROCESS_ENTRY entry; entry = PhGetSelectedListViewItemParam(PhHiddenProcessesListViewHandle); if (entry) { PPH_PROCESS_ITEM processItem; if (processItem = PhpCreateProcessItemForHiddenProcess(entry)) { ProcessHacker_ShowProcessProperties(PhMainWndHandle, processItem); PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"Unable to create a process structure for the selected process."); } } } } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&WindowLayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_CTLCOLORSTATIC: { if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_DESCRIPTION)) { if (NumberOfHiddenProcesses != 0) { SetTextColor((HDC)wParam, RGB(0xff, 0x00, 0x00)); } SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE)); return (INT_PTR)GetSysColorBrush(COLOR_3DFACE); } } break; } REFLECT_MESSAGE_DLG(hwndDlg, PhHiddenProcessesListViewHandle, uMsg, wParam, lParam); return FALSE; }