HRESULT CALLBACK CheckForUpdatesCallbackProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ LONG_PTR dwRefData ) { PPH_UPDATER_CONTEXT context = (PPH_UPDATER_CONTEXT)dwRefData; switch (uMsg) { case TDN_NAVIGATED: { if (!PhTestEvent(&InitializedEvent)) { // Taskdialog is now initialized PhSetEvent(&InitializedEvent); } } break; case TDN_BUTTON_CLICKED: { if ((INT)wParam == IDOK) { ShowCheckingForUpdatesDialog(hwndDlg, dwRefData); return S_FALSE; } } break; } return S_OK; }
static NTSTATUS WindowThreadStart( __in PVOID Parameter ) { PH_AUTO_POOL autoPool; BOOL result; MSG message; PhInitializeAutoPool(&autoPool); GfxWindowHandle = CreateDialog( PluginInstance->DllBase, MAKEINTRESOURCE(IDD_SYSGFX), NULL, MainWndProc ); PhSetEvent(&InitializedEvent); while (result = GetMessage(&message, NULL, 0, 0)) { if (result == -1) break; if (!IsDialogMessage(GfxWindowHandle, &message)) { TranslateMessage(&message); DispatchMessage(&message); } PhDrainAutoPool(&autoPool); } PhDeleteAutoPool(&autoPool); PhResetEvent(&InitializedEvent); NtClose(GfxThreadHandle); GfxWindowHandle = NULL; GfxPanelWindowHandle = NULL; GfxThreadHandle = NULL; return STATUS_SUCCESS; }
static NTSTATUS ShowUpdateDialogThreadStart( __in PVOID Parameter ) { BOOL result; MSG message; PH_AUTO_POOL autoPool; PhInitializeAutoPool(&autoPool); UpdateDialogHandle = CreateDialog( (HINSTANCE)PluginInstance->DllBase, MAKEINTRESOURCE(IDD_UPDATE), PhMainWndHandle, UpdaterWndProc ); PhSetEvent(&InitializedEvent); while (result = GetMessage(&message, NULL, 0, 0)) { if (result == -1) break; if (!IsDialogMessage(UpdateDialogHandle, &message)) { TranslateMessage(&message); DispatchMessage(&message); } PhDrainAutoPool(&autoPool); } PhDeleteAutoPool(&autoPool); PhResetEvent(&InitializedEvent); // Ensure global objects are disposed and reset when window closes. if (SetupFilePath) { PhDereferenceObject(SetupFilePath); SetupFilePath = NULL; } if (UpdateCheckThreadHandle) { NtClose(UpdateCheckThreadHandle); UpdateCheckThreadHandle = NULL; } if (DownloadThreadHandle) { NtClose(DownloadThreadHandle); DownloadThreadHandle = NULL; } if (UpdaterDialogThreadHandle) { NtClose(UpdaterDialogThreadHandle); UpdaterDialogThreadHandle = NULL; } if (FontHandle) { DeleteObject(FontHandle); FontHandle = NULL; } FreeXmlData(); if (UpdateDialogHandle) { DestroyWindow(UpdateDialogHandle); UpdateDialogHandle = NULL; } return STATUS_SUCCESS; }
VOID PhSvcHandleConnectionRequest( _In_ PPORT_MESSAGE PortMessage ) { NTSTATUS status; PPHSVC_API_MSG message; PPHSVC_API_MSG64 message64; CLIENT_ID clientId; PPHSVC_CLIENT client; HANDLE portHandle; REMOTE_PORT_VIEW clientView; REMOTE_PORT_VIEW64 clientView64; PREMOTE_PORT_VIEW actualClientView; message = (PPHSVC_API_MSG)PortMessage; message64 = (PPHSVC_API_MSG64)PortMessage; if (PhIsExecutingInWow64()) { clientId.UniqueProcess = (HANDLE)message64->h.ClientId.UniqueProcess; clientId.UniqueThread = (HANDLE)message64->h.ClientId.UniqueThread; } else { PPH_STRING referenceFileName; PPH_STRING remoteFileName; clientId = message->h.ClientId; // Make sure that the remote process is Process Hacker itself and not some other program. referenceFileName = NULL; PhGetProcessImageFileNameByProcessId(NtCurrentProcessId(), &referenceFileName); PH_AUTO(referenceFileName); remoteFileName = NULL; PhGetProcessImageFileNameByProcessId(clientId.UniqueProcess, &remoteFileName); PH_AUTO(remoteFileName); if (!referenceFileName || !remoteFileName || !PhEqualString(referenceFileName, remoteFileName, TRUE)) { NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL); return; } } client = PhSvcCreateClient(&clientId); if (!client) { NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL); return; } if (PhIsExecutingInWow64()) { message64->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId()); clientView64.Length = sizeof(REMOTE_PORT_VIEW64); clientView64.ViewSize = 0; clientView64.ViewBase = 0; actualClientView = (PREMOTE_PORT_VIEW)&clientView64; } else { message->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId()); clientView.Length = sizeof(REMOTE_PORT_VIEW); clientView.ViewSize = 0; clientView.ViewBase = NULL; actualClientView = &clientView; } status = NtAcceptConnectPort( &portHandle, client, PortMessage, TRUE, NULL, actualClientView ); if (!NT_SUCCESS(status)) { PhDereferenceObject(client); return; } // IMPORTANT: Since Vista, NtCompleteConnectPort does not do anything and simply returns STATUS_SUCCESS. // We will call it anyway (for completeness), but we need to use an event to ensure that other threads don't try // to process requests before we have finished setting up the client object. client->PortHandle = portHandle; if (PhIsExecutingInWow64()) { client->ClientViewBase = (PVOID)clientView64.ViewBase; client->ClientViewLimit = PTR_ADD_OFFSET(clientView64.ViewBase, clientView64.ViewSize); } else { client->ClientViewBase = clientView.ViewBase; client->ClientViewLimit = PTR_ADD_OFFSET(clientView.ViewBase, clientView.ViewSize); } NtCompleteConnectPort(portHandle); PhSetEvent(&client->ReadyEvent); if (_InterlockedIncrement(&PhSvcApiNumberOfClients) == 1) { NtSetEvent(PhSvcTimeoutCancelEventHandle, NULL); } }
NTSTATUS PhpThreadProviderLoadSymbols( __in PVOID Parameter ) { PPH_THREAD_PROVIDER threadProvider = (PPH_THREAD_PROVIDER)Parameter; PH_THREAD_SYMBOL_LOAD_CONTEXT loadContext; loadContext.ThreadProvider = threadProvider; loadContext.SymbolProvider = threadProvider->SymbolProvider; PhLoadSymbolProviderOptions(threadProvider->SymbolProvider); if (threadProvider->ProcessId != SYSTEM_IDLE_PROCESS_ID) { if ( threadProvider->SymbolProvider->IsRealHandle || threadProvider->ProcessId == SYSTEM_PROCESS_ID ) { loadContext.ProcessId = threadProvider->ProcessId; PhEnumGenericModules( threadProvider->ProcessId, threadProvider->SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } else { // We can't enumerate the process modules. Load // symbols for ntdll.dll and kernel32.dll. loadContext.ProcessId = NtCurrentProcessId(); PhEnumGenericModules( NtCurrentProcessId(), NtCurrentProcess(), 0, LoadBasicSymbolsEnumGenericModulesCallback, &loadContext ); } // Load kernel module symbols as well. if (threadProvider->ProcessId != SYSTEM_PROCESS_ID) { loadContext.ProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } } else { // System Idle Process has one thread for each CPU, // each having a start address at KiIdleLoop. We // need to load symbols for the kernel. PRTL_PROCESS_MODULES kernelModules; if (NT_SUCCESS(PhEnumKernelModules(&kernelModules))) { if (kernelModules->NumberOfModules > 0) { PPH_STRING fileName; PPH_STRING newFileName; fileName = PhCreateStringFromAnsi(kernelModules->Modules[0].FullPathName); newFileName = PhGetFileName(fileName); PhDereferenceObject(fileName); PhLoadModuleSymbolProvider( threadProvider->SymbolProvider, newFileName->Buffer, (ULONG64)kernelModules->Modules[0].ImageBase, kernelModules->Modules[0].ImageSize ); PhDereferenceObject(newFileName); } PhFree(kernelModules); } } // Check if the process has services - we'll need to know before getting service tag/name // information. if (WINDOWS_HAS_SERVICE_TAGS) { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(threadProvider->ProcessId)) { threadProvider->HasServices = processItem->ServiceList && processItem->ServiceList->Count != 0; PhDereferenceObject(processItem); } } PhSetEvent(&threadProvider->SymbolsLoadedEvent); PhDereferenceObject(threadProvider); return STATUS_SUCCESS; }
static PPH_PROCESS_ITEM PhpCreateProcessItemForHiddenProcess( _In_ PPH_HIDDEN_PROCESS_ENTRY Entry ) { NTSTATUS status; PPH_PROCESS_ITEM processItem; PPH_PROCESS_ITEM idleProcessItem; HANDLE processHandle; PROCESS_BASIC_INFORMATION basicInfo; KERNEL_USER_TIMES times; PROCESS_PRIORITY_CLASS priorityClass; ULONG handleCount; HANDLE processHandle2; if (Entry->Type == NormalProcess) { processItem = PhReferenceProcessItem(Entry->ProcessId); if (processItem) return processItem; } processItem = PhCreateProcessItem(Entry->ProcessId); // Mark the process as terminated if necessary. if (Entry->Type == TerminatedProcess) processItem->State |= PH_PROCESS_ITEM_REMOVED; // We need a process record. Just use the record of System Idle Process. if (idleProcessItem = PhReferenceProcessItem(SYSTEM_IDLE_PROCESS_ID)) { processItem->Record = idleProcessItem->Record; PhReferenceProcessRecord(processItem->Record); } else { PhDereferenceObject(processItem); return NULL; } // Set up the file name and process name. PhSwapReference(&processItem->FileName, Entry->FileName); if (processItem->FileName) { processItem->ProcessName = PhGetBaseName(processItem->FileName); } else { processItem->ProcessName = PhCreateString(L"Unknown"); } if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } if (NT_SUCCESS(status)) { // Basic information and not-so-dynamic information processItem->QueryHandle = processHandle; if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &basicInfo))) { processItem->ParentProcessId = basicInfo.InheritedFromUniqueProcessId; processItem->BasePriority = basicInfo.BasePriority; } PhGetProcessSessionId(processHandle, &processItem->SessionId); PhPrintUInt32(processItem->ParentProcessIdString, HandleToUlong(processItem->ParentProcessId)); PhPrintUInt32(processItem->SessionIdString, processItem->SessionId); if (NT_SUCCESS(PhGetProcessTimes(processHandle, ×))) { processItem->CreateTime = times.CreateTime; processItem->KernelTime = times.KernelTime; processItem->UserTime = times.UserTime; } // TODO: Token information? if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS), NULL ))) { processItem->PriorityClass = priorityClass.PriorityClass; } if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessHandleCount, &handleCount, sizeof(ULONG), NULL ))) { processItem->NumberOfHandles = handleCount; } } // Stage 1 // Some copy and paste magic here... if (processItem->FileName) { // Small icon, large icon. ExtractIconEx( processItem->FileName->Buffer, 0, &processItem->LargeIcon, &processItem->SmallIcon, 1 ); // Version info. PhInitializeImageVersionInfo(&processItem->VersionInfo, processItem->FileName->Buffer); } // Use the default EXE icon if we didn't get the file's icon. { if (!processItem->SmallIcon || !processItem->LargeIcon) { if (processItem->SmallIcon) { DestroyIcon(processItem->SmallIcon); processItem->SmallIcon = NULL; } else if (processItem->LargeIcon) { DestroyIcon(processItem->LargeIcon); processItem->LargeIcon = NULL; } PhGetStockApplicationIcon(&processItem->SmallIcon, &processItem->LargeIcon); processItem->SmallIcon = DuplicateIcon(NULL, processItem->SmallIcon); processItem->LargeIcon = DuplicateIcon(NULL, processItem->LargeIcon); } } // POSIX, command line status = PhOpenProcess( &processHandle2, ProcessQueryAccess | PROCESS_VM_READ, Entry->ProcessId ); if (NT_SUCCESS(status)) { BOOLEAN isPosix = FALSE; PPH_STRING commandLine; ULONG i; status = PhGetProcessIsPosix(processHandle2, &isPosix); processItem->IsPosix = isPosix; if (!NT_SUCCESS(status) || !isPosix) { status = PhGetProcessCommandLine(processHandle2, &commandLine); if (NT_SUCCESS(status)) { // Some command lines (e.g. from taskeng.exe) have nulls in them. // Since Windows can't display them, we'll replace them with // spaces. for (i = 0; i < (ULONG)commandLine->Length / 2; i++) { if (commandLine->Buffer[i] == 0) commandLine->Buffer[i] = ' '; } } } else { // Get the POSIX command line. status = PhGetProcessPosixCommandLine(processHandle2, &commandLine); } if (NT_SUCCESS(status)) { processItem->CommandLine = commandLine; } NtClose(processHandle2); } // TODO: Other stage 1 tasks. PhSetEvent(&processItem->Stage1Event); return processItem; }