/// <summary> /// Starts a process with a low integrity level /// </summary> /// <param name="executableFileName">Path and filename of executable.</param> /// <param name="args">Command line arguments</param> /// <returns>The new running process</returns> /// <exception cref="T:System.ComponentModel.Win32Exception">Any errors creating the process</exception> public static Process Start(string executableFileName, string args) { SafeTokenHandle hToken = SafeTokenHandle.InvalidHandle; SafeTokenHandle newToken = SafeTokenHandle.InvalidHandle; // Get the current token if (Win32Native.OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessLevels.MaximumAllowed, ref hToken)) { using (hToken) { // Make a copy if (Win32Native.DuplicateTokenEx(hToken, TokenAccessLevels.MaximumAllowed, IntPtr.Zero, Win32Native.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, Win32Native.TokenType.TokenPrimary, ref newToken)) { using (newToken) { // Get the Low Integrity SID as a PSID SafeLocalMemHandle sid; if (Win32Native.ConvertStringSidToSid(LowIntegritySid, out sid)) { using (sid) { // Create the low integrity label Win32Native.TOKEN_MANDATORY_LABEL til = new Win32Native.TOKEN_MANDATORY_LABEL(); til.Label.Attributes = Win32Native.SE_GROUP_INTEGRITY; til.Label.Sid = sid; int sidLen = Win32Native.GetLengthSid(sid); int size = Marshal.SizeOf(til); // Set low integrity label on the token if (Win32Native.SetTokenInformation(newToken, Win32Native.TOKEN_INFORMATION_CLASS. TokenIntegrityLevel, til, size + sidLen)) { Win32Native.STARTUPINFO startup = new Win32Native.STARTUPINFO(); Win32Native.PROCESS_INFORMATION info = new Win32Native.PROCESS_INFORMATION(); string cmdLine = BuildCommandLine(executableFileName, args); // Spawn the process if (Win32Native.CreateProcessAsUser(newToken, null, cmdLine, null, null, false, 0, IntPtr.Zero, null, startup, info)) { return Process.GetProcessById(info.dwProcessId); } } } // free sid } } // using newToken } } // using hToken } // If we get here, then one of the Win32 API's failed -- get the error and throw int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error); }
/// <summary> /// Starts a process with a low integrity level /// </summary> /// <param name="executableFileName">Path and filename of executable.</param> /// <param name="args">Command line arguments</param> /// <returns>The new running process</returns> /// <exception cref="T:System.ComponentModel.Win32Exception">Any errors creating the process</exception> public static Process Start(string executableFileName, string args) { SafeTokenHandle hToken = SafeTokenHandle.InvalidHandle; SafeTokenHandle newToken = SafeTokenHandle.InvalidHandle; // Get the current token if (Win32Native.OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessLevels.MaximumAllowed, ref hToken)) { using (hToken) { // Make a copy if (Win32Native.DuplicateTokenEx(hToken, TokenAccessLevels.MaximumAllowed, IntPtr.Zero, Win32Native.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, Win32Native.TokenType.TokenPrimary, ref newToken)) { using (newToken) { // Get the Low Integrity SID as a PSID SafeLocalMemHandle sid; if (Win32Native.ConvertStringSidToSid(LowIntegritySid, out sid)) { using (sid) { // Create the low integrity label Win32Native.TOKEN_MANDATORY_LABEL til = new Win32Native.TOKEN_MANDATORY_LABEL(); til.Label.Attributes = Win32Native.SE_GROUP_INTEGRITY; til.Label.Sid = sid; int sidLen = Win32Native.GetLengthSid(sid); int size = Marshal.SizeOf(til); // Set low integrity label on the token if (Win32Native.SetTokenInformation(newToken, Win32Native.TOKEN_INFORMATION_CLASS. TokenIntegrityLevel, til, size + sidLen)) { Win32Native.STARTUPINFO startup = new Win32Native.STARTUPINFO(); Win32Native.PROCESS_INFORMATION info = new Win32Native.PROCESS_INFORMATION(); string cmdLine = BuildCommandLine(executableFileName, args); // Spawn the process if (Win32Native.CreateProcessAsUser(newToken, null, cmdLine, null, null, false, 0, IntPtr.Zero, null, startup, info)) { return(Process.GetProcessById(info.dwProcessId)); } } } // free sid } } // using newToken } } // using hToken } // If we get here, then one of the Win32 API's failed -- get the error and throw int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error); }