Exemple #1
0
        /// <summary>
        /// Creates a new process under this debugging pipeline.
        /// </summary>
        /// <param name="application">raw application to launch. Passed directly to kernel32!CreateProcess.</param>
        /// <param name="commandArgs">raw arguments to pass to the debuggee. Passed directly to kernel32!CreateProcess.</param>
        /// <param name="newConsole">true if the debuggee should get a new console, else false</param>
        /// <param name="debugChild">true if this should debug child processes, else false to debug just the
        /// launched processes.</param>
        /// <returns>NativeDbgProcess instance for newly created process</returns>
        /// <seealso cref="Attach"/>
        /// <remarks>Pump the process for debug events by calling WaitForDebugEvent.
        /// Create a process under the debugger.
        /// This passes application and commandArgs directly to Passed directly to kernel32!CreateProcess and
        /// does not do any filtering on them.</remarks>
        public NativeDbgProcess CreateProcessDebugRaw(string application, string commandArgs, bool newConsole, bool debugChild)
        {
            // This is a pretty rich overload. We should considering just using a rich structure (like
            // ProcessStartInfo) instead of ever growign signatures. ProcessStartInfo isn't perfect:
            // - it's missing some flags like child-process debugging.
            // - it has extra flags like UseShellExecute.

            NativeMethods.CreateProcessFlags flags = NativeMethods.CreateProcessFlags.DEBUG_PROCESS;
            if (!debugChild)
            {
                flags |= NativeMethods.CreateProcessFlags.DEBUG_ONLY_THIS_PROCESS;
            }
            if (newConsole)
            {
                flags |= NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE;
            }

            return(CreateProcessDebugRawWorker(application, commandArgs, flags));
        }
        private NativeDbgProcess CreateProcessDebugWorker(string application, string commandArgs,
                                                          NativeMethods.CreateProcessFlags flags)
        {
            if (application == null)
            {
                throw new ArgumentException("can't be null", "application");
            }

            // Compensate for Win32's behavior, where arg[0] is the application name.
            if (commandArgs != null)
            {
                commandArgs = application + " " + commandArgs;
            }

            // This is using definition imports from Mdbg core, where these are classes.
            var pi = new PROCESS_INFORMATION(); // class

            var si = new STARTUPINFO();         // struct


            NativeMethods.CreateProcess(
                application,
                commandArgs,
                IntPtr.Zero, // process attributes
                IntPtr.Zero, // thread attributes
                false,       // inherit handles,
                NativeMethods.CreateProcessFlags.CREATE_NEW_CONSOLE | flags,
                IntPtr.Zero, // env block
                null,        // current dir
                si,
                pi);

            // We'll close these handle now. We'll get them again from the CreateProcess debug event.
            NativeMethods.CloseHandle(pi.hProcess);
            NativeMethods.CloseHandle(pi.hThread);

            return(CreateNew(pi.dwProcessId));
        }
Exemple #3
0
        static void Main(string[] args)
        {
            string desktopName = "MyDesktop";
            string appPath     = @"%SystemRoot%\system32\cmd.exe";
            string parameters  = @"/c dir C:\ >%TEMP%\dir.txt";
            IntPtr hDesktop    = IntPtr.Zero;

            NativeMethods.ProcessInformation processInfo = new NativeMethods.ProcessInformation();
            bool isSuccess;

            try {
                hDesktop = NativeMethods.CreateDesktop(desktopName, null, null, 0,
                                                       NativeMethods.ACCESS_MASK.MAXIMUM_ALLOWED, null);
                if (hDesktop == IntPtr.Zero)
                {
                    DisplayLastErrorMessage();
                    return;
                }

                NativeMethods.StartupInfo        startupInfo     = new NativeMethods.StartupInfo();
                NativeMethods.CreateProcessFlags dwCreationFlags = NativeMethods.CreateProcessFlags.NormalPriorityClass;
                startupInfo.cb        = Marshal.SizeOf(typeof(NativeMethods.StartupInfo));
                startupInfo.lpDesktop = "WinSta0\\" + desktopName;
                string currentDirectory = Environment.CurrentDirectory;
                appPath = Environment.ExpandEnvironmentVariables(appPath);
                //if (appPath.IndexOf (' ') != -1)
                //    appPath = '\"' + appPath + '\"';
                StringBuilder sbParameters = new StringBuilder(3 + appPath.Length + parameters.Length);
                if (appPath.IndexOf(' ') != -1)
                {
                    sbParameters.Append('\"');
                    sbParameters.Append(appPath);
                    sbParameters.Append('\"');
                }
                else
                {
                    sbParameters.Append(appPath);
                }
                sbParameters.Append(' ');
                sbParameters.Append(parameters);
                // appPath - full path to the exe without having " if the file has blanks in the path
                isSuccess = NativeMethods.CreateProcess(appPath,
                                                        sbParameters.ToString(), IntPtr.Zero, IntPtr.Zero, false, dwCreationFlags,
                                                        IntPtr.Zero, currentDirectory, ref startupInfo, out processInfo);
                if (!isSuccess)
                {
                    DisplayLastErrorMessage();
                    return;
                }
                NativeMethods.CloseHandle(processInfo.hThread);
                processInfo.hThread = IntPtr.Zero;

                if (NativeMethods.WaitForSingleObject(processInfo.hProcess, NativeMethods.Infinite) == NativeMethods.WaitObject0)
                {
                    Console.WriteLine("the process is ended");
                }
            }
            finally {
                if (processInfo.hThread != IntPtr.Zero)
                {
                    isSuccess = NativeMethods.CloseHandle(processInfo.hThread);
                }
                if (processInfo.hProcess != IntPtr.Zero)
                {
                    isSuccess = NativeMethods.CloseHandle(processInfo.hProcess);
                }
                if (hDesktop != IntPtr.Zero)
                {
                    isSuccess = NativeMethods.CloseDesktop(hDesktop);
                }
            }
        }
Exemple #4
0
        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);
        }