internal static extern bool CreateProcessA( string lpApplicationName, string lpCommandLine, Advapi32.SECURITY_ATTRIBUTES lpProcessAttributes, Advapi32.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, Advapi32.ProcessCreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, Advapi32.STARTUPINFO lpStartupInfo, out Advapi32.PROCESS_INFORMATION lpProcessInformation);
/// <summary> /// Spawn a new process that respects tokens and credentials under the criterion /// of the creation flags and command line arguments given. This process will /// write to a named pipe stream given by PipeClient and its results are retrievable /// by the GetOutput enumerator. Once the process has finished executing, the caller /// should call CloseHandles() on this object. /// </summary> /// <param name="lpApplicationName">Application to spawn.</param> /// <param name="lpCommandLine">Any command line arguments to pass to the application.</param> /// <param name="processCreationFlags">Process creation flags to spawn the process with. By default, this is SUSPENDED.</param> /// <param name="useLogon">If true, this will use the current network logon token the agent has.</param> /// <param name="useCredentials">If true, this will first create a new logon session for the current credential set in Token.Cred and use that session to spawn a process.</param> private bool CreateProcess(string lpApplicationName, string lpCommandLine = "", Advapi32.ProcessCreationFlags processCreationFlags = Advapi32.ProcessCreationFlags.CREATE_SUSPENDED, bool useLogon = false, bool useCredentials = false, bool useToken = false) { Advapi32.PROCESS_INFORMATION piProcInfo = new Advapi32.PROCESS_INFORMATION(); Advapi32.STARTUPINFO siStartInfo = new Advapi32.STARTUPINFO(); Advapi32.SECURITY_ATTRIBUTES nullSecAttrs = new Advapi32.SECURITY_ATTRIBUTES(); bool bSuccess; unsafe { siStartInfo.hStdError = PipeClient.SafePipeHandle.DangerousGetHandle(); siStartInfo.hStdOutput = PipeClient.SafePipeHandle.DangerousGetHandle(); siStartInfo.dwFlags = (int)Advapi32.STARTF.STARTF_USESTDHANDLES | (int)Advapi32.STARTF.STARTF_USESHOWWINDOW; siStartInfo.wShowWindow = 0; if (lpCommandLine != "") { lpCommandLine = String.Format("{0} {1}", lpApplicationName, lpCommandLine); //bSuccess = Kernel32.CreateProcessA( // "", // lpCommandLine, // nullSecAttrs, // nullSecAttrs, // true, // processCreationFlags, // IntPtr.Zero, // null, // siStartInfo, // out piProcInfo); } else { lpCommandLine = lpApplicationName; } //else // bSuccess = Kernel32.CreateProcessA( // lpApplicationName, // "", // nullSecAttrs, // nullSecAttrs, // true, // processCreationFlags, // IntPtr.Zero, // null, // siStartInfo, // out piProcInfo); bSuccess = Kernel32.CreateProcessA( null, lpCommandLine, nullSecAttrs, nullSecAttrs, true, processCreationFlags, IntPtr.Zero, null, siStartInfo, out piProcInfo); if (!bSuccess) { return(false); } //hProcess = piProcInfo.hProcess; hProcess = piProcInfo.hProcess; hThread = piProcInfo.hThread; PID = piProcInfo.dwProcessId; return(true); } }
/// <summary> /// Constructor that will spawn a new process using named pipes as its I/O stream. /// If it fails to spawn the designated process, an error will be thrown. /// </summary> /// <param name="lpApplicationName">Application to spawn.</param> /// <param name="lpCommandLine">Any command line arguments to pass to the application.</param> /// <param name="processCreationFlags">Process creation flags to spawn the process with. By default, this is SUSPENDED.</param> /// <param name="useLogon">If true, this will use the current network logon token the agent has.</param> /// <param name="useCredentials">If true, this will first create a new logon session for the current credential set in Token.Cred and use that session to spawn a process.</param> public ProcessWithAnonymousPipeIO(string lpApplicationName, string lpCommandLine = "", Advapi32.ProcessCreationFlags processCreationFlags = Advapi32.ProcessCreationFlags.CREATE_SUSPENDED, bool useLogon = false, bool useCredentials = false, bool useToken = false) { if (useLogon && useCredentials) { throw new Exception("Cannot create a new process using the current logon session and using a set of credentials simultaneously."); } PipeSecurity sec = new PipeSecurity(); sec.SetAccessRule(new PipeAccessRule("Everyone", PipeAccessRights.FullControl, AccessControlType.Allow)); PipeServer = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable, 1024, sec); PipeClient = new AnonymousPipeClientStream(PipeDirection.Out, PipeServer.GetClientHandleAsString()); //PipeServer.ReadTimeout = 10000; if (!CreateProcess(lpApplicationName, lpCommandLine, processCreationFlags, useLogon, useCredentials, useToken)) { CloseHandles(); throw new Exception("Failed to start child process."); } }