public static DllInjector CreateProcess(ProcessStartInfo StartInfo, bool CreateSuspended = false, bool FreeOnDispose = false) { Process process; if (CreateSuspended) { if (StartInfo == null) { throw new ArgumentNullException("StartInfo"); } if (string.IsNullOrEmpty(StartInfo.FileName)) { throw new ArgumentException("FileNameMissing"); } if (StartInfo.StandardOutputEncoding != null && !StartInfo.RedirectStandardOutput) { throw new ArgumentException("StandardOutputEncodingNotAllowed"); } if (StartInfo.StandardErrorEncoding != null && !StartInfo.RedirectStandardError) { throw new ArgumentException("StandardErrorEncodingNotAllowed"); } /* * private static StringBuilder BuildCommandLine(string executableFileName, string arguments); * * Declaring Type: System.Diagnostics.Process * Assembly: System, Version=4.0.0.0 */ StringBuilder cmdLine = new StringBuilder(); string str = StartInfo.FileName.Trim(); bool flag = str.StartsWith("\"", StringComparison.Ordinal) && str.EndsWith("\"", StringComparison.Ordinal); if (!flag) { cmdLine.Append("\""); } cmdLine.Append(str); if (!flag) { cmdLine.Append("\""); } if (!string.IsNullOrEmpty(StartInfo.Arguments)) { cmdLine.Append(" "); cmdLine.Append(StartInfo.Arguments); } /* * private bool StartWithCreateProcess(ProcessStartInfo startInfo); * * Declaring Type: System.Diagnostics.Process * Assembly: System, Version=4.0.0.0 */ Win32.STARTUPINFO lpStartupInfo = new Win32.STARTUPINFO() { hStdError = new SafeFileHandle(IntPtr.Zero, false), hStdInput = new SafeFileHandle(IntPtr.Zero, false), hStdOutput = new SafeFileHandle(IntPtr.Zero, false) }; Win32.PROCESS_INFORMATION lpProcessInformation = new Win32.PROCESS_INFORMATION(); IntPtr processHandle = IntPtr.Zero; IntPtr handle2 = IntPtr.Zero; SafeFileHandle parentHandle = null; SafeFileHandle handle4 = null; SafeFileHandle handle5 = null; int error = 0; GCHandle handle6 = new GCHandle(); try { if (StartInfo.RedirectStandardInput || StartInfo.RedirectStandardOutput || StartInfo.RedirectStandardError) { if (StartInfo.RedirectStandardInput) { CreatePipe(out parentHandle, out lpStartupInfo.hStdInput, true); } else { lpStartupInfo.hStdInput = new SafeFileHandle(Win32.GetStdHandle(Win32.StdHandles.STD_INPUT_HANDLE), false); } if (StartInfo.RedirectStandardOutput) { CreatePipe(out handle4, out lpStartupInfo.hStdOutput, false); } else { lpStartupInfo.hStdOutput = new SafeFileHandle(Win32.GetStdHandle(Win32.StdHandles.STD_OUTPUT_HANDLE), false); } if (StartInfo.RedirectStandardError) { CreatePipe(out handle5, out lpStartupInfo.hStdError, false); } else { lpStartupInfo.hStdError = new SafeFileHandle(Win32.GetStdHandle(Win32.StdHandles.STD_ERROR_HANDLE), false); } lpStartupInfo.dwFlags = 0x100; } Win32.ProcessCreationFlags creationFlags = Win32.ProcessCreationFlags.CREATE_SUSPENDED; if (StartInfo.CreateNoWindow) { creationFlags |= Win32.ProcessCreationFlags.CREATE_NO_WINDOW; } if (Utilities.IsNt) { creationFlags |= Win32.ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT; handle6 = GCHandle.Alloc(EnvironmentBlock.ToByteArray(StartInfo.EnvironmentVariables, true), GCHandleType.Pinned); } else { handle6 = GCHandle.Alloc(EnvironmentBlock.ToByteArray(StartInfo.EnvironmentVariables, false), GCHandleType.Pinned); } string workingDirectory = StartInfo.WorkingDirectory; if (workingDirectory == string.Empty) { workingDirectory = Environment.CurrentDirectory; } if (StartInfo.UserName.Length != 0) { Win32.LogonFlags logonFlags = 0; if (StartInfo.LoadUserProfile) { logonFlags = Win32.LogonFlags.LOGON_WITH_PROFILE; } IntPtr password = IntPtr.Zero; try { if (StartInfo.Password == null) { password = Marshal.StringToCoTaskMemUni(string.Empty); } else { password = Marshal.SecureStringToCoTaskMemUnicode(StartInfo.Password); } RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { flag = Win32.CreateProcessWithLogon(StartInfo.UserName, StartInfo.Domain, password, logonFlags, null, cmdLine, creationFlags, handle6.AddrOfPinnedObject(), workingDirectory, ref lpStartupInfo, out lpProcessInformation); if (!flag) { error = Marshal.GetLastWin32Error(); } if (lpProcessInformation.hProcess != IntPtr.Zero && lpProcessInformation.hProcess != Win32.INVALID_HANDLE_VALUE) { processHandle = lpProcessInformation.hProcess; } if (lpProcessInformation.hThread != IntPtr.Zero && lpProcessInformation.hThread != Win32.INVALID_HANDLE_VALUE) { handle2 = lpProcessInformation.hThread; } } if (!flag) { if ((error != 0xc1) && (error != 0xd8)) { throw new Win32Exception(error); } throw new Win32Exception(error, "InvalidApplication"); } } finally { if (password != IntPtr.Zero) { Marshal.ZeroFreeCoTaskMemUnicode(password); } } } else { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { flag = Win32.CreateProcess(null, cmdLine, IntPtr.Zero, IntPtr.Zero, true, creationFlags, handle6.AddrOfPinnedObject(), workingDirectory, ref lpStartupInfo, out lpProcessInformation); if (!flag) { error = Marshal.GetLastWin32Error(); } if (lpProcessInformation.hProcess != IntPtr.Zero && lpProcessInformation.hProcess != Win32.INVALID_HANDLE_VALUE) { processHandle = lpProcessInformation.hProcess; } if (lpProcessInformation.hThread != IntPtr.Zero && lpProcessInformation.hThread != Win32.INVALID_HANDLE_VALUE) { handle2 = lpProcessInformation.hThread; } } if (!flag) { if ((error != 0xc1) && (error != 0xd8)) { throw new Win32Exception(error); } throw new Win32Exception(error, "InvalidApplication"); } } } finally { if (handle6.IsAllocated) { handle6.Free(); } if (lpStartupInfo.hStdInput != null && !lpStartupInfo.hStdInput.IsInvalid) { lpStartupInfo.hStdInput.Close(); } if (lpStartupInfo.hStdOutput != null && !lpStartupInfo.hStdOutput.IsInvalid) { lpStartupInfo.hStdOutput.Close(); } if (lpStartupInfo.hStdError != null && !lpStartupInfo.hStdError.IsInvalid) { lpStartupInfo.hStdError.Close(); } } if (processHandle != IntPtr.Zero && processHandle != Win32.INVALID_HANDLE_VALUE) { Win32.CloseHandle(handle2); } process = Process.GetProcessById((int)lpProcessInformation.dwProcessId); if (StartInfo.RedirectStandardInput) { FieldInfo standardInput = typeof(Process).GetField("standardInput", BindingFlags.Instance | BindingFlags.NonPublic); standardInput.SetValue(process, new StreamWriter(new FileStream(parentHandle, FileAccess.Write, 0x1000, false), Console.InputEncoding, 0x1000) { AutoFlush = true }); } if (StartInfo.RedirectStandardOutput) { FieldInfo standardOutput = typeof(Process).GetField("standardOutput", BindingFlags.Instance | BindingFlags.NonPublic); standardOutput.SetValue(process, new StreamReader(new FileStream(handle4, FileAccess.Read, 0x1000, false), (StartInfo.StandardOutputEncoding != null) ? StartInfo.StandardOutputEncoding : Console.OutputEncoding, true, 0x1000)); } if (StartInfo.RedirectStandardError) { FieldInfo standardError = typeof(Process).GetField("standardError", BindingFlags.Instance | BindingFlags.NonPublic); standardError.SetValue(process, new StreamReader(new FileStream(handle5, FileAccess.Read, 0x1000, false), (StartInfo.StandardErrorEncoding != null) ? StartInfo.StandardErrorEncoding : Console.OutputEncoding, true, 0x1000)); } } else { process = Process.Start(StartInfo); } return(new DllInjector(process, FreeOnDispose)); }
public void ExecuteApplication(PasswordEntryManager entryManager) { ExecutionSettings settings = entryManager.GetExecutionSettings(); // Determine the values to use on native calls based on the impersonation settings. string domain = settings.Domain; string username = settings.Username; Win32.LogonFlags logonFlags = settings.NetOnly ? Win32.LogonFlags.LOGON_NETCREDENTIALS_ONLY : Win32.LogonFlags.LOGON_WITH_PROFILE; string application = settings.Application; string arguments = settings.Arguments; string workingDir = string.IsNullOrWhiteSpace(settings.WorkingDir) ? null : settings.WorkingDir; // Create variables required for impersonation handling. IntPtr token = IntPtr.Zero; Win32.StartupInfo startupInfo = new Win32.StartupInfo(); Win32.ProcessInformation processInfo = new Win32.ProcessInformation(); try { // Create process startupInfo.cb = Marshal.SizeOf(startupInfo); bool result = Win32.CreateProcessWithLogonW( username, domain, entryManager.ProcessReplacementTags(settings.Password), (uint)logonFlags, application, arguments, 0, IntPtr.Zero, workingDir, ref startupInfo, out processInfo); if (!result) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } catch (Win32Exception ex) { string errorMessage = ex.Message; if ("A logon request contained an invalid logon type value".Equals(errorMessage)) { errorMessage = string.Concat(errorMessage, ". This is usually caused by attempting to use credentials for the network only but not specifying a domain."); } throw new ApplicationExecutionException(errorMessage, ex); } finally { if (processInfo.process != IntPtr.Zero) { Win32.CloseHandle(processInfo.process); } if (processInfo.thread != IntPtr.Zero) { Win32.CloseHandle(processInfo.thread); } } }