70 typedef struct _RUNAS_DIALOG_CONTEXT
94 #define SIP(String, Integer) { (String), (PVOID)(Integer) }
98 SIP(L
"Batch", LOGON32_LOGON_BATCH),
99 SIP(L
"Interactive", LOGON32_LOGON_INTERACTIVE),
100 SIP(L
"Network", LOGON32_LOGON_NETWORK),
101 SIP(L
"New credentials", LOGON32_LOGON_NEW_CREDENTIALS),
102 SIP(L
"Service", LOGON32_LOGON_SERVICE)
105 static WCHAR RunAsOldServiceName[32] = L
"";
109 static SERVICE_STATUS_HANDLE RunAsServiceStatusHandle;
113 _In_ HWND ParentWindowHandle,
120 context.DesktopList = NULL;
131 static VOID PhpAddAccountsToComboBox(
132 _In_ HWND ComboBoxHandle
135 LSA_HANDLE policyHandle;
136 LSA_ENUMERATION_HANDLE enumerationContext = 0;
137 PLSA_ENUMERATION_INFORMATION buffer;
141 SID_NAME_USE nameUse;
153 for (i = 0; i < count; i++)
159 if (nameUse == SidTypeUser)
160 ComboBox_AddString(ComboBoxHandle, name->
Buffer);
166 LsaFreeMemory(buffer);
169 LsaClose(policyHandle);
173 static BOOLEAN IsServiceAccount(
199 if (GetUserObjectInformation(
200 GetProcessWindowStation(),
203 (ULONG)string->
Length + 2,
217 static BOOL CALLBACK EnumDesktopsCallback(
218 _In_ PWSTR DesktopName,
226 context->CurrentWinStaName->Buffer,
243 if (uMsg != WM_INITDIALOG)
260 HWND typeComboBoxHandle = GetDlgItem(hwndDlg,
IDC_TYPE);
261 HWND userNameComboBoxHandle = GetDlgItem(hwndDlg,
IDC_USERNAME);
270 SHACF_AUTOAPPEND_FORCE_ON | SHACF_AUTOSUGGEST_FORCE_ON | SHACF_FILESYS_ONLY
274 ComboBox_AddString(typeComboBoxHandle, L
"Batch");
275 ComboBox_AddString(typeComboBoxHandle, L
"Interactive");
276 ComboBox_AddString(typeComboBoxHandle, L
"Network");
277 ComboBox_AddString(typeComboBoxHandle, L
"New credentials");
278 ComboBox_AddString(typeComboBoxHandle, L
"Service");
281 ComboBox_AddString(userNameComboBoxHandle, L
"NT AUTHORITY\\SYSTEM");
282 ComboBox_AddString(userNameComboBoxHandle, L
"NT AUTHORITY\\LOCAL SERVICE");
283 ComboBox_AddString(userNameComboBoxHandle, L
"NT AUTHORITY\\NETWORK SERVICE");
285 PhpAddAccountsToComboBox(userNameComboBoxHandle);
290 SetDlgItemText(hwndDlg,
IDC_DESKTOP, L
"WinSta0\\Default");
295 if (!context->ProcessId)
301 SendMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(
IDC_USERNAME, CBN_EDITCHANGE), 0);
305 HANDLE processHandle;
333 NtClose(tokenHandle);
336 NtClose(processHandle);
344 SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg,
IDC_PROGRAM),
TRUE);
345 Edit_SetSel(GetDlgItem(hwndDlg,
IDC_PROGRAM), 0, -1);
356 if (context->DesktopList)
364 switch (LOWORD(wParam))
367 EndDialog(hwndDlg, IDCANCEL);
379 BOOLEAN useLinkedToken;
398 userName = newUserName;
405 if (!IsServiceAccount(userName))
416 useLinkedToken =
FALSE;
420 sizeof(PhpLogonTypePairs),
426 logonType == LOGON32_LOGON_INTERACTIVE &&
427 !context->ProcessId &&
428 sessionId == NtCurrentPeb()->SessionId &&
483 status = STATUS_INVALID_PARAMETER;
488 RtlSecureZeroMemory(password->
Buffer, password->
Length);
494 if (status != STATUS_CANCELLED)
495 PhShowStatus(hwndDlg, L
"Unable to start the program", status, 0);
497 else if (status != STATUS_TIMEOUT)
501 EndDialog(hwndDlg, IDOK);
509 { L
"Programs (*.exe;*.pif;*.com;*.bat)", L
"*.exe;*.pif;*.com;*.bat" },
510 { L
"All files (*.*)", L
"*.*" }
534 if (!context->ProcessId && HIWORD(wParam) == CBN_SELCHANGE)
538 else if (!context->ProcessId && (
539 HIWORD(wParam) == CBN_EDITCHANGE ||
540 HIWORD(wParam) == CBN_CLOSEUP
548 if (IsServiceAccount(userName))
577 ULONG numberOfSessions;
586 for (i = 0; i < numberOfSessions; i++)
594 sessions[i].SessionId,
601 winStationInfo.
Domain[0] = 0;
612 sessions[i].SessionId,
613 sessions[i].WinStationName,
618 else if (winStationInfo.
UserName[0] != 0)
622 sessions[i].SessionId,
627 else if (sessions[i].WinStationName[0] != 0)
631 sessions[i].SessionId,
632 sessions[i].WinStationName
647 GetWindowRect(GetDlgItem(hwndDlg,
IDC_SESSIONS), &buttonRect);
681 if (!context->DesktopList)
684 context->CurrentWinStaName = GetCurrentWinStaName();
686 EnumDesktops(GetProcessWindowStation(), EnumDesktopsCallback, (LPARAM)context);
688 for (i = 0; i < context->DesktopList->Count; i++)
697 GetWindowRect(GetDlgItem(hwndDlg,
IDC_DESKTOPS), &buttonRect);
717 for (i = 0; i < context->DesktopList->Count; i++)
741 static SID_IDENTIFIER_AUTHORITY appPackageAuthority = SECURITY_APP_PACKAGE_AUTHORITY;
745 ULONG allocationLength;
746 PSECURITY_DESCRIPTOR securityDescriptor;
748 CHAR allAppPackagesSidBuffer[FIELD_OFFSET(SID, SubAuthority) +
sizeof(ULONG) * 2];
749 PSID allAppPackagesSid;
753 allAppPackagesSid = (PISID)allAppPackagesSidBuffer;
754 RtlInitializeSid(allAppPackagesSid, &appPackageAuthority, SECURITY_BUILTIN_APP_PACKAGE_RID_COUNT);
760 allocationLength = SECURITY_DESCRIPTOR_MIN_LENGTH +
762 (ULONG)
sizeof(ACCESS_ALLOWED_ACE) +
764 (ULONG)
sizeof(ACCESS_ALLOWED_ACE) +
766 securityDescriptor = PhAllocate(allocationLength);
767 dacl = (PACL)((PCHAR)securityDescriptor + SECURITY_DESCRIPTOR_MIN_LENGTH);
771 RtlCreateAcl(dacl, allocationLength - SECURITY_DESCRIPTOR_MIN_LENGTH, ACL_REVISION);
781 if (wsHandle = OpenWindowStation(
788 CloseWindowStation(wsHandle);
791 if (desktopHandle = OpenDesktop(
795 WRITE_DAC | DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS
799 CloseDesktop(desktopHandle);
802 PhFree(securityDescriptor);
819 SC_HANDLE scManagerHandle;
820 SC_HANDLE serviceHandle;
824 LARGE_INTEGER interval;
826 if (!(scManagerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)))
831 serviceHandle = CreateService(
833 Parameters->ServiceName,
834 Parameters->ServiceName,
836 SERVICE_WIN32_OWN_PROCESS,
837 SERVICE_DEMAND_START,
838 SERVICE_ERROR_IGNORE,
846 win32Result = GetLastError();
850 CloseServiceHandle(scManagerHandle);
854 return NTSTATUS_FROM_WIN32(win32Result);
859 StartService(serviceHandle, 0, NULL);
860 DeleteService(serviceHandle);
862 portName =
PhConcatStrings2(L
"\\BaseNamedObjects\\", Parameters->ServiceName);
876 NtDelayExecution(
FALSE, &interval);
877 }
while (--attempts != 0);
888 CloseServiceHandle(serviceHandle);
924 _In_opt_ PWSTR UserName,
925 _In_opt_ PWSTR Password,
926 _In_opt_ ULONG LogonType,
927 _In_opt_ HANDLE ProcessIdWithToken,
928 _In_ ULONG SessionId,
929 _In_ PWSTR DesktopName,
930 _In_ BOOLEAN UseLinkedToken
933 NTSTATUS status = STATUS_SUCCESS;
935 WCHAR serviceName[32];
940 parameters.
ProcessId = (ULONG)ProcessIdWithToken;
950 if (RunAsOldServiceName[0] != 0)
975 memcpy(serviceName, L
"ProcessHacker", 13 *
sizeof(WCHAR));
978 memcpy(RunAsOldServiceName, serviceName,
sizeof(serviceName));
996 status = STATUS_CANCELLED;
1004 _In_ PWSTR UserName,
1027 static VOID SetRunAsServiceStatus(
1031 SERVICE_STATUS status;
1033 memset(&status, 0,
sizeof(SERVICE_STATUS));
1034 status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
1035 status.dwCurrentState = State;
1036 status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
1038 SetServiceStatus(RunAsServiceStatusHandle, &status);
1041 static DWORD WINAPI RunAsServiceHandlerEx(
1042 _In_ DWORD dwControl,
1043 _In_ DWORD dwEventType,
1044 _In_ LPVOID lpEventData,
1045 _In_ LPVOID lpContext
1050 case SERVICE_CONTROL_STOP:
1053 case SERVICE_CONTROL_INTERROGATE:
1057 return ERROR_CALL_NOT_IMPLEMENTED;
1060 static VOID WINAPI RunAsServiceMain(
1062 _In_ LPTSTR *lpszArgv
1067 LARGE_INTEGER timeout;
1069 memset(&RunAsServiceStop, 0,
sizeof(
PHSVC_STOP));
1070 RunAsServiceStatusHandle = RegisterServiceCtrlHandlerEx(RunAsServiceName->
Buffer, RunAsServiceHandlerEx, NULL);
1071 SetRunAsServiceStatus(SERVICE_RUNNING);
1078 PhSvcMain(&portNameUs, &timeout, &RunAsServiceStop);
1080 SetRunAsServiceStatus(SERVICE_STOPPED);
1088 SERVICE_TABLE_ENTRY entry;
1094 TOKEN_ADJUST_PRIVILEGES,
1098 PhSetTokenPrivilege(tokenHandle, L
"SeAssignPrimaryTokenPrivilege", NULL, SE_PRIVILEGE_ENABLED);
1101 PhSetTokenPrivilege(tokenHandle, L
"SeIncreaseQuotaPrivilege", NULL, SE_PRIVILEGE_ENABLED);
1103 NtClose(tokenHandle);
1108 entry.lpServiceName = ServiceName->
Buffer;
1109 entry.lpServiceProc = RunAsServiceMain;
1111 StartServiceCtrlDispatcher(&entry);
1113 return STATUS_SUCCESS;
1126 if (Parameters->UserName)
1142 createInfo.
Password = Parameters->Password;
1143 createInfo.
LogonType = Parameters->LogonType;
1144 createInfo.
SessionId = Parameters->SessionId;
1149 if (Parameters->ProcessId)
1155 if (Parameters->UseLinkedToken)