public static extern bool DetourCreateProcessWithDllExA( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref NativeMethods.StartupInfo lpStartupInfo, out NativeMethods.ProcessInformation lpProcessInformation, string lpDllName, IntPtr pfCreateProcessA);
public static extern bool DetourCreateProcessWithDllsExW( [MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref NativeMethods.StartupInfo lpStartupInfo, out NativeMethods.ProcessInformation lpProcessInformation, uint nDlls, IntPtr rlpDlls, IntPtr pfCreateProcessW);
public static uint CreateProcess(string userName, string domain, string password, string application, string workingDirectory, bool showMinimized = false) { TraceFactory.Logger.Debug("Creating user process for {0}/{1} - {2}".FormatWith(domain, userName, application)); try { // Default flags for the impersonation startup. NativeMethods.LogonFlags logonFlags = NativeMethods.LogonFlags.LogonWithProfile; NativeMethods.CreationFlags creationFlags = 0; IntPtr environment = IntPtr.Zero; string currentDirectory = workingDirectory; string commandLine = application; NativeMethods.StartupInfo startupInfo = new NativeMethods.StartupInfo(); startupInfo.Cb = Marshal.SizeOf(typeof(NativeMethods.StartupInfo)); if (showMinimized) { startupInfo.Flags = (uint)NativeMethods.StartupInfoFlags.StartfUseShowWindow; startupInfo.ShowWindow = (ushort)NativeMethods.StartupInfoFlags.SWMinimize; } NativeMethods.ProcessInfo processInfo = new NativeMethods.ProcessInfo(); TraceFactory.Logger.Debug("Calling CreateProcessWithLogonW..."); bool created = NativeMethods.CreateProcessWithLogonW(userName, domain, password, logonFlags, null, commandLine, creationFlags, environment, currentDirectory, ref startupInfo, out processInfo); if (created) { TraceFactory.Logger.Debug("Process ({0}) successfully created, closing handles".FormatWith(processInfo.ProcessId)); NativeMethods.CloseHandle(processInfo.ProcessPtr); NativeMethods.CloseHandle(processInfo.ThreadPtr); } else { int error = Marshal.GetLastWin32Error(); var msg = "Unable to create Process, error code {3}: {0}, {1}, {2}".FormatWith(userName, domain, password, error); TraceFactory.Logger.Debug(msg); throw new Exception(msg); } return(processInfo.ProcessId); } catch (Exception ex) { // TODO: Need to do something here... TraceFactory.Logger.Fatal("Failed to create process", ex); throw; } }
public static bool DetourCreateProcessWithDllsExW( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref NativeMethods.StartupInfo lpStartupInfo, out NativeMethods.ProcessInformation lpProcessInformation, uint nDlls, IntPtr rlpDlls, IntPtr pfCreateProcessW) { if (Is64Bit) { return(NativeApi64.DetourCreateProcessWithDllsExW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, out lpProcessInformation, nDlls, rlpDlls, pfCreateProcessW)); } else { return(NativeApi32.DetourCreateProcessWithDllsExW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, out lpProcessInformation, nDlls, rlpDlls, pfCreateProcessW)); } }
private static NativeMethods.ProcessInformation DoCreateProcessWithLogon() { var cmdLine = new StringBuilder(1024); // cmdLine.Append(@"powershell.exe -NoExit -Command ""dir env:"""); // Look at the environment cmdLine.Append(@"cmd.exe /k set"); // Look at the environment var createProcessFlags = NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; /* * NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | * NativeMethods.CreateProcessFlags.CREATE_BREAKAWAY_FROM_JOB | * NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE; */ var startupInfo = new NativeMethods.StartupInfo(); NativeMethods.ProcessInformation pi; if (NativeMethods.CreateProcessWithLogon(userName, ".", password, NativeMethods.LogonFlags.LOGON_WITH_PROFILE, null, cmdLine, createProcessFlags, IntPtr.Zero, workingDir, startupInfo, out pi)) { Console.WriteLine("create-process-with-logon cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); return(pi); } else { throw new Win32Exception(); } }
public bool Start() { processInfo = new NativeMethods.ProcessInformation(); var startInfo = new NativeMethods.StartupInfo(); var success = false; SafeFileHandle hToken, hReadOut, hWriteOut, hReadErr, hWriteErr, hReadIn, hWriteIn; var securityAttributes = new NativeMethods.SecurityAttributes(); securityAttributes.bInheritHandle = true; success = NativeMethods.CreatePipe(out hReadOut, out hWriteOut, securityAttributes, 0); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } success = NativeMethods.CreatePipe(out hReadErr, out hWriteErr, securityAttributes, 0); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } success = NativeMethods.CreatePipe(out hReadIn, out hWriteIn, securityAttributes, 0); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } success = NativeMethods.SetHandleInformation(hReadOut, NativeMethods.Constants.HANDLE_FLAG_INHERIT, 0); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Logon user success = NativeMethods.LogonUser( runSpec.Credentials.UserName, runSpec.Credentials.Domain, runSpec.Credentials.Password, NativeMethods.LogonType.LOGON32_LOGON_BATCH, NativeMethods.LogonProvider.LOGON32_PROVIDER_DEFAULT, out hToken ); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } NativeMethods.LUID privilegeLuid; if (!NativeMethods.LookupPrivilegeValue(null, "SeImpersonatePrivilege", out privilegeLuid)) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, "Error calling LookupPrivilegeValue: " + lastError); } var tokenPrivileges = new NativeMethods.TOKEN_PRIVILEGES(); tokenPrivileges.PrivilegeCount = 1; tokenPrivileges.Attributes = 1; tokenPrivileges.Luid = privilegeLuid; if (!NativeMethods.AdjustTokenPrivileges(hToken, false, ref tokenPrivileges, 1024, IntPtr.Zero, IntPtr.Zero)) { var lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, "Error calling AdjustTokenPrivileges: " + lastError); } IntPtr unmanagedEnv; if (!NativeMethods.CreateEnvironmentBlock(out unmanagedEnv, hToken.DangerousGetHandle(), false)) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, "Error calling CreateEnvironmentBlock: " + lastError); } // Create process startInfo.cb = Marshal.SizeOf(startInfo); startInfo.dwFlags = NativeMethods.Constants.STARTF_USESTDHANDLES; startInfo.hStdOutput = hWriteOut; startInfo.hStdError = hWriteErr; startInfo.hStdInput = hReadIn; success = NativeMethods.CreateProcessWithTokenW( hToken, NativeMethods.LogonFlags.WithProfile, null, CommandLine(), NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT, unmanagedEnv, null, ref startInfo, out processInfo ); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } NativeMethods.DestroyEnvironmentBlock(unmanagedEnv); NativeMethods.CloseHandle(processInfo.hThread); Handle = processInfo.hProcess; startInfo.hStdOutput.Close(); startInfo.hStdError.Close(); startInfo.hStdInput.Close(); StandardOutput = new StreamReader(new FileStream(hReadOut, FileAccess.Read), Console.OutputEncoding); StandardError = new StreamReader(new FileStream(hReadErr, FileAccess.Read), Console.OutputEncoding); StandardInput = new StreamWriter(new FileStream(hWriteIn, FileAccess.Write), Console.InputEncoding) { AutoFlush = true }; WaitForExitAsync(); return(success); }
private void ServiceMain() { const string testFile = @"C:\tmp\test-it.ps1"; File.Delete(testFile); File.WriteAllText(testFile, testPowershellScript); var permissionManager = new DesktopPermissionManager(userName); var startupInfo = new NativeMethods.StartupInfo(); string lpApplicationName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; var cmdLine = new StringBuilder(1024); cmdLine.AppendFormat(@" -InputFormat None -NoLogo -NoProfile -NonInteractive -File {0}", testFile); permissionManager.AddDesktopPermission(); using (var jobObject = new JobObject("StartProcessServiceJobObject")) { jobObject.KillProcessesOnJobClose = true; while (!ct.IsCancellationRequested) { try { log.Debug("Executing command: '{0}'", cmdLine); // Now create the process as the user NativeMethods.ProcessInformation pi; var saProcessAttributes = new NativeMethods.SecurityAttributes(); var saThreadAttributes = new NativeMethods.SecurityAttributes(); var createProcessFlags = NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; IntPtr primaryToken = Utils.LogonAndGetPrimaryToken(userName, password); if (NativeMethods.CreateProcessAsUser(primaryToken, lpApplicationName, cmdLine, saProcessAttributes, saThreadAttributes, false, createProcessFlags, IntPtr.Zero, workingDir, startupInfo, out pi)) { log.Debug("created process: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); jobObject.AddProcess(pi.hProcess); log.Debug("job object has '{0}' processes in it.", jobObject.GetJobProcesses().Count()); NativeMethods.CloseHandle(pi.hProcess); NativeMethods.CloseHandle(pi.hThread); } else { int err = Marshal.GetLastWin32Error(); log.Error("Error '{0}' creating process.", err); } } catch (Exception ex) { log.ErrorException("Exception creating process.", ex); } finally { Thread.Sleep(TimeSpan.FromSeconds(10)); } } } permissionManager.RemoveDesktopPermission(); }
public MatchResult Run() { const string robotBattleExePath = @"C:\Program Files (x86)\Robot Battle\winrob32.exe"; var loadListFile = Path.GetTempPath() + "loadlist.ll"; var scoreLogFile = Path.GetTempPath() + "score.log"; var statsLogFile = Path.GetTempPath() + "stats.log"; using (var writer = XmlWriter.Create(loadListFile, new XmlWriterSettings { Indent = true })) { matchBuilder.ToXml().WriteTo(writer); } if (hideWindow) { var desktopName = "RobotBattle.Automation." + Guid.NewGuid(); var desktopPtr = NativeMethods.CreateDesktop(desktopName, null, null, 0, 0xff, IntPtr.Zero); try { if (desktopPtr == IntPtr.Zero) throw new InvalidOperationException("Failed to create the secondary desktop"); // set startup parameters. var si = new NativeMethods.StartupInfo(); si.cb = Marshal.SizeOf(si); si.lpDesktop = desktopName; var pi = new NativeMethods.ProcessInformation(); var path = string.Format( "\"{0}\" \"{1}\" /t /lf \"{2}\" /slf \"{3}\" /slg 1 /lo 1 /slo 1", robotBattleExePath, loadListFile, scoreLogFile, statsLogFile ); if ( !NativeMethods.CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, true, 0x00000020, /*NORMAL_PRIORITY_CLASS*/ IntPtr.Zero, null, ref si, ref pi)) throw new InvalidOperationException("Failed to launch the Robot Battle process"); Process.GetProcessById(pi.dwProcessId) .WaitForExit(); } finally { NativeMethods.CloseDesktop(desktopPtr); } } else { Process.Start(new ProcessStartInfo { FileName = robotBattleExePath, Arguments = string.Format( "\"{1}\" /t /lf \"{2}\" /slf \"{3}\" /slg 1 /lo 1 /slo 1", robotBattleExePath, loadListFile, scoreLogFile, statsLogFile ) }).WaitForExit(); } return MatchResult.FromFiles(loadListFile, scoreLogFile, statsLogFile); }
private static NativeMethods.ProcessInformation DoCreateProcessAsUser() { var startupInfo = new NativeMethods.StartupInfo(); string lpApplicationName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; // string lpApplicationName = @"C:\Windows\System32\cmd.exe"; var cmdLine = new StringBuilder(1024); // NB: /k will keep window open. Try running powershell from the window and you won't see any modules available. Weird. // This works, however: runas /user:test_user /noprofile /savecred "powershell -NoExit" // cmdLine.Append(@" /k set"); // Other commands to try: // cmdLine.Append(@" -NoExit -Command ""dir env:"""); // Look at the environment // cmdLine.Append(@"powershell.exe -InputFormat None -NoLogo -NoProfile -NonInteractive -Command ""echo 'START'; Start-Sleep -s 15; echo 'STOP'"""); // cmdLine.Append(@"cmd /c ping 127.0.0.1 -n 15 -w 1000"); // Useful for "sleep" cmdLine.Append(@" -InputFormat None -NoLogo -NoProfile -NonInteractive -Command ""Add-Content -Path C:\tmp\test.txt -Value FOO"""); // Create structs var saProcessAttributes = new NativeMethods.SecurityAttributes(); var saThreadAttributes = new NativeMethods.SecurityAttributes(); // Now create the process as the user NativeMethods.ProcessInformation pi; var createProcessFlags = NativeMethods.CreateProcessFlags.CREATE_NO_WINDOW | NativeMethods.CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT; // NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE; // Remove this to have a hidden window. Having this here allows you to see output IntPtr primaryToken = Utils.LogonAndGetPrimaryToken(userName, password); /* * uint sessionId = 1; * if (NativeMethods.SetTokenInformation(primaryToken, * NativeMethods.TokenInformationClass.TokenSessionId, * ref sessionId, (uint)Marshal.SizeOf(sessionId))) * { */ if (NativeMethods.CreateProcessWithToken(primaryToken, NativeMethods.LogonFlags.LOGON_WITH_PROFILE, lpApplicationName, cmdLine.ToString(), createProcessFlags, IntPtr.Zero, workingDir, startupInfo, out pi)) { Console.WriteLine("create-process-with-token cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); return(pi); } else { throw new Win32Exception(); } /* * } * else * { * throw new Win32Exception(); * } */ /* * var profileInfo = new NativeMethods.ProfileInfo(); * profileInfo.lpUserName = userName; * * if (NativeMethods.LoadUserProfile(primaryToken, profileInfo)) * { * IntPtr envBlock = IntPtr.Zero; * if (NativeMethods.CreateEnvironmentBlock(out envBlock, primaryToken, false)) * { * // http://odetocode.com/blogs/scott/archive/2004/10/29/createprocessasuser.aspx * if (NativeMethods.CreateProcessAsUser( * primaryToken, * lpApplicationName, * cmdLine, // lpCommandLine * saProcessAttributes, * saThreadAttributes, * false, // bInheritHandles * createProcessFlags, * envBlock, * workingDir, * startupInfo, * out pi)) * { * Console.WriteLine("create-process-as-user cmd: '{0}' pid: '{1}'", cmdLine.ToString(), pi.dwProcessId); * return pi; * } * else * { * throw new Win32Exception(); * } * } * else * { * throw new Win32Exception(); * } * } * else * { * throw new Win32Exception(); * } */ }
public bool StartAsUser(IntPtr userToken) { _processInformation = new NativeMethods.ProcessInformation(); NativeMethods.StartupInfo startupInfo = new NativeMethods.StartupInfo(); switch (StartInfo.WindowStyle) { case ProcessWindowStyle.Hidden: startupInfo.wShowWindow = SW_HIDE; break; case ProcessWindowStyle.Maximized: startupInfo.wShowWindow = SW_MAXIMIZE; break; case ProcessWindowStyle.Minimized: startupInfo.wShowWindow = SW_MINIMIZE; break; case ProcessWindowStyle.Normal: startupInfo.wShowWindow = SW_SHOW; break; } CreateStandardPipe(out _stdinReadHandle, out _stdinWriteHandle, STD_INPUT_HANDLE, true, StartInfo.RedirectStandardInput); CreateStandardPipe(out _stdoutReadHandle, out _stdoutWriteHandle, STD_OUTPUT_HANDLE, false, StartInfo.RedirectStandardOutput); CreateStandardPipe(out _stderrReadHandle, out _stderrWriteHandle, STD_ERROR_HANDLE, false, StartInfo.RedirectStandardError); startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startupInfo.hStdInput = _stdinReadHandle; startupInfo.hStdOutput = _stdoutWriteHandle; startupInfo.hStdError = _stderrWriteHandle; NativeMethods.CreateProcessFlags createFlags = NativeMethods.CreateProcessFlags.CreateNewConsole | NativeMethods.CreateProcessFlags.CreateNewProcessGroup | NativeMethods.CreateProcessFlags.CreateDefaultErrorMode; if (StartInfo.CreateNoWindow) { startupInfo.wShowWindow = SW_HIDE; createFlags |= NativeMethods.CreateProcessFlags.CreateNoWindow; } // Create process as user, fail hard if this is unsuccessful so it can be caught in EncoderUnit if (!NativeMethods.CreateProcessAsUserW(userToken, null, GetCommandLine(), IntPtr.Zero, IntPtr.Zero, true, createFlags, IntPtr.Zero, null, startupInfo, out _processInformation)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "ImpersonationProcess: CreateProcessAsUser failed"); } if (_processInformation.hThread != (IntPtr)(-1)) { ImpersonationHelper.SafeCloseHandle(ref _processInformation.hThread); _processInformation.hThread = IntPtr.Zero; } if (StartInfo.RedirectStandardInput) { ImpersonationHelper.SafeCloseHandle(ref _stdinReadHandle); StreamWriter standardInput = new StreamWriter(new FileStream(_stdinWriteHandle, FileAccess.Write, 4096), Console.Out.Encoding) { AutoFlush = true }; SetField("standardInput", standardInput); } if (StartInfo.RedirectStandardOutput) { ImpersonationHelper.SafeCloseHandle(ref _stdoutWriteHandle); StreamReader standardOutput = new StreamReader(new FileStream(_stdoutReadHandle, FileAccess.Read, 4096), StartInfo.StandardOutputEncoding); SetField("standardOutput", standardOutput); } if (StartInfo.RedirectStandardError) { ImpersonationHelper.SafeCloseHandle(ref _stderrWriteHandle); StreamReader standardError = new StreamReader(new FileStream(_stderrReadHandle, FileAccess.Read, 4096), StartInfo.StandardErrorEncoding); SetField("standardError", standardError); } // Workaround to get process handle as non-public SafeProcessHandle Assembly processAssembly = typeof(System.Diagnostics.Process).Assembly; Type processManager = processAssembly.GetType("System.Diagnostics.ProcessManager"); object safeProcessHandle = processManager.InvokeMember("OpenProcess", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, this, new object[] { _processInformation.dwProcessId, 0x100000, false }); InvokeMethod("SetProcessHandle", safeProcessHandle); InvokeMethod("SetProcessId", _processInformation.dwProcessId); return(true); }
public MatchResult Run() { const string robotBattleExePath = @"C:\Program Files (x86)\Robot Battle\winrob32.exe"; var loadListFile = Path.GetTempPath() + "loadlist.ll"; var scoreLogFile = Path.GetTempPath() + "score.log"; var statsLogFile = Path.GetTempPath() + "stats.log"; using (var writer = XmlWriter.Create(loadListFile, new XmlWriterSettings { Indent = true })) { matchBuilder.ToXml().WriteTo(writer); } if (hideWindow) { var desktopName = "RobotBattle.Automation." + Guid.NewGuid(); var desktopPtr = NativeMethods.CreateDesktop(desktopName, null, null, 0, 0xff, IntPtr.Zero); try { if (desktopPtr == IntPtr.Zero) { throw new InvalidOperationException("Failed to create the secondary desktop"); } // set startup parameters. var si = new NativeMethods.StartupInfo(); si.cb = Marshal.SizeOf(si); si.lpDesktop = desktopName; var pi = new NativeMethods.ProcessInformation(); var path = string.Format( "\"{0}\" \"{1}\" /t /lf \"{2}\" /slf \"{3}\" /slg 1 /lo 1 /slo 1", robotBattleExePath, loadListFile, scoreLogFile, statsLogFile ); if ( !NativeMethods.CreateProcess(null, path, IntPtr.Zero, IntPtr.Zero, true, 0x00000020, /*NORMAL_PRIORITY_CLASS*/ IntPtr.Zero, null, ref si, ref pi)) { throw new InvalidOperationException("Failed to launch the Robot Battle process"); } Process.GetProcessById(pi.dwProcessId) .WaitForExit(); } finally { NativeMethods.CloseDesktop(desktopPtr); } } else { Process.Start(new ProcessStartInfo { FileName = robotBattleExePath, Arguments = string.Format( "\"{1}\" /t /lf \"{2}\" /slf \"{3}\" /slg 1 /lo 1 /slo 1", robotBattleExePath, loadListFile, scoreLogFile, statsLogFile ) }).WaitForExit(); } return(MatchResult.FromFiles(loadListFile, scoreLogFile, statsLogFile)); }