//public class ProcessInfo : IDisposable //{ // public readonly uint Id = default; // public IntPtr StdIn { get; internal set; } = default; // public IntPtr StdOut { get; internal set; } = default; // public IntPtr StdErr { get; internal set; } = default; // public readonly Process Process; // internal ProcessInfo(uint id) // { // Id = id; // try // { // Process = Process.GetProcessById((int)Id); // } // catch (System.ArgumentException e)//throws an exception if the process is not running // { } // } // public bool WriteIn(byte[] buffer, int offset, int count) // { // lock (this) // { // if (fileStreamIn == null) // { // if (StdIn == default) // throw new Exception("StdIn is not redirected."); // SafeFileHandle h = new SafeFileHandle(StdIn, true); // fileStreamIn = new FileStream(h, FileAccess.Write, BufferLength); // } // if (!fileStreamIn.CanWrite) // return false; // fileStreamIn.Write(buffer, offset, count); // fileStreamIn.Flush(); // return true; // } // } // FileStream fileStreamIn = null; // public int BufferLength = 4096; // public bool WriteIn2(string m) // { // byte[] buffer = System.Text.Encoding.ASCII.GetBytes(m); // uint dwWritten; // System.Threading.NativeOverlapped o = new System.Threading.NativeOverlapped(); // bool r = Kernel32.WriteFile(new SafeFileHandle(StdIn, true), buffer, (uint)buffer.Length, out dwWritten, ref o); // WinApi.Kernel32.CloseHandle(StdIn); // return r; // } // public bool WriteIn(string m) // { // //byte[] bs = Process.StandardInput.Encoding.GetBytes(m);!!! does not work // byte[] bs = System.Text.Encoding.ASCII.GetBytes(m); // return WriteIn(bs, 0, bs.Length); // } // public int ReadOut(byte[] buffer, int offset, int count) // { // lock (this) // { // if (fileStreamOut == null) // { // if (StdOut == default) // throw new Exception("StdOut is not redirected."); // SafeFileHandle h = new SafeFileHandle(StdOut, true); // fileStreamOut = new FileStream(h, FileAccess.Read, BufferLength, false); // } // if (!fileStreamOut.CanRead) // return -1; // return fileStreamOut.Read(buffer, offset, count); // } // } // FileStream fileStreamOut = null; // System.Text.Encoding encoding // { // get // { // if (_encoding == null) // _encoding = System.Text.Encoding.GetEncoding(Kernel32.GetConsoleOutputCP()); // return _encoding; // } // } // System.Text.Encoding _encoding = null; // public string ReadOut(int count) // { // byte[] bs = new byte[count]; // int r = ReadOut(bs, 0, count); // return encoding.GetString(bs, 0, r); // } // //public string ReadOut(int count) // //{ // // byte[] bs = new byte[count]; // // uint r; // // System.Threading.NativeOverlapped o = new System.Threading.NativeOverlapped(); // // //Kernel32.ReadFile(new SafeFileHandle(StdOut, true), bs, 100, out r, ref o); // // bool c = Kernel32.ReadFile(StdOut, bs, (uint)count, out r, ref o); // // return System.Text.Encoding.ASCII.GetString(bs, 0, (int)r); // //} // public int ReadErr(byte[] buffer, int offset, int count) // { // lock (this) // { // if (fileStreamErr == null) // fileStreamErr = new FileStream(new SafeFileHandle(StdErr, true), FileAccess.Read); // if (!fileStreamErr.CanRead) // return -1; // return fileStreamErr.Read(buffer, offset, count); // } // } // FileStream fileStreamErr = null; // public string ReadErr(int count) // { // byte[] bs = new byte[count]; // int r = ReadErr(bs, 0, count); // return encoding.GetString(bs, 0, r); // } // ~ProcessInfo() // { // Dispose(); // } // public void Dispose() // { // lock (this) // { // if (StdIn != default) // { // Kernel32.CloseHandle(StdIn); // if (fileStreamIn != null) // { // fileStreamIn.Close(); // fileStreamIn = null; // } // } // if (StdOut != default) // { // Kernel32.CloseHandle(StdOut); // if (fileStreamOut != null) // { // fileStreamOut.Close(); // fileStreamOut = null; // } // } // if (StdErr != default) // { // Kernel32.CloseHandle(StdErr); // if (fileStreamErr != null) // { // fileStreamErr.Close(); // fileStreamErr = null; // } // } // } // } //} public static int CreateProcess(ProcessParameters processParameters) { try { Advapi32.STARTUPINFO si = new Advapi32.STARTUPINFO(); si.hStdInput = processParameters.StdIn != null ? processParameters.StdIn : new SafeFileHandle(Kernel32.GetStdHandle(Kernel32.StdHandles.STD_INPUT_HANDLE), true); si.hStdOutput = processParameters.StdOut != null ? processParameters.StdOut : new SafeFileHandle(Kernel32.GetStdHandle(Kernel32.StdHandles.STD_OUTPUT_HANDLE), true); si.hStdError = processParameters.StdErr != null ? processParameters.StdErr : new SafeFileHandle(Kernel32.GetStdHandle(Kernel32.StdHandles.STD_ERROR_HANDLE), true); if (processParameters.StdIn != null || processParameters.StdOut != null || processParameters.StdErr != null) { si.dwFlags |= Advapi32.dwFlags.STARTF_USESTDHANDLES; } si.dwFlags |= Advapi32.dwFlags.STARTF_USESHOWWINDOW; //it is needed if hiding the window when CREATE_NEW_CONSOLE si.wShowWindow = (short)(!processParameters.ShowWindow ? User32.SW.SW_HIDE : User32.SW.SW_SHOW); //what does it do??? //si.lpDesktop = "winsta0\\default"; SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); if (processParameters.StdIn != null || processParameters.StdOut != null || processParameters.StdErr != null) { sa.bInheritHandle = true; } Advapi32.CreationFlags creationFlags = 0; //|=Advapi32.CreationFlags.CREATE_UNICODE_ENVIRONMENT if (processParameters.NewConsole) { creationFlags |= Advapi32.CreationFlags.CREATE_NEW_CONSOLE; } if (!processParameters.ShowWindow) { creationFlags |= Advapi32.CreationFlags.CREATE_NO_WINDOW; } Advapi32.PROCESS_INFORMATION pi = new Advapi32.PROCESS_INFORMATION(); if (!Advapi32.CreateProcess( processParameters.Executable, // file to execute processParameters.Arguments, // command line null, // pointer to process SECURITY_ATTRIBUTES null, // pointer to thread SECURITY_ATTRIBUTES true, // handles are inheritable creationFlags, // creation flags IntPtr.Zero, // pointer to new environment block; NULL = use parent's environment Environment.CurrentDirectory, // name of current directory; NULL = use parent's current directory si, // pointer to STARTUPINFO structure pi // receives information about new process )) { throw new LastErrorException("!CreateProcess()"); } return(pi.dwProcessId); } finally { } }
static int createProcessAsUser(string cmdLine, IntPtr hToken, IntPtr envBlock) { try { SECURITY_ATTRIBUTES saProcess = new SECURITY_ATTRIBUTES(); SECURITY_ATTRIBUTES saThread = new SECURITY_ATTRIBUTES(); saProcess.nLength = Marshal.SizeOf(saProcess); saThread.nLength = Marshal.SizeOf(saThread); Advapi32.STARTUPINFO si = new Advapi32.STARTUPINFO(); si.cb = Marshal.SizeOf(si); //if this member is NULL, the new process inherits the desktop //and window station of its parent process. If this member is //an empty string, the process does not inherit the desktop and //window station of its parent process; instead, the system //determines if a new desktop and window station need to be created. //If the impersonated user already has a desktop, the system uses the //existing desktop. //si.lpDesktop = @"WinSta0\Default"; //Modify as needed si.dwFlags = Advapi32.dwFlags.STARTF_USESHOWWINDOW | Advapi32.dwFlags.STARTF_FORCEONFEEDBACK; si.wShowWindow = WinApi.User32.SW_SHOW; Advapi32.PROCESS_INFORMATION pi = new Advapi32.PROCESS_INFORMATION(); if (!Advapi32.CreateProcessAsUser( hToken, null, cmdLine, saProcess, saThread, false, WinApi.Advapi32.CreationFlags.CREATE_UNICODE_ENVIRONMENT, envBlock, null, si, pi )) { throw new Exception("!CreateProcessAsUser()", ErrorRoutines.GetLastError()); } return(pi.dwProcessId); } //catch(Exception e) //{ //} finally { } }
/// <summary> /// Run a process in the specified logon session as the user of the current process. /// </summary> /// <param name="dwSessionId">ID of the logon session where the process is to run</param> /// <param name="processParameters"></param> /// <returns></returns> public static int CreateProcessAsUserOfCurrentProcess(uint dwSessionId, ProcessParameters processParameters) { IntPtr hNewProcessToken = IntPtr.Zero; IntPtr hProcessToken = IntPtr.Zero; try { if (!Advapi32.OpenProcessToken(Process.GetCurrentProcess().Handle, Advapi32.DesiredAccess.MAXIMUM_ALLOWED, out hProcessToken)) { throw new LastErrorException("!OpenProcessToken()"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = true; if (!Advapi32.DuplicateTokenEx(hProcessToken, Advapi32.DesiredAccess.MAXIMUM_ALLOWED, sa, Advapi32.SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, Advapi32.TOKEN_TYPE.TokenPrimary, out hNewProcessToken)) { throw new LastErrorException("!DuplicateTokenEx()"); } //is it needed to specify in which logon session the process is to run //!!!it usually needs to run with SYSTEM priviledges if (!Advapi32.SetTokenInformation(hNewProcessToken, WinApi.Advapi32.TOKEN_INFORMATION_CLASS.TokenSessionId, ref dwSessionId, (uint)IntPtr.Size)) { throw new LastErrorException("!SetTokenInformation()"); } Advapi32.STARTUPINFO si = new Advapi32.STARTUPINFO(); //si.lpDesktop = "winsta0\\default"; si.wShowWindow = (short)(processParameters.ShowWindow ? User32.SW.SW_SHOW : User32.SW.SW_HIDE);//what does it do??? Advapi32.CreationFlags creationFlags = processParameters.ShowWindow ? 0 : Advapi32.CreationFlags.CREATE_NO_WINDOW; Advapi32.PROCESS_INFORMATION pi = new Advapi32.PROCESS_INFORMATION(); if (!Advapi32.CreateProcessAsUser( hNewProcessToken, // client's access token processParameters.Executable, // file to execute processParameters.Arguments, // command line null, // process SECURITY_ATTRIBUTES null, // thread SECURITY_ATTRIBUTES false, // You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the process in the same session as the caller. creationFlags, // creation flags IntPtr.Zero, // pointer to new environment block processParameters.CurrentDirectory, // name of current directory si, // pointer to STARTUPINFO structure pi // receives information about new process )) { throw new Exception("!CreateProcessAsUser()", ErrorRoutines.GetLastError()); } return(pi.dwProcessId); } finally { if (hProcessToken != IntPtr.Zero) { Kernel32.CloseHandle(hProcessToken); } if (hNewProcessToken != IntPtr.Zero) { Kernel32.CloseHandle(hNewProcessToken); } } }
/// <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); } }