VOID GetDriverVersion(VOID) { NvStatus status = NVAPI_ERROR; NV_DISPLAY_DRIVER_VERSION versionInfo = { 0 }; versionInfo.Version = NV_DISPLAY_DRIVER_VERSION_VER; status = NvAPI_GetDisplayDriverVersion(dispHandle, &versionInfo); if (NV_SUCCESS(status)) { PH_STRING_BUILDER strb = { 0 }; PhInitializeStringBuilder(&strb, 30); PhAppendFormatStringBuilder(&strb, L"Driver Version: %d", versionInfo.drvVersion / 100); PhAppendFormatStringBuilder(&strb, L".%d", versionInfo.drvVersion % 100); //PhAppendFormatStringBuilder(&strb, L" Driver Branch: %ls", versionInfo.szBuildBranchString); PhDeleteStringBuilder(&strb); } else { LogEvent(L"gfxinfo: (GetDriverVersion) NvAPI_GetDisplayDriverVersion failed (%s)", status); } }
PPH_STRING PhSaveListViewColumnSettings( _In_ HWND ListViewHandle ) { PH_STRING_BUILDER stringBuilder; ULONG i = 0; LVCOLUMN lvColumn; PhInitializeStringBuilder(&stringBuilder, 20); PhAppendFormatStringBuilder(&stringBuilder, L"@%u|", PhGlobalDpi); lvColumn.mask = LVCF_WIDTH | LVCF_ORDER; while (ListView_GetColumn(ListViewHandle, i, &lvColumn)) { PhAppendFormatStringBuilder( &stringBuilder, L"%u,%u|", lvColumn.iOrder, lvColumn.cx ); i++; } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
VOID StatusBarSaveSettings( VOID ) { ULONG buttonIndex = 0; PPH_STRING settingsString; PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 100); PhAppendFormatStringBuilder( &stringBuilder, L"%lu|", StatusBarItemList->Count ); for (buttonIndex = 0; buttonIndex < StatusBarItemList->Count; buttonIndex++) { PSTATUSBAR_ITEM statusItem = StatusBarItemList->Items[buttonIndex]; PhAppendFormatStringBuilder( &stringBuilder, L"%lu|", statusItem->Id ); } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder)); PhSetStringSetting2(SETTING_NAME_STATUSBAR_CONFIG, &settingsString->sr); }
PPH_STRING DiskDriveQueryDosMountPoints( _In_ ULONG DeviceNumber ) { ULONG driveMask; WCHAR deviceNameBuffer[7] = L"\\\\.\\?:"; PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, MAX_PATH); driveMask = DiskDriveQueryDeviceMap(); // NOTE: This isn't the best way of doing this but it works. for (INT i = 0; i < 0x1A; i++) { if (driveMask & (0x1 << i)) { HANDLE deviceHandle; deviceNameBuffer[4] = (WCHAR)('A' + i); if (NT_SUCCESS(PhCreateFileWin32( &deviceHandle, deviceNameBuffer, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { ULONG deviceNumber = ULONG_MAX; // Note: Do not initialize to zero. DEVICE_TYPE deviceType = 0; if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber( deviceHandle, &deviceNumber, &deviceType ))) { // BUG: Device numbers are re-used on seperate device controllers and this // causes drive letters to be assigned to disks at those same indexes. // For now, just filter CD_ROM devices but we may need to be a lot more strict and // only allow devices of type FILE_DEVICE_DISK to be scanned for mount points. if (deviceNumber == DeviceNumber && deviceType != FILE_DEVICE_CD_ROM) { PhAppendFormatStringBuilder(&stringBuilder, L"%c: ", deviceNameBuffer[4]); } } NtClose(deviceHandle); } } } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
static PPH_STRING PhpGetStringForSelectedResults( _In_ HWND ListViewHandle, _In_ PPH_LIST Results, _In_ BOOLEAN All ) { PH_STRING_BUILDER stringBuilder; ULONG i; PhInitializeStringBuilder(&stringBuilder, 0x100); for (i = 0; i < Results->Count; i++) { PPH_MEMORY_RESULT result; if (!All) { if (!(ListView_GetItemState(ListViewHandle, i, LVIS_SELECTED) & LVIS_SELECTED)) continue; } result = Results->Items[i]; PhAppendFormatStringBuilder(&stringBuilder, L"0x%Ix (%u): %s\r\n", result->Address, result->Length, result->Display.Buffer ? result->Display.Buffer : L""); } return PhFinalStringBuilderString(&stringBuilder); }
VOID ToolbarSaveButtonSettings( VOID ) { INT buttonIndex = 0; INT buttonCount = 0; PPH_STRING settingsString; PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 100); buttonCount = (INT)SendMessage(ToolBarHandle, TB_BUTTONCOUNT, 0, 0); PhAppendFormatStringBuilder( &stringBuilder, L"%d|", buttonCount ); for (buttonIndex = 0; buttonIndex < buttonCount; buttonIndex++) { TBBUTTONINFO buttonInfo = { sizeof(TBBUTTONINFO), TBIF_BYINDEX | TBIF_IMAGE | TBIF_STYLE | TBIF_COMMAND }; // Get button information. if (SendMessage(ToolBarHandle, TB_GETBUTTONINFO, buttonIndex, (LPARAM)&buttonInfo) == -1) break; PhAppendFormatStringBuilder( &stringBuilder, L"%d|", buttonInfo.idCommand ); } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PhFinalStringBuilderString(&stringBuilder); PhSetStringSetting2(SETTING_NAME_TOOLBAR_CONFIG, &settingsString->sr); PhDereferenceObject(settingsString); }
PPH_STRING DiskDriveQueryDosMountPoints( _In_ ULONG DeviceNumber ) { ULONG driveMask; PH_STRING_BUILDER stringBuilder; WCHAR devicePath[] = L"\\\\.\\?:"; PhInitializeStringBuilder(&stringBuilder, MAX_PATH); driveMask = DiskDriveQueryDeviceMap(); // NOTE: This isn't the best way of doing this but it works (It's also what Task Manager does). for (INT i = 0; i < 0x1A; i++) { if (driveMask & (0x1 << i)) { HANDLE deviceHandle; devicePath[4] = 'A' + i; if (NT_SUCCESS(PhCreateFileWin32( &deviceHandle, devicePath, FILE_READ_ATTRIBUTES | SYNCHRONIZE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { ULONG deviceNumber = ULONG_MAX; // Note: Do not initialize to zero. if (NT_SUCCESS(DiskDriveQueryDeviceTypeAndNumber( deviceHandle, &deviceNumber, NULL ))); { if (deviceNumber == DeviceNumber) { PhAppendFormatStringBuilder(&stringBuilder, L"%c: ", devicePath[4]); } } NtClose(deviceHandle); } } } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
VOID ReBarSaveLayoutSettings( VOID ) { UINT bandIndex = 0; UINT bandCount = 0; PPH_STRING settingsString; PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 100); bandCount = (UINT)SendMessage(RebarHandle, RB_GETBANDCOUNT, 0, 0); for (bandIndex = 0; bandIndex < bandCount; bandIndex++) { REBARBANDINFO rebarBandInfo = { REBARBANDINFO_V6_SIZE, RBBIM_STYLE | RBBIM_SIZE | RBBIM_ID }; SendMessage(RebarHandle, RB_GETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo); if (rebarBandInfo.fStyle & RBBS_GRIPPERALWAYS) { rebarBandInfo.fStyle &= ~RBBS_GRIPPERALWAYS; } if (rebarBandInfo.fStyle & RBBS_NOGRIPPER) { rebarBandInfo.fStyle &= ~RBBS_NOGRIPPER; } if (rebarBandInfo.fStyle & RBBS_FIXEDSIZE) { rebarBandInfo.fStyle &= ~RBBS_FIXEDSIZE; } PhAppendFormatStringBuilder( &stringBuilder, L"%u|%u|%u|", rebarBandInfo.wID, rebarBandInfo.cx, rebarBandInfo.fStyle ); } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PhFinalStringBuilderString(&stringBuilder); PhSetStringSetting2(SETTING_NAME_REBAR_CONFIG, &settingsString->sr); PhDereferenceObject(settingsString); }
VOID PhSaveSettingsColumnList( _In_ PWSTR SettingName, _In_ PPH_LIST ColumnSetList ) { ULONG index; PPH_STRING settingsString; PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 100); PhAppendFormatStringBuilder( &stringBuilder, L"%lu-", ColumnSetList->Count ); for (index = 0; index < ColumnSetList->Count; index++) { PPH_COLUMN_SET_ENTRY entry = ColumnSetList->Items[index]; if (PhIsNullOrEmptyString(entry->Name)) continue; PhAppendFormatStringBuilder( &stringBuilder, L"%s-%s-%s-", entry->Name->Buffer, PhGetStringOrEmpty(entry->Setting), PhGetStringOrEmpty(entry->Sorting) ); } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder)); PhSetStringSetting2(SettingName, &settingsString->sr); }
VOID GetProcessTooltipTextCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PPH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText = Parameter; PPH_PROCESS_ITEM processItem; processItem = getTooltipText->Parameter; // Put some text into the tooltip. This will go in just before the Notes section. PhAppendFormatStringBuilder( getTooltipText->StringBuilder, L"Sample plugin:\n The process name is: %s\n", processItem->ProcessName->Buffer ); }
VOID NTAPI GetProcessTooltipTextCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PPH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText = Parameter; BOXED_PROCESS lookupBoxedProcess; PBOXED_PROCESS boxedProcess; PhAcquireQueuedLockShared(&BoxedProcessesLock); lookupBoxedProcess.ProcessId = ((PPH_PROCESS_ITEM)getTooltipText->Parameter)->ProcessId; if (boxedProcess = PhFindEntryHashtable(BoxedProcessesHashtable, &lookupBoxedProcess)) { PhAppendFormatStringBuilder(getTooltipText->StringBuilder, L"Sandboxie:\n Box name: %s\n", boxedProcess->BoxName); } PhReleaseQueuedLockShared(&BoxedProcessesLock); }
VOID NetAdaptersSaveList( VOID ) { PH_STRING_BUILDER stringBuilder; PPH_STRING settingsString; PhInitializeStringBuilder(&stringBuilder, 260); PhAcquireQueuedLockShared(&NetworkAdaptersListLock); for (ULONG i = 0; i < NetworkAdaptersList->Count; i++) { PDV_NETADAPTER_ENTRY entry = PhReferenceObjectSafe(NetworkAdaptersList->Items[i]); if (!entry) continue; if (entry->UserReference) { PhAppendFormatStringBuilder( &stringBuilder, L"%lu,%I64u,%s,", entry->AdapterId.InterfaceIndex, // This value is UNSAFE and will change after reboot. entry->AdapterId.InterfaceLuid.Value, // This value is SAFE and does not change (Vista+). entry->AdapterId.InterfaceGuid->Buffer ); } PhDereferenceObjectDeferDelete(entry); } PhReleaseQueuedLockShared(&NetworkAdaptersListLock); if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder)); PhSetStringSetting2(SETTING_NAME_INTERFACE_LIST, &settingsString->sr); }
PPH_STRING PhGetDiagnosticsString( VOID ) { PH_STRING_BUILDER stringBuilder; PhInitializeStringBuilder(&stringBuilder, 50); PhAppendFormatStringBuilder(&stringBuilder, L"OBJECT INFORMATION\r\n"); #define OBJECT_TYPE_COUNT(Type) PhAppendFormatStringBuilder(&stringBuilder, \ L#Type L": %u objects\r\n", PhpGetObjectTypeObjectCount(Type)) // ref OBJECT_TYPE_COUNT(PhObjectTypeObject); // basesup OBJECT_TYPE_COUNT(PhStringType); OBJECT_TYPE_COUNT(PhBytesType); OBJECT_TYPE_COUNT(PhListType); OBJECT_TYPE_COUNT(PhPointerListType); OBJECT_TYPE_COUNT(PhHashtableType); OBJECT_TYPE_COUNT(PhFileStreamType); // ph OBJECT_TYPE_COUNT(PhSymbolProviderType); OBJECT_TYPE_COUNT(PhProcessItemType); OBJECT_TYPE_COUNT(PhServiceItemType); OBJECT_TYPE_COUNT(PhNetworkItemType); OBJECT_TYPE_COUNT(PhModuleProviderType); OBJECT_TYPE_COUNT(PhModuleItemType); OBJECT_TYPE_COUNT(PhThreadProviderType); OBJECT_TYPE_COUNT(PhThreadItemType); OBJECT_TYPE_COUNT(PhHandleProviderType); OBJECT_TYPE_COUNT(PhHandleItemType); OBJECT_TYPE_COUNT(PhMemoryItemType); return PhFinalStringBuilderString(&stringBuilder); }
VOID DiskDrivesSaveList( VOID ) { PH_STRING_BUILDER stringBuilder; PPH_STRING settingsString; PhInitializeStringBuilder(&stringBuilder, 260); PhAcquireQueuedLockShared(&DiskDrivesListLock); for (ULONG i = 0; i < DiskDrivesList->Count; i++) { PDV_DISK_ENTRY entry = PhReferenceObjectSafe(DiskDrivesList->Items[i]); if (!entry) continue; if (entry->UserReference) { PhAppendFormatStringBuilder( &stringBuilder, L"%s,", entry->Id.DevicePath->Buffer // This value is SAFE and does not change. ); } PhDereferenceObjectDeferDelete(entry); } PhReleaseQueuedLockShared(&DiskDrivesListLock); if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); settingsString = PH_AUTO(PhFinalStringBuilderString(&stringBuilder)); PhSetStringSetting2(SETTING_NAME_DISK_LIST, &settingsString->sr); }
/** * Loads plugins from the default plugins directory. */ VOID PhLoadPlugins( VOID ) { HANDLE pluginsDirectoryHandle; PPH_STRING pluginsDirectory; pluginsDirectory = PhGetStringSetting(L"PluginsDirectory"); if (RtlDetermineDosPathNameType_U(pluginsDirectory->Buffer) == RtlPathTypeRelative) { // Not absolute. Make sure it is. PluginsDirectory = PhConcatStrings(4, PhApplicationDirectory->Buffer, L"\\", pluginsDirectory->Buffer, L"\\"); PhDereferenceObject(pluginsDirectory); } else { PluginsDirectory = pluginsDirectory; } if (NT_SUCCESS(PhCreateFileWin32( &pluginsDirectoryHandle, PluginsDirectory->Buffer, FILE_GENERIC_READ, 0, FILE_SHARE_READ, FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ))) { UNICODE_STRING pattern = RTL_CONSTANT_STRING(L"*.dll"); PhEnumDirectoryFile(pluginsDirectoryHandle, &pattern, EnumPluginsDirectoryCallback, NULL); NtClose(pluginsDirectoryHandle); } // Handle load errors. // In certain startup modes we want to ignore all plugin load errors. if (LoadErrors && LoadErrors->Count != 0 && !PhStartupParameters.PhSvc) { PH_STRING_BUILDER sb; ULONG i; PPHP_PLUGIN_LOAD_ERROR loadError; PPH_STRING baseName; PhInitializeStringBuilder(&sb, 100); PhAppendStringBuilder2(&sb, L"Unable to load the following plugin(s):\n\n"); for (i = 0; i < LoadErrors->Count; i++) { loadError = LoadErrors->Items[i]; baseName = PhGetBaseName(loadError->FileName); PhAppendFormatStringBuilder(&sb, L"%s: %s\n", baseName->Buffer, PhGetStringOrDefault(loadError->ErrorMessage, L"An unknown error occurred.")); PhDereferenceObject(baseName); } PhAppendStringBuilder2(&sb, L"\nDo you want to disable the above plugin(s)?"); if (PhShowMessage( NULL, MB_ICONERROR | MB_YESNO, sb.String->Buffer ) == IDYES) { ULONG i; for (i = 0; i < LoadErrors->Count; i++) { loadError = LoadErrors->Items[i]; baseName = PhGetBaseName(loadError->FileName); PhSetPluginDisabled(&baseName->sr, TRUE); PhDereferenceObject(baseName); } } PhDeleteStringBuilder(&sb); } // When we loaded settings before, we didn't know about plugin settings, so they // went into the ignored settings list. Now that they've had a chance to add // settings, we should scan the ignored settings list and move the settings to // the right places. if (PhSettingsFileName) PhConvertIgnoredSettings(); PhpExecuteCallbackForAllPlugins(PluginCallbackLoad, TRUE); }
static BOOLEAN NTAPI PhpWalkThreadStackAnalyzeCallback( _In_ PPH_THREAD_STACK_FRAME StackFrame, _In_opt_ PVOID Context ) { PANALYZE_WAIT_CONTEXT context = (PANALYZE_WAIT_CONTEXT)Context; PPH_STRING name; name = PhGetSymbolFromAddress( context->SymbolProvider, (ULONG64)StackFrame->PcAddress, NULL, NULL, NULL, NULL ); if (!name) return TRUE; context->Found = TRUE; #define FUNC_MATCH(Name) PhStartsWithString2(name, L##Name, TRUE) #define NT_FUNC_MATCH(Name) ( \ PhStartsWithString2(name, L"ntdll.dll!Nt" L##Name, TRUE) || \ PhStartsWithString2(name, L"ntdll.dll!Zw" L##Name, TRUE) \ ) if (!name) { // Dummy } else if (FUNC_MATCH("kernel32.dll!Sleep")) { PhAppendFormatStringBuilder( &context->StringBuilder, L"Thread is sleeping. Timeout: %lu milliseconds.", PtrToUlong(StackFrame->Params[0]) ); } else if (NT_FUNC_MATCH("DelayExecution")) { BOOLEAN alertable = !!StackFrame->Params[0]; PVOID timeoutAddress = StackFrame->Params[1]; LARGE_INTEGER timeout; if (NT_SUCCESS(NtReadVirtualMemory( context->ProcessHandle, timeoutAddress, &timeout, sizeof(LARGE_INTEGER), NULL ))) { if (timeout.QuadPart < 0) { PhAppendFormatStringBuilder( &context->StringBuilder, L"Thread is sleeping. Timeout: %I64u milliseconds.", -timeout.QuadPart / PH_TIMEOUT_MS ); } else { // TODO } } else { PhAppendStringBuilder2( &context->StringBuilder, L"Thread is sleeping." ); } } else if (NT_FUNC_MATCH("DeviceIoControlFile")) { HANDLE handle = (HANDLE)StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for an I/O control request:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if (NT_FUNC_MATCH("FsControlFile")) { HANDLE handle = StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for a FS control request:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if (NT_FUNC_MATCH("QueryObject")) { HANDLE handle = StackFrame->Params[0]; // Use the KiFastSystemCall args if the handle we have is wrong. if ((ULONG_PTR)handle % 4 != 0 || !handle) handle = context->PrevParams[1]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is querying an object:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if (NT_FUNC_MATCH("ReadFile") || NT_FUNC_MATCH("WriteFile")) { HANDLE handle = StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for file I/O:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if (NT_FUNC_MATCH("RemoveIoCompletion")) { HANDLE handle = StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for an I/O completion port:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if ( NT_FUNC_MATCH("ReplyWaitReceivePort") || NT_FUNC_MATCH("RequestWaitReplyPort") || NT_FUNC_MATCH("AlpcSendWaitReceivePort") ) { HANDLE handle = StackFrame->Params[0]; PPH_STRING alpcInfo; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for an ALPC port:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); if (alpcInfo = PhpaGetAlpcInformation(context->ThreadId)) { PhAppendStringBuilder2( &context->StringBuilder, L"\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &alpcInfo->sr ); } } else if ( NT_FUNC_MATCH("SetHighWaitLowEventPair") || NT_FUNC_MATCH("SetLowWaitHighEventPair") || NT_FUNC_MATCH("WaitHighEventPair") || NT_FUNC_MATCH("WaitLowEventPair") ) { HANDLE handle = StackFrame->Params[0]; if ((ULONG_PTR)handle % 4 != 0 || !handle) handle = context->PrevParams[1]; PhAppendFormatStringBuilder( &context->StringBuilder, L"Thread is waiting (%s) for an event pair:\r\n", name->Buffer ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if ( FUNC_MATCH("user32.dll!NtUserGetMessage") || FUNC_MATCH("user32.dll!NtUserWaitMessage") ) { PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for a USER message.\r\n" ); } else if (FUNC_MATCH("user32.dll!NtUserMessageCall")) { PPH_STRING receiverString; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is sending a USER message:\r\n" ); receiverString = PhpaGetSendMessageReceiver(context->ThreadId); if (receiverString) { PhAppendStringBuilder(&context->StringBuilder, &receiverString->sr); PhAppendStringBuilder2(&context->StringBuilder, L"\r\n"); } else { PhAppendStringBuilder2(&context->StringBuilder, L"Unknown.\r\n"); } } else if (NT_FUNC_MATCH("WaitForDebugEvent")) { HANDLE handle = StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for a debug event:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if ( NT_FUNC_MATCH("WaitForKeyedEvent") || NT_FUNC_MATCH("ReleaseKeyedEvent") ) { HANDLE handle = StackFrame->Params[0]; PVOID key = StackFrame->Params[1]; PhAppendFormatStringBuilder( &context->StringBuilder, L"Thread is waiting (%s) for a keyed event (key 0x%Ix):\r\n", name->Buffer, key ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if ( NT_FUNC_MATCH("WaitForMultipleObjects") || FUNC_MATCH("kernel32.dll!WaitForMultipleObjects") ) { ULONG numberOfHandles = PtrToUlong(StackFrame->Params[0]); PVOID addressOfHandles = StackFrame->Params[1]; WAIT_TYPE waitType = (WAIT_TYPE)StackFrame->Params[2]; BOOLEAN alertable = !!StackFrame->Params[3]; if (numberOfHandles > MAXIMUM_WAIT_OBJECTS) { numberOfHandles = PtrToUlong(context->PrevParams[1]); addressOfHandles = context->PrevParams[2]; waitType = (WAIT_TYPE)context->PrevParams[3]; alertable = FALSE; } PhpGetWfmoInformation( context->ProcessHandle, TRUE, // on x64 this function is only called for WOW64 processes numberOfHandles, addressOfHandles, waitType, alertable, &context->StringBuilder ); } else if ( NT_FUNC_MATCH("WaitForSingleObject") || FUNC_MATCH("kernel32.dll!WaitForSingleObject") ) { HANDLE handle = StackFrame->Params[0]; BOOLEAN alertable = !!StackFrame->Params[1]; if ((ULONG_PTR)handle % 4 != 0 || !handle) { handle = context->PrevParams[1]; alertable = !!context->PrevParams[2]; } PhAppendFormatStringBuilder( &context->StringBuilder, L"Thread is waiting (%s) for:\r\n", alertable ? L"alertable" : L"non-alertable" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else if (NT_FUNC_MATCH("WaitForWorkViaWorkerFactory")) { HANDLE handle = StackFrame->Params[0]; PhAppendStringBuilder2( &context->StringBuilder, L"Thread is waiting for work from a worker factory:\r\n" ); PhAppendStringBuilder( &context->StringBuilder, &PhpaGetHandleString(context->ProcessHandle, handle)->sr ); } else { context->Found = FALSE; } PhDereferenceObject(name); memcpy(&context->PrevParams, StackFrame->Params, sizeof(StackFrame->Params)); return !context->Found; }
static INT_PTR CALLBACK NetworkOutputDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PNETWORK_OUTPUT_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PNETWORK_OUTPUT_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PNETWORK_OUTPUT_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) { PhSaveWindowPlacementToSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); PhDeleteLayoutManager(&context->LayoutManager); if (context->ProcessHandle) { // Terminate the child process. PhTerminateProcess(context->ProcessHandle, STATUS_SUCCESS); // Close the child process handle. NtClose(context->ProcessHandle); } // Close the pipe handle. if (context->PipeReadHandle) NtClose(context->PipeReadHandle); RemoveProp(hwndDlg, L"Context"); PhFree(context); } } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { PH_RECTANGLE windowRectangle; context->WindowHandle = hwndDlg; context->OutputHandle = GetDlgItem(hwndDlg, IDC_NETOUTPUTEDIT); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, context->OutputHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_MORE_INFO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_RIGHT); windowRectangle.Position = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_POSITION); windowRectangle.Size = PhGetIntegerPairSetting(SETTING_NAME_TRACERT_WINDOW_SIZE); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 190; rect.bottom = 120; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } // Check for first-run default position. if (windowRectangle.Position.X == 0 || windowRectangle.Position.Y == 0) { PhCenterWindow(hwndDlg, GetParent(hwndDlg)); } else { PhLoadWindowPlacementFromSetting(SETTING_NAME_TRACERT_WINDOW_POSITION, SETTING_NAME_TRACERT_WINDOW_SIZE, hwndDlg); } if (context->IpAddress.Type == PH_IPV4_NETWORK_TYPE) { RtlIpv4AddressToString(&context->IpAddress.InAddr, context->IpAddressString); } else { RtlIpv6AddressToString(&context->IpAddress.In6Addr, context->IpAddressString); } switch (context->Action) { case NETWORK_ACTION_TRACEROUTE: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Tracing route to %s...", context->IpAddressString)->Buffer ); if (dialogThread = PhCreateThread(0, NetworkTracertThreadStart, (PVOID)context)) NtClose(dialogThread); } break; case NETWORK_ACTION_WHOIS: { HANDLE dialogThread = INVALID_HANDLE_VALUE; Static_SetText(context->WindowHandle, PhaFormatString(L"Whois %s...", context->IpAddressString)->Buffer ); ShowWindow(GetDlgItem(hwndDlg, IDC_MORE_INFO), SW_SHOW); if (dialogThread = PhCreateThread(0, NetworkWhoisThreadStart, (PVOID)context)) NtClose(dialogThread); } break; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: PostQuitMessage(0); break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_SIZING: PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); break; case WM_CTLCOLORDLG: case WM_CTLCOLORSTATIC: { HDC hDC = (HDC)wParam; HWND hwndChild = (HWND)lParam; // Check if old graph colors are enabled. if (!PhGetIntegerSetting(L"GraphColorMode")) break; // Set a transparent background for the control backcolor. SetBkMode(hDC, TRANSPARENT); // Check for our edit control and change the color. if (hwndChild == context->OutputHandle) { // Set text color as the Green PH graph text color. SetTextColor(hDC, RGB(124, 252, 0)); // Set a black control backcolor. return (INT_PTR)GetStockBrush(BLACK_BRUSH); } } break; case WM_NOTIFY: { switch (((LPNMHDR)lParam)->code) { case NM_CLICK: case NM_RETURN: { PNMLINK syslink = (PNMLINK)lParam; if (syslink->hdr.idFrom == IDC_MORE_INFO) { PhShellExecute( PhMainWndHandle, PhaConcatStrings2(L"http://wq.apnic.net/apnic-bin/whois.pl?searchtext=", context->IpAddressString)->Buffer, NULL ); } } break; } } break; case NTM_RECEIVEDTRACE: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (wParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { PPH_STRING windowText = NULL; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Get the current output text. windowText = PhGetWindowText(context->OutputHandle); // Append the current output text to the New string. if (!PhIsNullOrEmptyString(windowText)) PhAppendStringBuilder(&receivedString, &windowText->sr); PhAppendFormatStringBuilder(&receivedString, L"%s", convertedString.Buffer); // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_BOTTOM, 0); PhDereferenceObject(windowText); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } } } break; case NTM_RECEIVEDWHOIS: { OEM_STRING inputString; UNICODE_STRING convertedString; PH_STRING_BUILDER receivedString; if (lParam != 0) { inputString.Buffer = (PCHAR)lParam; inputString.Length = (USHORT)wParam; if (NT_SUCCESS(RtlOemStringToUnicodeString(&convertedString, &inputString, TRUE))) { USHORT i; PhInitializeStringBuilder(&receivedString, PAGE_SIZE); // Convert carriage returns. for (i = 0; i < convertedString.Length; i++) { if (convertedString.Buffer[i] == '\n') { PhAppendStringBuilder2(&receivedString, L"\r\n"); } else { PhAppendCharStringBuilder(&receivedString, convertedString.Buffer[i]); } } // Remove leading newlines. if (receivedString.String->Length >= 2 * 2 && receivedString.String->Buffer[0] == '\r' && receivedString.String->Buffer[1] == '\n') { PhRemoveStringBuilder(&receivedString, 0, 2); } SetWindowText(context->OutputHandle, receivedString.String->Buffer); SendMessage( context->OutputHandle, EM_SETSEL, receivedString.String->Length / 2 - 1, receivedString.String->Length / 2 - 1 ); SendMessage(context->OutputHandle, WM_VSCROLL, SB_TOP, 0); PhDeleteStringBuilder(&receivedString); RtlFreeUnicodeString(&convertedString); } PhFree((PVOID)lParam); } } break; case NTM_RECEIVEDFINISH: { PPH_STRING windowText = PhGetWindowText(context->WindowHandle); if (windowText) { Static_SetText( context->WindowHandle, PhaFormatString(L"%s Finished.", windowText->Buffer)->Buffer ); PhDereferenceObject(windowText); } } break; } return FALSE; }
PPH_STRING PhGetProcessTooltipText( _In_ PPH_PROCESS_ITEM Process, _Out_opt_ PULONG ValidToTickCount ) { PH_STRING_BUILDER stringBuilder; ULONG validForMs = 60 * 60 * 1000; // 1 hour PPH_STRING tempString; PH_KNOWN_PROCESS_TYPE knownProcessType = UnknownProcessType; PhInitializeStringBuilder(&stringBuilder, 200); // Command line if (Process->CommandLine) { tempString = PhEllipsisString(Process->CommandLine, 100 * 10); // This is necessary because the tooltip control seems to use some kind of O(n^9999) word-wrapping // algorithm. PhpAppendStringWithLineBreaks(&stringBuilder, &tempString->sr, 100, NULL); PhAppendCharStringBuilder(&stringBuilder, '\n'); PhDereferenceObject(tempString); } // File information tempString = PhFormatImageVersionInfo( Process->FileName, &Process->VersionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); // Known command line information if (Process->QueryHandle) PhGetProcessKnownType(Process->QueryHandle, &knownProcessType); if (Process->CommandLine && Process->QueryHandle) { PH_KNOWN_PROCESS_COMMAND_LINE knownCommandLine; if (knownProcessType != UnknownProcessType && PhaGetProcessKnownCommandLine( Process->CommandLine, knownProcessType, &knownCommandLine )) { switch (knownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: PhAppendStringBuilder2(&stringBuilder, L"Service group name:\n "); PhAppendStringBuilder(&stringBuilder, &knownCommandLine.ServiceHost.GroupName->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); break; case RunDllAsAppProcessType: { PH_IMAGE_VERSION_INFO versionInfo; if (PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.RunDllAsApp.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.RunDllAsApp.FileName, &versionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"Run DLL target file:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; case ComSurrogateProcessType: { PH_IMAGE_VERSION_INFO versionInfo; PPH_STRING guidString; PhAppendStringBuilder2(&stringBuilder, L"COM target:\n"); if (knownCommandLine.ComSurrogate.Name) { PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &knownCommandLine.ComSurrogate.Name->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (guidString = PhFormatGuid(&knownCommandLine.ComSurrogate.Guid)) { PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &guidString->sr); PhDereferenceObject(guidString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (knownCommandLine.ComSurrogate.FileName && PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.ComSurrogate.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.ComSurrogate.FileName, &versionInfo, &StandardIndent, 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"COM target file:\n"); PhAppendStringBuilder(&stringBuilder, &tempString->sr); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; } } } // Services if (Process->ServiceList && Process->ServiceList->Count != 0) { ULONG enumerationKey = 0; PPH_SERVICE_ITEM serviceItem; PPH_LIST serviceList; ULONG i; // Copy the service list into our own list so we can sort it. serviceList = PhCreateList(Process->ServiceList->Count); PhAcquireQueuedLockShared(&Process->ServiceListLock); while (PhEnumPointerList( Process->ServiceList, &enumerationKey, &serviceItem )) { PhReferenceObject(serviceItem); PhAddItemList(serviceList, serviceItem); } PhReleaseQueuedLockShared(&Process->ServiceListLock); qsort(serviceList->Items, serviceList->Count, sizeof(PPH_SERVICE_ITEM), ServiceForTooltipCompare); PhAppendStringBuilder2(&stringBuilder, L"Services:\n"); // Add the services. for (i = 0; i < serviceList->Count; i++) { serviceItem = serviceList->Items[i]; PhAppendStringBuilder(&stringBuilder, &StandardIndent); PhAppendStringBuilder(&stringBuilder, &serviceItem->Name->sr); PhAppendStringBuilder2(&stringBuilder, L" ("); PhAppendStringBuilder(&stringBuilder, &serviceItem->DisplayName->sr); PhAppendStringBuilder2(&stringBuilder, L")\n"); } PhDereferenceObjects(serviceList->Items, serviceList->Count); PhDereferenceObject(serviceList); } // Tasks, Drivers switch (knownProcessType & KnownProcessTypeMask) { case TaskHostProcessType: { PH_STRING_BUILDER tasks; PhInitializeStringBuilder(&tasks, 40); PhpFillRunningTasks(Process, &tasks); if (tasks.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Tasks:\n"); PhAppendStringBuilder(&stringBuilder, &tasks.String->sr); } PhDeleteStringBuilder(&tasks); } break; case UmdfHostProcessType: { PH_STRING_BUILDER drivers; PhInitializeStringBuilder(&drivers, 40); PhpFillUmdfDrivers(Process, &drivers); if (drivers.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Drivers:\n"); PhAppendStringBuilder(&stringBuilder, &drivers.String->sr); } PhDeleteStringBuilder(&drivers); validForMs = 10 * 1000; // 10 seconds } break; } // Plugin if (PhPluginsEnabled) { PH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText; getTooltipText.Parameter = Process; getTooltipText.StringBuilder = &stringBuilder; getTooltipText.ValidForMs = validForMs; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackGetProcessTooltipText), &getTooltipText); validForMs = getTooltipText.ValidForMs; } // Notes { PH_STRING_BUILDER notes; PhInitializeStringBuilder(¬es, 40); if (Process->FileName) { if (Process->VerifyResult == VrTrusted) { if (!PhIsNullOrEmptyString(Process->VerifySignerName)) PhAppendFormatStringBuilder(¬es, L" Signer: %s\n", Process->VerifySignerName->Buffer); else PhAppendStringBuilder2(¬es, L" Signed.\n"); } else if (Process->VerifyResult == VrUnknown) { // Nothing } else if (Process->VerifyResult != VrNoSignature) { PhAppendStringBuilder2(¬es, L" Signature invalid.\n"); } } if (Process->IsPacked) { PhAppendFormatStringBuilder( ¬es, L" Image is probably packed (%u imports over %u modules).\n", Process->ImportFunctions, Process->ImportModules ); } if ((ULONG_PTR)Process->ConsoleHostProcessId & ~3) { CLIENT_ID clientId; PWSTR description = L"Console host"; PPH_STRING clientIdString; clientId.UniqueProcess = (HANDLE)((ULONG_PTR)Process->ConsoleHostProcessId & ~3); clientId.UniqueThread = NULL; if ((ULONG_PTR)Process->ConsoleHostProcessId & 2) description = L"Console application"; clientIdString = PhGetClientIdName(&clientId); PhAppendFormatStringBuilder(¬es, L" %s: %s\n", description, clientIdString->Buffer); PhDereferenceObject(clientIdString); } if (Process->PackageFullName) { PhAppendFormatStringBuilder(¬es, L" Package name: %s\n", Process->PackageFullName->Buffer); } if (Process->IsDotNet) PhAppendStringBuilder2(¬es, L" Process is managed (.NET).\n"); if (Process->IsElevated) PhAppendStringBuilder2(¬es, L" Process is elevated.\n"); if (Process->IsImmersive) PhAppendStringBuilder2(¬es, L" Process is a Modern UI app.\n"); if (Process->IsInJob) PhAppendStringBuilder2(¬es, L" Process is in a job.\n"); if (Process->IsPosix) PhAppendStringBuilder2(¬es, L" Process is POSIX.\n"); if (Process->IsWow64) PhAppendStringBuilder2(¬es, L" Process is 32-bit (WOW64).\n"); if (notes.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Notes:\n"); PhAppendStringBuilder(&stringBuilder, ¬es.String->sr); } PhDeleteStringBuilder(¬es); } if (ValidToTickCount) *ValidToTickCount = GetTickCount() + validForMs; // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); return PhFinalStringBuilderString(&stringBuilder); }
static INT_PTR CALLBACK PhpThreadStackDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; PTHREAD_STACK_CONTEXT threadStackContext; PPH_STRING title; HWND lvHandle; PPH_LAYOUT_MANAGER layoutManager; threadStackContext = (PTHREAD_STACK_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)threadStackContext); title = PhFormatString(L"Stack - thread %u", (ULONG)threadStackContext->ThreadId); SetWindowText(hwndDlg, title->Buffer); PhDereferenceObject(title); lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 30, L" "); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 300, L"Name"); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhLoadListViewColumnsFromSetting(L"ThreadStackListViewColumns", lvHandle); threadStackContext->ListViewHandle = lvHandle; layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER)); PhInitializeLayoutManager(layoutManager, hwndDlg); SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager); PhAddLayoutItem(layoutManager, lvHandle, NULL, PH_ANCHOR_ALL); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_COPY), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_REFRESH), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 190; rect.bottom = 120; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } PhLoadWindowPlacementFromSetting(NULL, L"ThreadStackWindowSize", hwndDlg); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); if (PhPluginsEnabled) { PH_PLUGIN_THREAD_STACK_CONTROL control; control.Type = PluginThreadStackInitializing; control.UniqueKey = threadStackContext; control.u.Initializing.ProcessId = threadStackContext->ProcessId; control.u.Initializing.ThreadId = threadStackContext->ThreadId; control.u.Initializing.ThreadHandle = threadStackContext->ThreadHandle; control.u.Initializing.SymbolProvider = threadStackContext->SymbolProvider; control.u.Initializing.CustomWalk = FALSE; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control); threadStackContext->CustomWalk = control.u.Initializing.CustomWalk; } status = PhpRefreshThreadStack(hwndDlg, threadStackContext); if (status == STATUS_ABANDONED) EndDialog(hwndDlg, IDCANCEL); else if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to load the stack", status, 0); } break; case WM_DESTROY: { PPH_LAYOUT_MANAGER layoutManager; PTHREAD_STACK_CONTEXT threadStackContext; ULONG i; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhDeleteLayoutManager(layoutManager); PhFree(layoutManager); threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); if (PhPluginsEnabled) { PH_PLUGIN_THREAD_STACK_CONTROL control; control.Type = PluginThreadStackUninitializing; control.UniqueKey = threadStackContext; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control); } for (i = 0; i < threadStackContext->List->Count; i++) PhpFreeThreadStackItem(threadStackContext->List->Items[i]); PhSaveListViewColumnsToSetting(L"ThreadStackListViewColumns", GetDlgItem(hwndDlg, IDC_LIST)); PhSaveWindowPlacementToSetting(NULL, L"ThreadStackWindowSize", hwndDlg); RemoveProp(hwndDlg, PhMakeContextAtom()); RemoveProp(hwndDlg, L"LayoutManager"); } break; case WM_COMMAND: { INT id = LOWORD(wParam); switch (id) { case IDCANCEL: // Esc and X button to close case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_REFRESH: { NTSTATUS status; if (!NT_SUCCESS(status = PhpRefreshThreadStack( hwndDlg, (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()) ))) { PhShowStatus(hwndDlg, L"Unable to load the stack", status, 0); } } break; case IDC_COPY: { HWND lvHandle; lvHandle = GetDlgItem(hwndDlg, IDC_LIST); if (ListView_GetSelectedCount(lvHandle) == 0) PhSetStateAllListViewItems(lvHandle, LVIS_SELECTED, LVIS_SELECTED); PhCopyListView(lvHandle); SetFocus(lvHandle); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case LVN_GETINFOTIP: { LPNMLVGETINFOTIP getInfoTip = (LPNMLVGETINFOTIP)header; HWND lvHandle; PTHREAD_STACK_CONTEXT threadStackContext; lvHandle = GetDlgItem(hwndDlg, IDC_LIST); threadStackContext = (PTHREAD_STACK_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); if (header->hwndFrom == lvHandle) { PTHREAD_STACK_ITEM stackItem; PPH_THREAD_STACK_FRAME stackFrame; if (PhGetListViewItemParam(lvHandle, getInfoTip->iItem, &stackItem)) { PH_STRING_BUILDER stringBuilder; PPH_STRING fileName; PH_SYMBOL_LINE_INFORMATION lineInfo; stackFrame = &stackItem->StackFrame; PhInitializeStringBuilder(&stringBuilder, 40); // There are no params for kernel-mode stack traces. if ((ULONG_PTR)stackFrame->PcAddress <= PhSystemBasicInformation.MaximumUserModeAddress) { PhAppendFormatStringBuilder( &stringBuilder, L"Parameters: 0x%Ix, 0x%Ix, 0x%Ix, 0x%Ix\n", stackFrame->Params[0], stackFrame->Params[1], stackFrame->Params[2], stackFrame->Params[3] ); } if (PhGetLineFromAddress( threadStackContext->SymbolProvider, (ULONG64)stackFrame->PcAddress, &fileName, NULL, &lineInfo )) { PhAppendFormatStringBuilder( &stringBuilder, L"File: %s: line %u\n", fileName->Buffer, lineInfo.LineNumber ); PhDereferenceObject(fileName); } if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); if (PhPluginsEnabled) { PH_PLUGIN_THREAD_STACK_CONTROL control; control.Type = PluginThreadStackGetTooltip; control.UniqueKey = threadStackContext; control.u.GetTooltip.StackFrame = stackFrame; control.u.GetTooltip.StringBuilder = &stringBuilder; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackThreadStackControl), &control); } PhCopyListViewInfoTip(getInfoTip, &stringBuilder.String->sr); PhDeleteStringBuilder(&stringBuilder); } } } break; } } break; case WM_SIZE: { PPH_LAYOUT_MANAGER layoutManager; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhLayoutManagerLayout(layoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; } return FALSE; }
PPH_STRING PhCmSaveSettingsEx( _In_ HWND TreeNewHandle, _In_opt_ PPH_CM_MANAGER Manager, _In_ ULONG Flags, _Out_opt_ PPH_STRING *SortSettings ) { PH_STRING_BUILDER stringBuilder; ULONG i = 0; ULONG count = 0; ULONG total; ULONG increment; PH_TREENEW_COLUMN column; total = TreeNew_GetColumnCount(TreeNewHandle); if (TreeNew_GetFixedColumn(TreeNewHandle)) increment = 1; // the first normal column should have a display index that starts with 1, for compatibility else increment = 0; PhInitializeStringBuilder(&stringBuilder, 100); while (count < total) { if (TreeNew_GetColumn(TreeNewHandle, i, &column)) { if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY)) { if (column.Visible) { if (!Manager || i < Manager->MinId) { PhAppendFormatStringBuilder( &stringBuilder, L"%u,%u,%u|", i, column.Fixed ? 0 : column.DisplayIndex + increment, column.Width ); } else { PPH_CM_COLUMN cmColumn; cmColumn = column.Context; PhAppendFormatStringBuilder( &stringBuilder, L"+%s+%u,%u,%u|", cmColumn->Plugin->Name.Buffer, cmColumn->SubId, column.DisplayIndex + increment, column.Width ); } } } else { if (!Manager || i < Manager->MinId) { PhAppendFormatStringBuilder( &stringBuilder, L"%u,,%u|", i, column.Width ); } else { PPH_CM_COLUMN cmColumn; cmColumn = column.Context; PhAppendFormatStringBuilder( &stringBuilder, L"+%s+%u,,%u|", cmColumn->Plugin->Name.Buffer, cmColumn->SubId, column.Width ); } } count++; } i++; } if (stringBuilder.String->Length != 0) PhRemoveEndStringBuilder(&stringBuilder, 1); if (SortSettings) { ULONG sortColumn; PH_SORT_ORDER sortOrder; if (TreeNew_GetSort(TreeNewHandle, &sortColumn, &sortOrder)) { if (sortOrder != NoSortOrder) { if (!Manager || sortColumn < Manager->MinId) { *SortSettings = PhFormatString(L"%u,%u", sortColumn, sortOrder); } else { PH_TREENEW_COLUMN column; PPH_CM_COLUMN cmColumn; if (TreeNew_GetColumn(TreeNewHandle, sortColumn, &column)) { cmColumn = column.Context; *SortSettings = PhFormatString(L"+%s+%u,%u", cmColumn->Plugin->Name.Buffer, cmColumn->SubId, sortOrder); } else { *SortSettings = PhReferenceEmptyString(); } } } else { *SortSettings = PhCreateString(L"0,0"); } } else { *SortSettings = PhReferenceEmptyString(); } } return PhFinalStringBuilderString(&stringBuilder); }
PPH_STRING PhGetProcessTooltipText( __in PPH_PROCESS_ITEM Process ) { PH_STRING_BUILDER stringBuilder; PPH_STRING tempString; PhInitializeStringBuilder(&stringBuilder, 200); // Command line if (Process->CommandLine) { PhAppendStringBuilder(&stringBuilder, Process->CommandLine); PhAppendCharStringBuilder(&stringBuilder, '\n'); } // File information tempString = PhFormatImageVersionInfo( Process->FileName, &Process->VersionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"File:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); // Known command line information if (Process->CommandLine && Process->QueryHandle) { PH_KNOWN_PROCESS_TYPE knownProcessType; PH_KNOWN_PROCESS_COMMAND_LINE knownCommandLine; if (NT_SUCCESS(PhGetProcessKnownType( Process->QueryHandle, &knownProcessType )) && PhaGetProcessKnownCommandLine( Process->CommandLine, knownProcessType, &knownCommandLine )) { switch (knownProcessType & KnownProcessTypeMask) { case ServiceHostProcessType: PhAppendStringBuilder2(&stringBuilder, L"Service group name:\n "); PhAppendStringBuilder(&stringBuilder, knownCommandLine.ServiceHost.GroupName); PhAppendCharStringBuilder(&stringBuilder, '\n'); break; case RunDllAsAppProcessType: { PH_IMAGE_VERSION_INFO versionInfo; if (PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.RunDllAsApp.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.RunDllAsApp.FileName, &versionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"Run DLL target file:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; case ComSurrogateProcessType: { PH_IMAGE_VERSION_INFO versionInfo; PPH_STRING guidString; PhAppendStringBuilder2(&stringBuilder, L"COM target:\n"); if (knownCommandLine.ComSurrogate.Name) { PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, knownCommandLine.ComSurrogate.Name); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (guidString = PhFormatGuid(&knownCommandLine.ComSurrogate.Guid)) { PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, guidString); PhDereferenceObject(guidString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (knownCommandLine.ComSurrogate.FileName && PhInitializeImageVersionInfo( &versionInfo, knownCommandLine.ComSurrogate.FileName->Buffer )) { tempString = PhFormatImageVersionInfo( knownCommandLine.ComSurrogate.FileName, &versionInfo, L" ", 0 ); if (!PhIsNullOrEmptyString(tempString)) { PhAppendStringBuilder2(&stringBuilder, L"COM target file:\n"); PhAppendStringBuilder(&stringBuilder, tempString); PhAppendCharStringBuilder(&stringBuilder, '\n'); } if (tempString) PhDereferenceObject(tempString); PhDeleteImageVersionInfo(&versionInfo); } } break; } } } // Services if (Process->ServiceList && Process->ServiceList->Count != 0) { ULONG enumerationKey = 0; PPH_SERVICE_ITEM serviceItem; PPH_LIST serviceList; ULONG i; // Copy the service list into our own list so we can sort it. serviceList = PhCreateList(Process->ServiceList->Count); PhAcquireQueuedLockShared(&Process->ServiceListLock); while (PhEnumPointerList( Process->ServiceList, &enumerationKey, &serviceItem )) { PhReferenceObject(serviceItem); PhAddItemList(serviceList, serviceItem); } PhReleaseQueuedLockShared(&Process->ServiceListLock); qsort(serviceList->Items, serviceList->Count, sizeof(PPH_SERVICE_ITEM), ServiceForTooltipCompare); PhAppendStringBuilder2(&stringBuilder, L"Services:\n"); // Add the services. for (i = 0; i < serviceList->Count; i++) { serviceItem = serviceList->Items[i]; PhAppendStringBuilder2(&stringBuilder, L" "); PhAppendStringBuilder(&stringBuilder, serviceItem->Name); PhAppendStringBuilder2(&stringBuilder, L" ("); PhAppendStringBuilder(&stringBuilder, serviceItem->DisplayName); PhAppendStringBuilder2(&stringBuilder, L")\n"); } PhDereferenceObjects(serviceList->Items, serviceList->Count); PhDereferenceObject(serviceList); } // Tasks if (PhEqualString2(Process->ProcessName, L"taskeng.exe", TRUE) || PhEqualString2(Process->ProcessName, L"taskhost.exe", TRUE)) { PH_STRING_BUILDER tasks; PhInitializeStringBuilder(&tasks, 40); PhpFillRunningTasks(Process, &tasks); if (tasks.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Tasks:\n"); PhAppendStringBuilder(&stringBuilder, tasks.String); } PhDeleteStringBuilder(&tasks); } // Plugin if (PhPluginsEnabled) { PH_PLUGIN_GET_TOOLTIP_TEXT getTooltipText; getTooltipText.Parameter = Process; getTooltipText.StringBuilder = &stringBuilder; PhInvokeCallback(PhGetGeneralCallback(GeneralCallbackGetProcessTooltipText), &getTooltipText); } // Notes { PH_STRING_BUILDER notes; PhInitializeStringBuilder(¬es, 40); if (Process->FileName) { if (Process->VerifyResult == VrTrusted) { if (!PhIsNullOrEmptyString(Process->VerifySignerName)) PhAppendFormatStringBuilder(¬es, L" Signer: %s\n", Process->VerifySignerName->Buffer); else PhAppendStringBuilder2(¬es, L" Signed.\n"); } else if (Process->VerifyResult == VrUnknown) { // Nothing } else if (Process->VerifyResult != VrNoSignature) { PhAppendStringBuilder2(¬es, L" Signature invalid.\n"); } } if (Process->IsPacked) { PhAppendFormatStringBuilder( ¬es, L" Image is probably packed (%u imports over %u modules).\n", Process->ImportFunctions, Process->ImportModules ); } if (Process->ConsoleHostProcessId) { CLIENT_ID clientId; PPH_STRING clientIdString; clientId.UniqueProcess = Process->ConsoleHostProcessId; clientId.UniqueThread = NULL; clientIdString = PhGetClientIdName(&clientId); PhAppendFormatStringBuilder(¬es, L" Console host: %s\n", clientIdString->Buffer); PhDereferenceObject(clientIdString); } if (Process->IsDotNet) PhAppendStringBuilder2(¬es, L" Process is managed (.NET).\n"); if (Process->IsElevated) PhAppendStringBuilder2(¬es, L" Process is elevated.\n"); if (Process->IsInJob) PhAppendStringBuilder2(¬es, L" Process is in a job.\n"); if (Process->IsPosix) PhAppendStringBuilder2(¬es, L" Process is POSIX.\n"); if (Process->IsWow64) PhAppendStringBuilder2(¬es, L" Process is 32-bit (WOW64).\n"); if (notes.String->Length != 0) { PhAppendStringBuilder2(&stringBuilder, L"Notes:\n"); PhAppendStringBuilder(&stringBuilder, notes.String); } PhDeleteStringBuilder(¬es); } // Remove the trailing newline. if (stringBuilder.String->Length != 0) PhRemoveStringBuilder(&stringBuilder, stringBuilder.String->Length / 2 - 1, 1); return PhFinalStringBuilderString(&stringBuilder); }
static VOID PhpGetWfmoInformation( _In_ HANDLE ProcessHandle, _In_ BOOLEAN IsWow64, _In_ ULONG NumberOfHandles, _In_ PHANDLE AddressOfHandles, _In_ WAIT_TYPE WaitType, _In_ BOOLEAN Alertable, _Inout_ PPH_STRING_BUILDER StringBuilder ) { NTSTATUS status; HANDLE handles[MAXIMUM_WAIT_OBJECTS]; ULONG i; status = STATUS_SUCCESS; if (NumberOfHandles <= MAXIMUM_WAIT_OBJECTS) { #ifdef _WIN64 if (IsWow64) { ULONG handles32[MAXIMUM_WAIT_OBJECTS]; if (NT_SUCCESS(status = NtReadVirtualMemory( ProcessHandle, AddressOfHandles, handles32, NumberOfHandles * sizeof(ULONG), NULL ))) { for (i = 0; i < NumberOfHandles; i++) handles[i] = UlongToHandle(handles32[i]); } } else { #endif status = NtReadVirtualMemory( ProcessHandle, AddressOfHandles, handles, NumberOfHandles * sizeof(HANDLE), NULL ); #ifdef _WIN64 } #endif if (NT_SUCCESS(status)) { PhAppendFormatStringBuilder( StringBuilder, L"Thread is waiting (%s, %s) for:\r\n", Alertable ? L"alertable" : L"non-alertable", WaitType == WaitAll ? L"wait all" : L"wait any" ); for (i = 0; i < NumberOfHandles; i++) { PhAppendStringBuilder( StringBuilder, &PhpaGetHandleString(ProcessHandle, handles[i])->sr ); PhAppendStringBuilder2( StringBuilder, L"\r\n" ); } } } if (!NT_SUCCESS(status) || NumberOfHandles > MAXIMUM_WAIT_OBJECTS) { PhAppendStringBuilder2( StringBuilder, L"Thread is waiting for multiple objects." ); } }
VOID PhpAnalyzeWaitPassive( _In_ HWND hWnd, _In_ HANDLE ProcessId, _In_ HANDLE ThreadId ) { NTSTATUS status; HANDLE processHandle; HANDLE threadHandle; THREAD_LAST_SYSCALL_INFORMATION lastSystemCall; PH_STRING_BUILDER stringBuilder; PPH_STRING string; PhpInitializeServiceNumbers(); if (!NT_SUCCESS(status = PhOpenThread(&threadHandle, THREAD_GET_CONTEXT, ThreadId))) { PhShowStatus(hWnd, L"Unable to open the thread.", status, 0); return; } if (!NT_SUCCESS(status = PhGetThreadLastSystemCall(threadHandle, &lastSystemCall))) { NtClose(threadHandle); PhShowStatus(hWnd, L"Unable to determine whether the thread is waiting.", status, 0); return; } if (!NT_SUCCESS(status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE, ProcessId))) { NtClose(threadHandle); PhShowStatus(hWnd, L"Unable to open the process.", status, 0); return; } PhInitializeStringBuilder(&stringBuilder, 100); if (lastSystemCall.SystemCallNumber == NumberForWfso) { string = PhpaGetHandleString(processHandle, lastSystemCall.FirstArgument); PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else if (lastSystemCall.SystemCallNumber == NumberForWfmo) { PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for multiple (%lu) objects.", PtrToUlong(lastSystemCall.FirstArgument)); } else if (lastSystemCall.SystemCallNumber == NumberForRf) { string = PhpaGetHandleString(processHandle, lastSystemCall.FirstArgument); PhAppendFormatStringBuilder(&stringBuilder, L"Thread is waiting for file I/O:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else { string = PhpaGetSendMessageReceiver(ThreadId); if (string) { PhAppendStringBuilder2(&stringBuilder, L"Thread is sending a USER message:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } else { string = PhpaGetAlpcInformation(ThreadId); if (string) { PhAppendStringBuilder2(&stringBuilder, L"Thread is waiting for an ALPC port:\r\n"); PhAppendStringBuilder(&stringBuilder, &string->sr); } } } if (stringBuilder.String->Length == 0) PhAppendStringBuilder2(&stringBuilder, L"Unable to determine why the thread is waiting."); PhShowInformationDialog(hWnd, stringBuilder.String->Buffer, 0); PhDeleteStringBuilder(&stringBuilder); NtClose(processHandle); NtClose(threadHandle); }