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); }
[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) { } }
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); } } } }
OnStart(string[] args) { //Interop.ShowMessageBox("This a message from AlertService.","AlertService Message");
WinAPI_Interop.CreateProcess(@"E:\work\box\GreenlandBox\BinFiles\ClientBin\BufferBox.exe");
//Interop.CreateProcess("cmd.exe", @"C:\Windows\System32\");
}
-----------------------------------------------------------------------------
do { // if (!OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hThisToken )) // { // PrintfDbgStr(TEXT("OpenProcessToken error !error code:%d\n"),GetLastError()); // bSuccess = FALSE; // break; // } // if(!SetPrivilege(hThisToken,SE_TCB_NAME,TRUE)) // { // PrintfDbgStr(TEXT("SetPrivilege error !error code:%d\n"),GetLastError()); // bSuccess = FALSE; // break; // } DWORD dwSessionId = WTSGetActiveConsoleSessionId(); if(!WTSQueryUserToken(dwSessionId,&hToken)) { PrintfDbgStr(TEXT("WTSQueryUserToken error !error code:%d\n"),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\n"),GetLastError()); bSuccess = FALSE; break; } }while(0);
创建的进程不是管理员权限的,因为是调用了用户的令牌创建的进程。
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\n"),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\n"),GetLastError()); bSuccess = FALSE; break; } if(!CreateProcessAsUser(hTokenDup,NULL,pBuf,NULL,NULL,FALSE,dwCreationFlag,pEnv,NULL,&si,&pi)) { PrintfDbgStr(TEXT("CreateProcessAsUser error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } if(pEnv) { DestroyEnvironmentBlock(pEnv); } } else { PrintfDbgStr(TEXT("DuplicateTokenEx error !error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } } else { PrintfDbgStr(TEXT("cannot get administror!error code:%d\n"),GetLastError()); bSuccess = FALSE; break; } }while(0); if(hTokenDup != NULL && hTokenDup != INVALID_HANDLE_VALUE) CloseHandle(hTokenDup); if(hToken != NULL && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
管理员权限 注意dwCreationFlag和si的参数设定