/* * Process Hacker Extra Plugins - * Trusted Installer Plugin * * Copyright (C) 2016 dmex * * This file is part of Process Hacker. * * Process Hacker is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Process Hacker is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Process Hacker. If not, see . */ #include "main.h" NTSTATUS RunAsCreateProcessThread( _In_ PVOID Parameter ) { NTSTATUS status = STATUS_UNSUCCESSFUL; SERVICE_STATUS_PROCESS serviceStatus = { 0 }; SC_HANDLE serviceHandle = NULL; HANDLE processHandle = NULL; HANDLE tokenHandle = NULL; PTOKEN_USER tokenUser = NULL; PPH_STRING userName = NULL; PPH_STRING commandLine = Parameter; ULONG bytesNeeded = 0; __try { if (!(serviceHandle = PhOpenService(L"TrustedInstaller", SERVICE_QUERY_STATUS | SERVICE_START))) { status = PhGetLastWin32ErrorAsNtStatus(); __leave; } if (!QueryServiceStatusEx( serviceHandle, SC_STATUS_PROCESS_INFO, (PBYTE)&serviceStatus, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded )) { status = PhGetLastWin32ErrorAsNtStatus(); __leave; } if (serviceStatus.dwCurrentState == SERVICE_RUNNING) { status = STATUS_SUCCESS; } else { ULONG attempts = 5; StartService(serviceHandle, 0, NULL); do { if (QueryServiceStatusEx( serviceHandle, SC_STATUS_PROCESS_INFO, (PBYTE)&serviceStatus, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded )) { if (serviceStatus.dwCurrentState == SERVICE_RUNNING) { status = STATUS_SUCCESS; break; } } Sleep(1000); } while (--attempts != 0); } if (!NT_SUCCESS(status)) { // One or more services failed to start. status = STATUS_SERVICES_FAILED_AUTOSTART; __leave; } if (!NT_SUCCESS(status = PhOpenProcess( &processHandle, ProcessQueryAccess, UlongToHandle(serviceStatus.dwProcessId) ))) { __leave; } if (!NT_SUCCESS(status = NtOpenProcessToken( processHandle, TOKEN_QUERY, &tokenHandle ))) { __leave; } if (!NT_SUCCESS(status = PhGetTokenUser(tokenHandle, &tokenUser))) __leave; if (!(userName = PhGetSidFullName(tokenUser->User.Sid, TRUE, NULL))) { // the SID structure is not valid. status = STATUS_INVALID_SID; __leave; } status = PhExecuteRunAsCommand2( PhMainWndHandle, PhGetStringOrEmpty(commandLine), PhGetStringOrEmpty(userName), L"", LOGON32_LOGON_SERVICE, UlongToHandle(serviceStatus.dwProcessId), NtCurrentPeb()->SessionId, NULL, FALSE ); } __finally { if (commandLine) PhDereferenceObject(commandLine); if (userName) PhDereferenceObject(userName); if (tokenUser) PhFree(tokenUser); if (tokenHandle) NtClose(tokenHandle); if (processHandle) NtClose(processHandle); if (serviceHandle) CloseServiceHandle(serviceHandle); } return status; }