C ProcessAsUser


 class Interop
    {
        public static void CreateProcess(string app, string path)
        {
            bool result;
            IntPtr hToken = WindowsIdentity.GetCurrent().Token;
            IntPtr hDupedToken = IntPtr.Zero;

            PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            sa.Length = Marshal.SizeOf(sa);

            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);

            int dwSessionID = WTSGetActiveConsoleSessionId();
            result = WTSQueryUserToken(dwSessionID, out hToken);

            if (!result)
            {
                ShowMessageBox("WTSQueryUserToken failed", "AlertService Message");
            }

            result = DuplicateTokenEx(
                   hToken,
                   GENERIC_ALL_ACCESS,
                   ref sa,
                   (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                   (int)TOKEN_TYPE.TokenPrimary,
                   ref hDupedToken
                );

            if (!result)
            {
                ShowMessageBox("DuplicateTokenEx failed", "AlertService Message");
            }

            IntPtr lpEnvironment = IntPtr.Zero;
            result = CreateEnvironmentBlock(out lpEnvironment, hDupedToken, false);

            if (!result)
            {
                ShowMessageBox("CreateEnvironmentBlock failed", "AlertService Message");
            }

            result = CreateProcessAsUser(
                                  hDupedToken,
                                  app,
                                  String.Empty,
                                  ref sa, ref sa,
                                  false, 0, IntPtr.Zero,
                                  null, ref si, ref pi);

            if (!result)
            {
                int error = Marshal.GetLastWin32Error();
                string message = String.Format("CreateProcessAsUser Error: {0}", error);
                ShowMessageBox(message, "AlertService Message");
            }

            if (pi.hProcess != IntPtr.Zero)
                CloseHandle(pi.hProcess);
            if (pi.hThread != IntPtr.Zero)
                CloseHandle(pi.hThread);
            if (hDupedToken != IntPtr.Zero)
                CloseHandle(hDupedToken);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public Int32 dwProcessID;
            public Int32 dwThreadID;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public Int32 Length;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        public enum SECURITY_IMPERSONATION_LEVEL
        {
            SecurityAnonymous,
            SecurityIdentification,
            SecurityImpersonation,
            SecurityDelegation
        }

        public enum TOKEN_TYPE
        {
            TokenPrimary = 1,
            TokenImpersonation
        }

        public const int GENERIC_ALL_ACCESS = 0x10000000;

        [DllImport("kernel32.dll", SetLastError = true,
             CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool CloseHandle(IntPtr handle);

        [DllImport("advapi32.dll", SetLastError = true,
             CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern bool CreateProcessAsUser(
            IntPtr hToken,
            string lpApplicationName,
            string lpCommandLine,
            ref SECURITY_ATTRIBUTES lpProcessAttributes,
            ref SECURITY_ATTRIBUTES lpThreadAttributes,
            bool bInheritHandle,
            Int32 dwCreationFlags,
            IntPtr lpEnvrionment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            ref PROCESS_INFORMATION lpProcessInformation);

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool DuplicateTokenEx(
            IntPtr hExistingToken,
            Int32 dwDesiredAccess,
            ref SECURITY_ATTRIBUTES lpThreadAttributes,
            Int32 ImpersonationLevel,
            Int32 dwTokenType,
            ref IntPtr phNewToken);

        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSQueryUserToken(
            Int32 sessionId,
            out IntPtr Token);

        [DllImport("userenv.dll", SetLastError = true)]
        static extern bool CreateEnvironmentBlock(
            out IntPtr lpEnvironment,
            IntPtr hToken,
            bool bInherit);

        public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
        public static void ShowMessageBox(string message, string title)
        {
            int resp = 0;
            WTSSendMessage(
                WTS_CURRENT_SERVER_HANDLE,
                WTSGetActiveConsoleSessionId(),
                title, title.Length,
                message, message.Length,
                0, 0, out resp, false);
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int WTSGetActiveConsoleSessionId();

        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSSendMessage(
            IntPtr hServer,
            int SessionId,
            String pTitle,
            int TitleLength,
            String pMessage,
            int MessageLength,
            int Style,
            int Timeout,
            out int pResponse,
            bool bWait);
    }
View Code

[StructLayout(LayoutKind.Sequential)]
         struct STARTUPINFO
         {
             public Int32 cb;
             [MarshalAs(UnmanagedType.LPTStr)]
             public String lpReserved;
            [MarshalAs(UnmanagedType.LPTStr)]
             public String lpDesktop;
             [MarshalAs(UnmanagedType.LPTStr)]
             public String lpTitle;
             public UInt32 dwX;
            public UInt32 dwY;
            public UInt32 dwXSize;
             public UInt32 dwYSize;
             public UInt32 dwXCountChars;
             public UInt32 dwYCountChars;
             public UInt32 dwFillAttribute;
             public UInt32 dwFlags;
             public Int16 wShowWindow;
             public Int16 cbReserved2;
             public IntPtr lpReserved2;
             public HandleRef hStdInput;
             public HandleRef hStdOutput;
             public HandleRef hStdError;
         }
 
         const int NORMAL_PRIORITY_CLASS = 0x00000020;
 
         struct PROCESS_INFORMATION
         {
             public HandleRef hProcess;
             public HandleRef hThread;
             public UInt32 dwProcessId;
             public UInt32 dwThreadId;
         }
 
         struct SECURITY_ATTRIBUTES
         {
             public UInt32 nLength;
             public IntPtr lpSecurityDescriptor;
             public Boolean bInheritHandle;
         }
 
         [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
         static extern Boolean CreateProcessAsUser(
         IntPtr hToken,
         String lpApplicationName,
         String lpCommandLine,
         IntPtr lpProcessAttributes,
         IntPtr lpThreadAttributes,
        Boolean bInheritHandles,
        UInt32 dwCreationFlags,
         IntPtr lpEnvironment,
         String lpCurrentDirectory,
         ref STARTUPINFO lpStartupInfo,
         out PROCESS_INFORMATION lpProcessInformation);
 
         [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
         static extern Boolean LogonUser(
         String lpszUsername,
         String lpszDomain,
         String lpszPassword,
         Int32 dwLogonType,
         Int32 dwLogonProvider,
         ref IntPtr phToken
         );
         const int LOGON32_LOGON_INTERACTIVE = 2;
 
         public void Execute(string File)
         {
             try
             {
                 //unsafe
                 {
                     PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
 
                     STARTUPINFO si = new STARTUPINFO();
                     si.cb = Marshal.SizeOf(si);
                     si.lpDesktop = "winsta0\default";
 
                     IntPtr hToken = new IntPtr(0);
                     if (LogonUser("auser", "mydomain", "Passw0rd!",
                         LOGON32_LOGON_INTERACTIVE, 0, ref hToken))
                     {
                         Boolean bResult = CreateProcessAsUser(
                             hToken,
                             File, // file to execute
                             null, // command line
                             IntPtr.Zero, // pointer to process SECURITY_ATTRIBUTES
                             IntPtr.Zero, // pointer to thread SECURITY_ATTRIBUTES
                             false, // handles are not inheritable
                             0, // creation flags
                             IntPtr.Zero, // pointer to new environment block
                             null, // name of current directory
                             ref si, // pointer to STARTUPINFO structure
                             out pi // receives information about new process
                             );
 
                         if (bResult)
                         {
                         }
                     }
                 }
             }
             catch(Exception e)
             {
             }
         }
View Code


 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;

namespace WindowsService1
{
    public class WinAPI_Interop
    {
        public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
        /// <summary>
        /// 服务程序执行消息提示,前台MessageBox.Show
        /// </summary>
        /// <param name="message">消息内容</param>
        /// <param name="title">标题</param>
        public static void ShowServiceMessage(string message, string title)
        {
            int resp = 0;
            WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTSGetActiveConsoleSessionId(), title, title.Length, message, message.Length, 0, 0, out resp, false);
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int WTSGetActiveConsoleSessionId();

        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSSendMessage(IntPtr hServer, int SessionId, String pTitle, int TitleLength, String pMessage, int MessageLength,int Style, int Timeout, out int pResponse, bool bWait);
        #region P/Invoke WTS APIs
        private enum WTS_CONNECTSTATE_CLASS
        {
            WTSActive,
            WTSConnected,
            WTSConnectQuery,
            WTSShadow,
            WTSDisconnected,
            WTSIdle,
            WTSListen,
            WTSReset,
            WTSDown,
            WTSInit
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct WTS_SESSION_INFO
        {
            public UInt32 SessionID;
            public string pWinStationName;
            public WTS_CONNECTSTATE_CLASS State;
        }

        [DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool WTSEnumerateSessions(
            IntPtr hServer,
            [MarshalAs(UnmanagedType.U4)] UInt32 Reserved,
            [MarshalAs(UnmanagedType.U4)] UInt32 Version,
            ref IntPtr ppSessionInfo,
            [MarshalAs(UnmanagedType.U4)] ref UInt32 pSessionInfoCount
            );

        [DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
        static extern void WTSFreeMemory(IntPtr pMemory);

        [DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool WTSQueryUserToken(UInt32 sessionId, out IntPtr Token);
        #endregion

        #region P/Invoke CreateProcessAsUser
        /// <summary> 
        /// Struct, Enum and P/Invoke Declarations for CreateProcessAsUser. 
        /// </summary> 
        ///  

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct STARTUPINFO
        {
            public Int32 cb;
            public string lpReserved;
            public string lpDesktop;
            public string lpTitle;
            public Int32 dwX;
            public Int32 dwY;
            public Int32 dwXSize;
            public Int32 dwYSize;
            public Int32 dwXCountChars;
            public Int32 dwYCountChars;
            public Int32 dwFillAttribute;
            public Int32 dwFlags;
            public Int16 wShowWindow;
            public Int16 cbReserved2;
            public IntPtr lpReserved2;
            public IntPtr hStdInput;
            public IntPtr hStdOutput;
            public IntPtr hStdError;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct PROCESS_INFORMATION
        {
            public IntPtr hProcess;
            public IntPtr hThread;
            public int dwProcessId;
            public int dwThreadId;
        }

        /// <summary>
        /// 以当前登录的windows用户(角色权限)运行指定程序进程
        /// </summary>
        /// <param name="hToken"></param>
        /// <param name="lpApplicationName">指定程序(全路径)</param>
        /// <param name="lpCommandLine">参数</param>
        /// <param name="lpProcessAttributes">进程属性</param>
        /// <param name="lpThreadAttributes">线程属性</param>
        /// <param name="bInheritHandles"></param>
        /// <param name="dwCreationFlags"></param>
        /// <param name="lpEnvironment"></param>
        /// <param name="lpCurrentDirectory"></param>
        /// <param name="lpStartupInfo">程序启动属性</param>
        /// <param name="lpProcessInformation">最后返回的进程信息</param>
        /// <returns>是否调用成功</returns>
        [DllImport("ADVAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool CreateProcessAsUser(IntPtr hToken,string lpApplicationName,string lpCommandLine,IntPtr lpProcessAttributes,IntPtr lpThreadAttributes,
                                                      bool bInheritHandles,uint dwCreationFlags,string lpEnvironment,string lpCurrentDirectory,
                                                      ref STARTUPINFO lpStartupInfo,out PROCESS_INFORMATION lpProcessInformation);

        [DllImport("KERNEL32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool CloseHandle(IntPtr hHandle);
        #endregion

        /// <summary>
        /// 以当前登录系统的用户角色权限启动指定的进程
        /// </summary>
        /// <param name="ChildProcName">指定的进程(全路径)</param>
        public static void CreateProcess(string ChildProcName)
        {
            IntPtr ppSessionInfo = IntPtr.Zero;
            UInt32 SessionCount = 0;
            if (WTSEnumerateSessions(
                                    (IntPtr)WTS_CURRENT_SERVER_HANDLE,  // Current RD Session Host Server handle would be zero. 
                                    0,  // This reserved parameter must be zero. 
                                    1,  // The version of the enumeration request must be 1. 
                                    ref ppSessionInfo, // This would point to an array of session info. 
                                    ref SessionCount  // This would indicate the length of the above array.
                                    ))
            {
                for (int nCount = 0; nCount < SessionCount; nCount++)
                {
                    WTS_SESSION_INFO tSessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(ppSessionInfo + nCount * Marshal.SizeOf(typeof(WTS_SESSION_INFO)), typeof(WTS_SESSION_INFO));
                    if (WTS_CONNECTSTATE_CLASS.WTSActive == tSessionInfo.State)
                    {
                        IntPtr hToken = IntPtr.Zero;
                        if (WTSQueryUserToken(tSessionInfo.SessionID, out hToken))
                        {
                            PROCESS_INFORMATION tProcessInfo;
                            STARTUPINFO tStartUpInfo = new STARTUPINFO();
                            tStartUpInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
                            bool ChildProcStarted = CreateProcessAsUser(
                                                                        hToken,             // Token of the logged-on user. 
                                                                        ChildProcName,      // Name of the process to be started. 
                                                                        null,               // Any command line arguments to be passed. 
                                                                        IntPtr.Zero,        // Default Process' attributes. 
                                                                        IntPtr.Zero,        // Default Thread's attributes. 
                                                                        false,              // Does NOT inherit parent's handles. 
                                                                        0,                  // No any specific creation flag. 
                                                                        null,               // Default environment path. 
                                                                        null,               // Default current directory. 
                                                                        ref tStartUpInfo,   // Process Startup Info.  
                                                                        out tProcessInfo    // Process information to be returned. 
                                                     );
                            if (ChildProcStarted)
                            {
                                CloseHandle(tProcessInfo.hThread);
                                CloseHandle(tProcessInfo.hProcess);
                            }
                            else
                            {
                                ShowServiceMessage("CreateProcessAsUser失败", "CreateProcess");
                            }
                            CloseHandle(hToken);
                            break;
                        }
                    }
                }
                WTSFreeMemory(ppSessionInfo);
            }
        }
    }
}
View Code

OnStart(string[] args) { //Interop.ShowMessageBox("This a message from AlertService.","AlertService Message");
            WinAPI_Interop.CreateProcess(@"E:workoxGreenlandBoxBinFilesClientBinBufferBox.exe"); //Interop.CreateProcess("cmd.exe", @"C:WindowsSystem32");
}

-----------------------------------------------------------------------------

do
    {
//         if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hThisToken ))
//         {
//             PrintfDbgStr(TEXT("OpenProcessToken error !error code:%d
"),GetLastError());
//             bSuccess = FALSE;
//             break;
//         }
//         if(!SetPrivilege(hThisToken,SE_TCB_NAME,TRUE))
//         {
//             PrintfDbgStr(TEXT("SetPrivilege error !error code:%d
"),GetLastError());
//             bSuccess = FALSE;
//             break;
//         }
        DWORD dwSessionId = WTSGetActiveConsoleSessionId();
        if(!WTSQueryUserToken(dwSessionId,&hToken))
        {
            PrintfDbgStr(TEXT("WTSQueryUserToken error !error code:%d
"),GetLastError());
            bSuccess = FALSE;
            break;
        }

        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        ZeroMemory(&si,sizeof(STARTUPINFO));
        ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
        si.cb = sizeof(STARTUPINFO);
        si.lpDesktop = _T("WinSta0\Default");
        si.wShowWindow = TRUE;
        si.dwFlags     = STARTF_USESHOWWINDOW;

        LPVOID pEnv = NULL;
        DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
        if(!CreateProcessAsUser(hToken,NULL,pBuf,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi))
        {
            PrintfDbgStr(TEXT("CreateProcessAsUser error !error code:%d
"),GetLastError());
            bSuccess = FALSE;
            break;
        }
        
    }while(0);
View Code

创建的进程不是管理员权限的,因为是调用了用户的令牌创建的进程。

HANDLE hToken = NULL;
    HANDLE hTokenDup = NULL;
    do 
    {
        if(OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hToken))
        {
            if(DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS,NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
            {
                DWORD dwSessionId = WTSGetActiveConsoleSessionId();
                if(!SetTokenInformation(hTokenDup,TokenSessionId,&dwSessionId,sizeof(DWORD)))
                {
                    PrintfDbgStr(TEXT("SetTokenInformation error !error code:%d
"),GetLastError());
                    bSuccess = FALSE;
                    break;
                }

                STARTUPINFO si;
                PROCESS_INFORMATION pi;
                ZeroMemory(&si,sizeof(STARTUPINFO));
                ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
                si.cb = sizeof(STARTUPINFO);
                si.lpDesktop = _T("WinSta0\Default");
                si.wShowWindow = SW_SHOW;
                si.dwFlags     =   STARTF_USESHOWWINDOW /*|STARTF_USESTDHANDLES*/;

                LPVOID pEnv = NULL;
                DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
                if(!CreateEnvironmentBlock(&pEnv,hTokenDup,FALSE))
                {
                    PrintfDbgStr(TEXT("CreateEnvironmentBlock error !error code:%d
"),GetLastError());
                    bSuccess = FALSE;
                    break;
                }

                if(!CreateProcessAsUser(hTokenDup,NULL,pBuf,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi))
                {
                    PrintfDbgStr(TEXT("CreateProcessAsUser error !error code:%d
"),GetLastError());
                    bSuccess = FALSE;
                    break;
                }

                if(pEnv)
                {
                    DestroyEnvironmentBlock(pEnv);
                }
            }
            else
            {
                PrintfDbgStr(TEXT("DuplicateTokenEx error !error code:%d
"),GetLastError());
                bSuccess = FALSE;
                break;
            }

                
        }
        else
        {
            PrintfDbgStr(TEXT("cannot get administror!error code:%d
"),GetLastError());
            bSuccess = FALSE;
            break;
        }
    }while(0);

    if(hTokenDup != NULL && hTokenDup != INVALID_HANDLE_VALUE)
        CloseHandle(hTokenDup);
    if(hToken != NULL && hToken != INVALID_HANDLE_VALUE)
        CloseHandle(hToken);
View Code

管理员权限  注意dwCreationFlag和si的参数设定

原文地址:https://www.cnblogs.com/xiangxiong/p/7661312.html