VOID SetupParseCommandLine( VOID ) { static PH_COMMAND_LINE_OPTION options[] = { { SETUP_COMMAND_INSTALL, L"install", NoArgumentType }, { SETUP_COMMAND_UNINSTALL, L"uninstall", NoArgumentType }, { SETUP_COMMAND_UPDATE, L"update", NoArgumentType }, { SETUP_COMMAND_REPAIR, L"repair", NoArgumentType }, { SETUP_COMMAND_SILENTINSTALL, L"silent", NoArgumentType }, }; PPH_STRING commandLine; if (NT_SUCCESS(PhGetProcessCommandLine(NtCurrentProcess(), &commandLine))) { PhParseCommandLine( &commandLine->sr, options, ARRAYSIZE(options), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS | PH_COMMAND_LINE_IGNORE_FIRST_PART, MainPropSheetCommandLineCallback, NULL ); PhDereferenceObject(commandLine); } }
NTSTATUS PhCommandModeStart( VOID ) { static PH_COMMAND_LINE_OPTION options[] = { { PH_COMMAND_OPTION_HWND, L"hwnd", MandatoryArgumentType } }; NTSTATUS status; PPH_STRING commandLine; if (!NT_SUCCESS(status = PhGetProcessCommandLine(NtCurrentProcess(), &commandLine))) return status; PhParseCommandLine( &commandLine->sr, options, sizeof(options) / sizeof(PH_COMMAND_LINE_OPTION), PH_COMMAND_LINE_IGNORE_UNKNOWN_OPTIONS, PhpCommandModeOptionCallback, NULL ); PhDereferenceObject(commandLine); if (PhEqualString2(PhStartupParameters.CommandType, L"process", TRUE)) { SIZE_T i; SIZE_T processIdLength; HANDLE processId; HANDLE processHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; processIdLength = PhStartupParameters.CommandObject->Length / 2; for (i = 0; i < processIdLength; i++) { if (!PhIsDigitCharacter(PhStartupParameters.CommandObject->Buffer[i])) break; } if (i == processIdLength) { ULONG64 processId64; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &processId64)) return STATUS_INVALID_PARAMETER; processId = (HANDLE)processId64; } else { PVOID processes; PSYSTEM_PROCESS_INFORMATION process; if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) return status; if (!(process = PhFindProcessInformationByImageName(processes, &PhStartupParameters.CommandObject->sr))) { PhFree(processes); return STATUS_NOT_FOUND; } processId = process->UniqueProcessId; PhFree(processes); } if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_TERMINATE, processId))) { status = NtTerminateProcess(processHandle, STATUS_SUCCESS); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtSuspendProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SUSPEND_RESUME, processId))) { status = NtResumeProcess(processHandle); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"priority", TRUE)) { UCHAR priority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"idle", TRUE)) priority = PROCESS_PRIORITY_CLASS_IDLE; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) priority = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) priority = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(PhStartupParameters.CommandValue, L"realtime", TRUE)) priority = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(PhStartupParameters.CommandValue, L"abovenormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_ABOVE_NORMAL; else if (PhEqualString2(PhStartupParameters.CommandValue, L"belownormal", TRUE)) priority = PROCESS_PRIORITY_CLASS_BELOW_NORMAL; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { PROCESS_PRIORITY_CLASS priorityClass; priorityClass.Foreground = FALSE; priorityClass.PriorityClass = priority; status = NtSetInformationProcess(processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS)); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"iopriority", TRUE)) { ULONG ioPriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandValue, L"verylow", TRUE)) ioPriority = 0; else if (PhEqualString2(PhStartupParameters.CommandValue, L"low", TRUE)) ioPriority = 1; else if (PhEqualString2(PhStartupParameters.CommandValue, L"normal", TRUE)) ioPriority = 2; else if (PhEqualString2(PhStartupParameters.CommandValue, L"high", TRUE)) ioPriority = 3; else return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = PhSetProcessIoPriority(processHandle, ioPriority); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pagepriority", TRUE)) { ULONG64 pagePriority64; ULONG pagePriority; if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; PhStringToInteger64(&PhStartupParameters.CommandValue->sr, 10, &pagePriority64); pagePriority = (ULONG)pagePriority64; if (NT_SUCCESS(status = PhOpenProcessPublic(&processHandle, PROCESS_SET_INFORMATION, processId))) { status = NtSetInformationProcess( processHandle, ProcessPagePriority, &pagePriority, sizeof(ULONG) ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"injectdll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhInjectDllProcess( processHandle, PhStartupParameters.CommandValue->Buffer, &timeout ); NtClose(processHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"unloaddll", TRUE)) { if (!PhStartupParameters.CommandValue) return STATUS_INVALID_PARAMETER; if (NT_SUCCESS(status = PhOpenProcessPublic( &processHandle, ProcessQueryAccess | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, processId ))) { PVOID baseAddress; if (NT_SUCCESS(status = PhpGetDllBaseRemote( processHandle, &PhStartupParameters.CommandValue->sr, &baseAddress ))) { LARGE_INTEGER timeout; timeout.QuadPart = -5 * PH_TIMEOUT_SEC; status = PhUnloadDllProcess( processHandle, baseAddress, &timeout ); } NtClose(processHandle); } } } else if (PhEqualString2(PhStartupParameters.CommandType, L"service", TRUE)) { SC_HANDLE serviceHandle; SERVICE_STATUS serviceStatus; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (PhEqualString2(PhStartupParameters.CommandAction, L"start", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_START ))) return PhGetLastWin32ErrorAsNtStatus(); if (!StartService(serviceHandle, 0, NULL)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"continue", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_CONTINUE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"pause", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_PAUSE_CONTINUE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_PAUSE, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"stop", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, SERVICE_STOP ))) return PhGetLastWin32ErrorAsNtStatus(); if (!ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } else if (PhEqualString2(PhStartupParameters.CommandAction, L"delete", TRUE)) { if (!(serviceHandle = PhOpenService( PhStartupParameters.CommandObject->Buffer, DELETE ))) return PhGetLastWin32ErrorAsNtStatus(); if (!DeleteService(serviceHandle)) status = PhGetLastWin32ErrorAsNtStatus(); CloseServiceHandle(serviceHandle); } } else if (PhEqualString2(PhStartupParameters.CommandType, L"thread", TRUE)) { ULONG64 threadId64; HANDLE threadId; HANDLE threadHandle; if (!PhStartupParameters.CommandObject) return STATUS_INVALID_PARAMETER; if (!PhStringToInteger64(&PhStartupParameters.CommandObject->sr, 10, &threadId64)) return STATUS_INVALID_PARAMETER; threadId = (HANDLE)threadId64; if (PhEqualString2(PhStartupParameters.CommandAction, L"terminate", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_TERMINATE, threadId))) { status = NtTerminateThread(threadHandle, STATUS_SUCCESS); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"suspend", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtSuspendThread(threadHandle, NULL); NtClose(threadHandle); } } else if (PhEqualString2(PhStartupParameters.CommandAction, L"resume", TRUE)) { if (NT_SUCCESS(status = PhOpenThreadPublic(&threadHandle, THREAD_SUSPEND_RESUME, threadId))) { status = NtResumeThread(threadHandle, NULL); NtClose(threadHandle); } } } return status; }
static PPH_PROCESS_ITEM PhpCreateProcessItemForHiddenProcess( _In_ PPH_HIDDEN_PROCESS_ENTRY Entry ) { NTSTATUS status; PPH_PROCESS_ITEM processItem; PPH_PROCESS_ITEM idleProcessItem; HANDLE processHandle; PROCESS_BASIC_INFORMATION basicInfo; KERNEL_USER_TIMES times; PROCESS_PRIORITY_CLASS priorityClass; ULONG handleCount; HANDLE processHandle2; if (Entry->Type == NormalProcess) { processItem = PhReferenceProcessItem(Entry->ProcessId); if (processItem) return processItem; } processItem = PhCreateProcessItem(Entry->ProcessId); // Mark the process as terminated if necessary. if (Entry->Type == TerminatedProcess) processItem->State |= PH_PROCESS_ITEM_REMOVED; // We need a process record. Just use the record of System Idle Process. if (idleProcessItem = PhReferenceProcessItem(SYSTEM_IDLE_PROCESS_ID)) { processItem->Record = idleProcessItem->Record; PhReferenceProcessRecord(processItem->Record); } else { PhDereferenceObject(processItem); return NULL; } // Set up the file name and process name. PhSwapReference(&processItem->FileName, Entry->FileName); if (processItem->FileName) { processItem->ProcessName = PhGetBaseName(processItem->FileName); } else { processItem->ProcessName = PhCreateString(L"Unknown"); } if (ProcessesMethod == BruteForceScanMethod) { status = PhOpenProcess( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } else { status = PhOpenProcessByCsrHandles( &processHandle, ProcessQueryAccess, Entry->ProcessId ); } if (NT_SUCCESS(status)) { // Basic information and not-so-dynamic information processItem->QueryHandle = processHandle; if (NT_SUCCESS(PhGetProcessBasicInformation(processHandle, &basicInfo))) { processItem->ParentProcessId = basicInfo.InheritedFromUniqueProcessId; processItem->BasePriority = basicInfo.BasePriority; } PhGetProcessSessionId(processHandle, &processItem->SessionId); PhPrintUInt32(processItem->ParentProcessIdString, HandleToUlong(processItem->ParentProcessId)); PhPrintUInt32(processItem->SessionIdString, processItem->SessionId); if (NT_SUCCESS(PhGetProcessTimes(processHandle, ×))) { processItem->CreateTime = times.CreateTime; processItem->KernelTime = times.KernelTime; processItem->UserTime = times.UserTime; } // TODO: Token information? if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessPriorityClass, &priorityClass, sizeof(PROCESS_PRIORITY_CLASS), NULL ))) { processItem->PriorityClass = priorityClass.PriorityClass; } if (NT_SUCCESS(NtQueryInformationProcess( processHandle, ProcessHandleCount, &handleCount, sizeof(ULONG), NULL ))) { processItem->NumberOfHandles = handleCount; } } // Stage 1 // Some copy and paste magic here... if (processItem->FileName) { // Small icon, large icon. ExtractIconEx( processItem->FileName->Buffer, 0, &processItem->LargeIcon, &processItem->SmallIcon, 1 ); // Version info. PhInitializeImageVersionInfo(&processItem->VersionInfo, processItem->FileName->Buffer); } // Use the default EXE icon if we didn't get the file's icon. { if (!processItem->SmallIcon || !processItem->LargeIcon) { if (processItem->SmallIcon) { DestroyIcon(processItem->SmallIcon); processItem->SmallIcon = NULL; } else if (processItem->LargeIcon) { DestroyIcon(processItem->LargeIcon); processItem->LargeIcon = NULL; } PhGetStockApplicationIcon(&processItem->SmallIcon, &processItem->LargeIcon); processItem->SmallIcon = DuplicateIcon(NULL, processItem->SmallIcon); processItem->LargeIcon = DuplicateIcon(NULL, processItem->LargeIcon); } } // POSIX, command line status = PhOpenProcess( &processHandle2, ProcessQueryAccess | PROCESS_VM_READ, Entry->ProcessId ); if (NT_SUCCESS(status)) { BOOLEAN isPosix = FALSE; PPH_STRING commandLine; ULONG i; status = PhGetProcessIsPosix(processHandle2, &isPosix); processItem->IsPosix = isPosix; if (!NT_SUCCESS(status) || !isPosix) { status = PhGetProcessCommandLine(processHandle2, &commandLine); if (NT_SUCCESS(status)) { // Some command lines (e.g. from taskeng.exe) have nulls in them. // Since Windows can't display them, we'll replace them with // spaces. for (i = 0; i < (ULONG)commandLine->Length / 2; i++) { if (commandLine->Buffer[i] == 0) commandLine->Buffer[i] = ' '; } } } else { // Get the POSIX command line. status = PhGetProcessPosixCommandLine(processHandle2, &commandLine); } if (NT_SUCCESS(status)) { processItem->CommandLine = commandLine; } NtClose(processHandle2); } // TODO: Other stage 1 tasks. PhSetEvent(&processItem->Stage1Event); return processItem; }