/// <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);
        }
Beispiel #2
0
        /// <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);
        }