From 47cc91cfea14e486691c4ba8d4862cb4b16e3fc3 Mon Sep 17 00:00:00 2001 From: dmex Date: Fri, 12 Aug 2016 18:30:51 +1000 Subject: [PATCH] Add TrustedInstaller plugin --- ExtraPlugins.sln | 10 + TrustedInstallerPlugin/CHANGELOG.txt | 2 + .../TrustedInstallerPlugin.rc | 148 ++++++++++++++ .../TrustedInstallerPlugin.vcxproj | 82 ++++++++ .../TrustedInstallerPlugin.vcxproj.filters | 44 +++++ TrustedInstallerPlugin/dialog.c | 147 ++++++++++++++ TrustedInstallerPlugin/main.c | 109 +++++++++++ TrustedInstallerPlugin/main.h | 48 +++++ TrustedInstallerPlugin/resource.h | 18 ++ TrustedInstallerPlugin/runas.c | 182 ++++++++++++++++++ 10 files changed, 790 insertions(+) create mode 100644 TrustedInstallerPlugin/CHANGELOG.txt create mode 100644 TrustedInstallerPlugin/TrustedInstallerPlugin.rc create mode 100644 TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj create mode 100644 TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj.filters create mode 100644 TrustedInstallerPlugin/dialog.c create mode 100644 TrustedInstallerPlugin/main.c create mode 100644 TrustedInstallerPlugin/main.h create mode 100644 TrustedInstallerPlugin/resource.h create mode 100644 TrustedInstallerPlugin/runas.c diff --git a/ExtraPlugins.sln b/ExtraPlugins.sln index 6ca2f872..1d1c7ec2 100644 --- a/ExtraPlugins.sln +++ b/ExtraPlugins.sln @@ -42,6 +42,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FirewallMonitorPlugin", "Fi EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ForceShutdownPlugin", "ForceShutdownPlugin\ForceShutdownPlugin.vcxproj", "{4417E8FC-5FA6-4631-B792-1872561E7DC2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TrustedInstallerPlugin", "TrustedInstallerPlugin\TrustedInstallerPlugin.vcxproj", "{652D6556-B8E3-4173-B321-60F623E127E8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -190,6 +192,14 @@ Global {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|Win32.Build.0 = Release|Win32 {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|x64.ActiveCfg = Release|x64 {4417E8FC-5FA6-4631-B792-1872561E7DC2}.Release|x64.Build.0 = Release|x64 + {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|Win32.ActiveCfg = Debug|Win32 + {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|Win32.Build.0 = Debug|Win32 + {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|x64.ActiveCfg = Debug|x64 + {652D6556-B8E3-4173-B321-60F623E127E8}.Debug|x64.Build.0 = Debug|x64 + {652D6556-B8E3-4173-B321-60F623E127E8}.Release|Win32.ActiveCfg = Release|Win32 + {652D6556-B8E3-4173-B321-60F623E127E8}.Release|Win32.Build.0 = Release|Win32 + {652D6556-B8E3-4173-B321-60F623E127E8}.Release|x64.ActiveCfg = Release|x64 + {652D6556-B8E3-4173-B321-60F623E127E8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TrustedInstallerPlugin/CHANGELOG.txt b/TrustedInstallerPlugin/CHANGELOG.txt new file mode 100644 index 00000000..f9aed183 --- /dev/null +++ b/TrustedInstallerPlugin/CHANGELOG.txt @@ -0,0 +1,2 @@ +1.0 + * Initial release \ No newline at end of file diff --git a/TrustedInstallerPlugin/TrustedInstallerPlugin.rc b/TrustedInstallerPlugin/TrustedInstallerPlugin.rc new file mode 100644 index 00000000..a77cc749 --- /dev/null +++ b/TrustedInstallerPlugin/TrustedInstallerPlugin.rc @@ -0,0 +1,148 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (Australia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS +#pragma code_page(1252) + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "0c0904b0" + BEGIN + VALUE "CompanyName", "dmex" + VALUE "FileDescription", "TrustedInstaller plugin for Process Hacker" + VALUE "FileVersion", "1.0" + VALUE "InternalName", "TrustedInstallerPlugin" + VALUE "LegalCopyright", "Licensed under the GNU GPL, v3." + VALUE "OriginalFilename", "TrustedInstallerPlugin.dll" + VALUE "ProductName", "TrustedInstaller plugin for Process Hacker" + VALUE "ProductVersion", "1.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0xc09, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_RUNASDIALOG DIALOGEX 0, 0, 251, 63 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Run As Trusted Installer" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,140,42,50,14 + PUSHBUTTON "Cancel",IDCANCEL,194,42,50,14 + EDITTEXT IDC_PROGRAM,7,20,181,14,ES_AUTOHSCROLL + LTEXT "Enter the command to run with Trusted Installer privileges:",IDC_STATIC,7,7,189,8 + PUSHBUTTON "Browse",IDC_BROWSE,194,20,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_RUNASDIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 244 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +IDD_RUNASDIALOG AFX_DIALOG_LAYOUT +BEGIN + 0 +END + +#endif // English (Australia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj b/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj new file mode 100644 index 00000000..0557568e --- /dev/null +++ b/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj @@ -0,0 +1,82 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {652D6556-B8E3-4173-B321-60F623E127E8} + TrustedInstallerPlugin + Win32Proj + TrustedInstallerPlugin + 10.0.10586.0 + + + + DynamicLibrary + Unicode + v140 + + + DynamicLibrary + Unicode + v140 + + + DynamicLibrary + Unicode + v140 + + + DynamicLibrary + Unicode + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj.filters b/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj.filters new file mode 100644 index 00000000..0ddfeec3 --- /dev/null +++ b/TrustedInstallerPlugin/TrustedInstallerPlugin.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/TrustedInstallerPlugin/dialog.c b/TrustedInstallerPlugin/dialog.c new file mode 100644 index 00000000..72c166a5 --- /dev/null +++ b/TrustedInstallerPlugin/dialog.c @@ -0,0 +1,147 @@ +/* + * 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 RunAsTrustedInstallerThread( + _In_ PVOID Parameter + ) +{ + HANDLE threadHandle; + THREAD_BASIC_INFORMATION basicInfo; + + if (threadHandle = PhCreateThread(0, RunAsCreateProcessThread, Parameter)) + { + LARGE_INTEGER timeout; + + NtWaitForSingleObject(threadHandle, FALSE, PhTimeoutFromMilliseconds(&timeout, 20 * 1000)); + + if (NT_SUCCESS(PhGetThreadBasicInformation(threadHandle, &basicInfo))) + { + if (basicInfo.ExitStatus != STATUS_SUCCESS) + { + // Show Error + PhShowStatus( + PhMainWndHandle, + L"Error creating process with TrustedInstaller privileges", + basicInfo.ExitStatus, + 0 + ); + } + } + + NtClose(threadHandle); + } + + return STATUS_SUCCESS; +} + +INT_PTR CALLBACK RunAsTrustedInstallerDlgProc( + _In_ HWND hwndDlg, + _In_ UINT uMsg, + _In_ WPARAM wParam, + _In_ LPARAM lParam + ) +{ + switch (uMsg) + { + case WM_INITDIALOG: + { + PhRegisterDialog(hwndDlg); + + SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_PROGRAM), TRUE); + } + break; + case WM_DESTROY: + { + PhUnregisterDialog(hwndDlg); + } + break; + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDCANCEL: + EndDialog(hwndDlg, IDCANCEL); + break; + case IDC_BROWSE: + { + static PH_FILETYPE_FILTER filters[] = + { + { L"Programs (*.exe;)", L"*.exe;" }, + { L"All files (*.*)", L"*.*" } + }; + PVOID fileDialog; + PPH_STRING fileName; + + fileDialog = PhCreateOpenFileDialog(); + PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); + + if (PhShowFileDialog(hwndDlg, fileDialog)) + { + fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog)); + SetDlgItemText(hwndDlg, IDC_PROGRAM, fileName->Buffer); + } + + PhFreeFileDialog(fileDialog); + } + break; + case IDOK: + { + PPH_STRING program; + HANDLE threadHandle; + + program = PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROGRAM)); + + if (PhIsNullOrEmptyString(program)) + { + PhDereferenceObject(program); + break; + } + + if (threadHandle = PhCreateThread(0, RunAsTrustedInstallerThread, program)) + { + NtClose(threadHandle); + } + + EndDialog(hwndDlg, IDOK); + } + break; + } + } + break; + } + + return FALSE; +} + +VOID ShowRunAsDialog( + _In_opt_ HWND Parent + ) +{ + DialogBox( + PluginInstance->DllBase, + MAKEINTRESOURCE(IDD_RUNASDIALOG), + Parent, + RunAsTrustedInstallerDlgProc + ); +} \ No newline at end of file diff --git a/TrustedInstallerPlugin/main.c b/TrustedInstallerPlugin/main.c new file mode 100644 index 00000000..18069fcd --- /dev/null +++ b/TrustedInstallerPlugin/main.c @@ -0,0 +1,109 @@ +/* + * 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" + +PPH_PLUGIN PluginInstance; +static PH_CALLBACK_REGISTRATION MenuItemCallbackRegistration; +static PH_CALLBACK_REGISTRATION MainMenuInitializingCallbackRegistration; + +VOID MenuItemCallback( + _In_opt_ PVOID Parameter, + _In_opt_ PVOID Context + ) +{ + PPH_PLUGIN_MENU_ITEM menuItem = Parameter; + + switch (menuItem->Id) + { + case RUNAS_MENU_ITEM: + { + if (!PhGetOwnTokenAttributes().Elevated) + { + PhShowInformation(menuItem->OwnerWindow, L"This option requires elevation."); + break; + } + else + { + ShowRunAsDialog(menuItem->OwnerWindow); + } + } + break; + } +} + +VOID NTAPI MainMenuInitializingCallback( + _In_opt_ PVOID Parameter, + _In_opt_ PVOID Context + ) +{ + PPH_PLUGIN_MENU_INFORMATION menuInfo = Parameter; + PPH_EMENU_ITEM runAsMenuItem; + ULONG indexOfMenuItem; + + if (menuInfo->u.MainMenu.SubMenuIndex != 0) // 0 = Hacker menu + return; + + runAsMenuItem = PhFindEMenuItem(menuInfo->Menu, PH_EMENU_FIND_STARTSWITH, L"Run as...", 0); + + if (!runAsMenuItem) + return; + + indexOfMenuItem = PhIndexOfEMenuItem(menuInfo->Menu, runAsMenuItem); + PhInsertEMenuItem(menuInfo->Menu, PhPluginCreateEMenuItem(PluginInstance, 0, RUNAS_MENU_ITEM, L"Run as trusted installer...", NULL), indexOfMenuItem + 1); +} + +LOGICAL DllMain( + _In_ HINSTANCE Instance, + _In_ ULONG Reason, + _Reserved_ PVOID Reserved + ) +{ + if (Reason == DLL_PROCESS_ATTACH) + { + PPH_PLUGIN_INFORMATION info; + + PluginInstance = PhRegisterPlugin(PLUGIN_NAME, Instance, &info); + + if (!PluginInstance) + return FALSE; + + info->DisplayName = L"Trusted Installer"; + info->Description = L"Run processes with Trusted Installer privileges via the Hacker menu > 'Run as trusted installer' menu."; + info->Author = L"dmex"; + + PhRegisterCallback( + PhGetPluginCallback(PluginInstance, PluginCallbackMenuItem), + MenuItemCallback, + NULL, + &MenuItemCallbackRegistration + ); + PhRegisterCallback( + PhGetGeneralCallback(GeneralCallbackMainMenuInitializing), + MainMenuInitializingCallback, + NULL, + &MainMenuInitializingCallbackRegistration + ); + } + + return TRUE; +} diff --git a/TrustedInstallerPlugin/main.h b/TrustedInstallerPlugin/main.h new file mode 100644 index 00000000..d9f79004 --- /dev/null +++ b/TrustedInstallerPlugin/main.h @@ -0,0 +1,48 @@ +/* + * 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 . + */ + +#ifndef _RUNAS_H_ +#define _RUNAS_H_ + +#define PLUGIN_NAME L"dmex.TrustedInstallerPlugin" +#define RUNAS_MENU_ITEM 1 + +#define CINTERFACE +#define COBJMACROS +#include +#include +#include +#include + +#include "resource.h" + +extern PPH_PLUGIN PluginInstance; + +VOID ShowRunAsDialog( + _In_opt_ HWND Parent + ); + +NTSTATUS RunAsCreateProcessThread( + _In_ PVOID Parameter + ); + +#endif _RUNAS_H_ \ No newline at end of file diff --git a/TrustedInstallerPlugin/resource.h b/TrustedInstallerPlugin/resource.h new file mode 100644 index 00000000..015b5eaf --- /dev/null +++ b/TrustedInstallerPlugin/resource.h @@ -0,0 +1,18 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by TrustedInstallerPlugin.rc +// +#define IDD_RUNASDIALOG 101 +#define IDC_PROGRAM 1001 +#define IDC_BROWSE 1003 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/TrustedInstallerPlugin/runas.c b/TrustedInstallerPlugin/runas.c new file mode 100644 index 00000000..361ffb55 --- /dev/null +++ b/TrustedInstallerPlugin/runas.c @@ -0,0 +1,182 @@ +/* + * 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 + ) +{ + static PH_STRINGREF processName = PH_STRINGREF_INIT(L"TrustedInstaller.exe"); + NTSTATUS status = STATUS_UNSUCCESSFUL; + BOOLEAN success = FALSE; + SERVICE_STATUS serviceStatus = { 0 }; + SC_HANDLE serviceHandle = NULL; + PVOID processes = NULL; + PSYSTEM_PROCESS_INFORMATION process = NULL; + HANDLE processHandle = NULL; + HANDLE tokenHandle = NULL; + PTOKEN_USER user = NULL; + PPH_STRING userName = NULL; + PPH_STRING program = Parameter; + + __try + { + if (!(serviceHandle = PhOpenService(L"TrustedInstaller", SERVICE_QUERY_STATUS | SERVICE_START))) + { + status = PhGetLastWin32ErrorAsNtStatus(); + __leave; + } + + if (!QueryServiceStatus(serviceHandle, &serviceStatus)) + { + status = PhGetLastWin32ErrorAsNtStatus(); + __leave; + } + + if (serviceStatus.dwCurrentState == SERVICE_RUNNING) + { + success = TRUE; + } + else + { + ULONG attempts = 5; + + StartService(serviceHandle, 0, NULL); + + do + { + if (QueryServiceStatus(serviceHandle, &serviceStatus)) + { + if (serviceStatus.dwCurrentState == SERVICE_RUNNING) + { + success = TRUE; + break; + } + } + + Sleep(1000); + + } while (--attempts != 0); + } + + if (!success) + { + // One or more services failed to start. + status = STATUS_SERVICES_FAILED_AUTOSTART; + __leave; + } + + if (!NT_SUCCESS(status = PhEnumProcesses(&processes))) + { + __leave; + } + + if (!(process = PhFindProcessInformationByImageName(processes, &processName))) + { + // The system could not find the instance specified. + status = STATUS_FLT_INSTANCE_NOT_FOUND; + __leave; + } + + if (!NT_SUCCESS(status = PhOpenProcess( + &processHandle, + ProcessQueryAccess, + process->UniqueProcessId + ))) + { + __leave; + } + + if (!NT_SUCCESS(status = NtOpenProcessToken( + processHandle, + TOKEN_QUERY, + &tokenHandle + ))) + { + __leave; + } + + if (!NT_SUCCESS(status = PhGetTokenUser(tokenHandle, &user))) + { + __leave; + } + + if (!(userName = PhGetSidFullName(user->User.Sid, TRUE, NULL))) + { + // the SID structure is not valid. + status = STATUS_INVALID_SID; + __leave; + } + + status = PhExecuteRunAsCommand2( + PhMainWndHandle, + program->Buffer, + userName->Buffer, + L"", + LOGON32_LOGON_SERVICE, + process->UniqueProcessId, + NtCurrentPeb()->SessionId, + NULL, + FALSE + ); + } + __finally + { + if (program) + { + PhDereferenceObject(program); + } + + if (userName) + { + PhDereferenceObject(userName); + } + + if (user) + { + PhFree(user); + } + + if (tokenHandle) + { + NtClose(tokenHandle); + } + + if (processHandle) + { + NtClose(processHandle); + } + + if (processes) + { + PhFree(processes); + } + + if (serviceHandle) + { + CloseServiceHandle(serviceHandle); + } + } + + return status; +}