Ejemplo n.º 1
0
        /// <summary>
        /// 此函数以低完整性级别启动一个应用程序
        /// </summary>
        /// <param name="commandLine">
        /// 需要被执行的命令行。此字符串最长为32K个字符。
        /// </param>
        /// <remarks>
        /// 启动一个低完整性进程
        /// 1) 复制当前进程的句柄,它拥有中完整性级别
        /// 2)使用SetTokenInformation设置访问进程的完整性级别为低。
        /// 3)使用CreateProcessAsUser及低完整性级别的访问令牌创建一个新的进程。
        /// </remarks>
        internal void CreateLowIntegrityProcess(string commandLine)
        {
            SafeTokenHandle hToken = null;
            SafeTokenHandle hNewToken = null;
            string strIntegritySid = "S-1-16-4096";  // Low integrity SID string 低完整性SID字符串
            IntPtr pIntegritySid = IntPtr.Zero;
            int cbTokenInfo = 0;
            IntPtr pTokenInfo = IntPtr.Zero;
            STARTUPINFO si = new STARTUPINFO();
            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();

            try
            {
                // 打开进程的主访问令牌。
                if (!NativeMethod.OpenProcessToken(Process.GetCurrentProcess().Handle,
                    NativeMethod.TOKEN_DUPLICATE | NativeMethod.TOKEN_ADJUST_DEFAULT |
                    NativeMethod.TOKEN_QUERY | NativeMethod.TOKEN_ASSIGN_PRIMARY,
                    out hToken))
                {
                    throw new Win32Exception();
                }

                // 复制当前进程的主令牌。
                if (!NativeMethod.DuplicateTokenEx(hToken, 0, IntPtr.Zero,
                    SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    TOKEN_TYPE.TokenPrimary, out hNewToken))
                {
                    throw new Win32Exception();
                }

                // 创建低完整性SID。
                if (!NativeMethod.ConvertStringSidToSid(strIntegritySid,
                    out pIntegritySid))
                {
                    throw new Win32Exception();
                }

                TOKEN_MANDATORY_LABEL tml;
                tml.Label.Attributes = NativeMethod.SE_GROUP_INTEGRITY;
                tml.Label.Sid = pIntegritySid;

                // 转换TOKEN_MANDATORY_LABEL结构至native内存。
                cbTokenInfo = Marshal.SizeOf(tml);
                pTokenInfo = Marshal.AllocHGlobal(cbTokenInfo);
                Marshal.StructureToPtr(tml, pTokenInfo, false);

                // 设置访问令牌的完整性级别为低。
                if (!NativeMethod.SetTokenInformation(hNewToken,
                    TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenInfo,
                    cbTokenInfo + NativeMethod.GetLengthSid(pIntegritySid)))
                {
                    throw new Win32Exception();
                }

                // 以低完整性级别创建一个新进程。
                si.cb = Marshal.SizeOf(si);
                if (!NativeMethod.CreateProcessAsUser(hNewToken, null, commandLine,
                    IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, null, ref si,
                    out pi))
                {
                    throw new Win32Exception();
                }
            }
            finally
            {
                // 集中清理已分配的资源
                if (hToken != null)
                {
                    hToken.Close();
                    hToken = null;
                }
                if (hNewToken != null)
                {
                    hNewToken.Close();
                    hNewToken = null;
                }
                if (pIntegritySid != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pIntegritySid);
                    pIntegritySid = IntPtr.Zero;
                }
                if (pTokenInfo != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pTokenInfo);
                    pTokenInfo = IntPtr.Zero;
                    cbTokenInfo = 0;
                }
                if (pi.hProcess != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hProcess);
                    pi.hProcess = IntPtr.Zero;
                }
                if (pi.hThread != IntPtr.Zero)
                {
                    NativeMethod.CloseHandle(pi.hThread);
                    pi.hThread = IntPtr.Zero;
                }
            }
        }
Ejemplo n.º 2
0
 public static extern bool CreateProcessAsUser(
     SafeTokenHandle hToken,
     string applicationName,
     string commandLine,
     IntPtr pProcessAttributes,
     IntPtr pThreadAttributes,
     bool bInheritHandles,
     uint dwCreationFlags,
     IntPtr pEnvironment,
     string currentDirectory,
     ref STARTUPINFO startupInfo,
     out PROCESS_INFORMATION processInformation);