Пример #1
0
        public unsafe static void CopyProcessParameters(
            ProcessHandle processHandle,
            IntPtr peb,
            ProcessCreationFlags creationFlags,
            string imagePathName,
            string dllPath,
            string currentDirectory,
            string commandLine,
            EnvironmentBlock environment,
            string windowTitle,
            string desktopInfo,
            string shellInfo,
            string runtimeInfo,
            ref StartupInfo startupInfo
            )
        {
            UnicodeString imagePathNameStr;
            UnicodeString dllPathStr;
            UnicodeString currentDirectoryStr;
            UnicodeString commandLineStr;
            UnicodeString windowTitleStr;
            UnicodeString desktopInfoStr;
            UnicodeString shellInfoStr;
            UnicodeString runtimeInfoStr;

            // Create the unicode strings.

            imagePathNameStr = new UnicodeString(imagePathName);
            dllPathStr = new UnicodeString(dllPath);
            currentDirectoryStr = new UnicodeString(currentDirectory);
            commandLineStr = new UnicodeString(commandLine);
            windowTitleStr = new UnicodeString(windowTitle);
            desktopInfoStr = new UnicodeString(desktopInfo);
            shellInfoStr = new UnicodeString(shellInfo);
            runtimeInfoStr = new UnicodeString(runtimeInfo);

            try
            {
                NtStatus status;
                IntPtr processParameters;

                // Create the process parameter block.

                status = Win32.RtlCreateProcessParameters(
                    out processParameters,
                    ref imagePathNameStr,
                    ref dllPathStr,
                    ref currentDirectoryStr,
                    ref commandLineStr,
                    environment,
                    ref windowTitleStr,
                    ref desktopInfoStr,
                    ref shellInfoStr,
                    ref runtimeInfoStr
                    );

                if (status >= NtStatus.Error)
                    Win32.Throw(status);

                try
                {
                    // Allocate a new memory region in the remote process for 
                    // the environment block and copy it over.

                    int environmentLength;
                    IntPtr newEnvironment;

                    environmentLength = environment.GetLength();
                    newEnvironment = processHandle.AllocateMemory(
                        environmentLength,
                        MemoryProtection.ReadWrite
                        );

                    processHandle.WriteMemory(
                        newEnvironment,
                        environment,
                        environmentLength
                        );

                    // Copy over the startup info data.
                    RtlUserProcessParameters* paramsStruct = (RtlUserProcessParameters*)processParameters;

                    paramsStruct->Environment = newEnvironment;
                    paramsStruct->StartingX = startupInfo.X;
                    paramsStruct->StartingY = startupInfo.Y;
                    paramsStruct->CountX = startupInfo.XSize;
                    paramsStruct->CountY = startupInfo.YSize;
                    paramsStruct->CountCharsX = startupInfo.XCountChars;
                    paramsStruct->CountCharsY = startupInfo.YCountChars;
                    paramsStruct->FillAttribute = startupInfo.FillAttribute;
                    paramsStruct->WindowFlags = startupInfo.Flags;
                    paramsStruct->ShowWindowFlags = startupInfo.ShowWindow;

                    if ((startupInfo.Flags & StartupFlags.UseStdHandles) == StartupFlags.UseStdHandles)
                    {
                        paramsStruct->StandardInput = startupInfo.StdInputHandle;
                        paramsStruct->StandardOutput = startupInfo.StdOutputHandle;
                        paramsStruct->StandardError = startupInfo.StdErrorHandle;
                    }

                    // TODO: Add console support.

                    // Allocate a new memory region in the remote process for 
                    // the process parameters.

                    IntPtr newProcessParameters;
                    IntPtr regionSize = paramsStruct->Length.ToIntPtr();

                    newProcessParameters = processHandle.AllocateMemory(
                        IntPtr.Zero,
                        ref regionSize,
                        MemoryFlags.Commit,
                        MemoryProtection.ReadWrite
                        );

                    paramsStruct->MaximumLength = regionSize.ToInt32();

                    processHandle.WriteMemory(newProcessParameters, processParameters, paramsStruct->Length);

                    // Modify the process parameters pointer in the PEB.
                    processHandle.WriteMemory(
                        peb.Increment(Peb.ProcessParametersOffset),
                        &newProcessParameters,
                        IntPtr.Size
                        );
                }
                finally
                {
                    Win32.RtlDestroyProcessParameters(processParameters);
                }
            }
            finally
            {
                imagePathNameStr.Dispose();
                dllPathStr.Dispose();
                currentDirectoryStr.Dispose();
                commandLineStr.Dispose();
                windowTitleStr.Dispose();
                desktopInfoStr.Dispose();
                shellInfoStr.Dispose();
                runtimeInfoStr.Dispose();
            }
        }
Пример #2
0
        public static void Main(Dictionary<string, string> pArgs)
        {
            args = pArgs;

            EnablePrivilege("SeAssignPrimaryTokenPrivilege");
            EnablePrivilege("SeBackupPrivilege");
            EnablePrivilege("SeRestorePrivilege");

            try
            {
                bool bad = false;

                if (!args.ContainsKey("-w"))
                {
                    if (!args.ContainsKey("-c") && !args.ContainsKey("-f"))
                        bad = true;

                    if (args.ContainsKey("-c") && args.ContainsKey("-f"))
                        bad = true;

                    if (!args.ContainsKey("-u") && !args.ContainsKey("-P"))
                        bad = true;

                    if (args.ContainsKey("-u") && args.ContainsKey("-P"))
                        bad = true;
                }

                if (args.ContainsKey("-v") || args.ContainsKey("-h"))
                    bad = true;

                if (bad)
                {
                    PrintUsage();
                    Exit();
                }
            }
            catch
            {
                PrintUsage();
                Exit();
            }

            if (args.ContainsKey("-w"))
            {
                try
                {
                    SetDesktopWinStaAccess();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Warning: Could not set desktop and window station access: " + ex.Message);
                }
            }

            TokenHandle token = null;
            string domain = null;
            string username;

            if (args.ContainsKey("-u"))
            {
                string user = args["-u"];

                if (user.Contains("\\", StringComparison.OrdinalIgnoreCase))
                {
                    domain = user.Split('\\')[0];
                    username = user.Split('\\')[1];
                }
                else if (user.Contains("@", StringComparison.OrdinalIgnoreCase))
                {
                    username = user.Split('@')[0];
                    domain = user.Split('@')[1];
                }
                else
                {
                    username = user;
                }

                LogonType type = LogonType.Interactive;

                if (args.ContainsKey("-t"))
                {
                    try
                    {
                        type = (LogonType)Enum.Parse(typeof(LogonType), args["-t"], true);
                    }
                    catch
                    {
                        Console.WriteLine("Error: Invalid logon type.");
                        Exit(-1);
                    }
                }

                try
                {
                    token = TokenHandle.Logon(
                        username,
                        domain,
                        args.ContainsKey("-p") ? args["-p"] : "",
                        type,
                        LogonProvider.Default
                        );
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: Could not logon as user: "******"-P"))
                        pid = int.Parse(args["-P"]);
                }
                catch
                {
                    Console.WriteLine("Error: Invalid PID.");
                }

                try
                {
                    using (var phandle = new ProcessHandle(pid, OSVersion.MinProcessQueryInfoAccess))
                    {
                        try
                        {
                            token = phandle.GetToken(TokenAccess.All);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Error: Could not open process token: " + ex.Message);
                            Exit(Marshal.GetLastWin32Error());
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: Could not open process: " + ex.Message);
                    Exit(Marshal.GetLastWin32Error());
                }

                // Need to duplicate the token if we're going to set the session ID.
                if (args.ContainsKey("-s"))
                {
                    try
                    {
                        TokenHandle dupToken;

                        dupToken = token.Duplicate(
                            TokenAccess.All,
                            SecurityImpersonationLevel.SecurityImpersonation,
                            TokenType.Primary
                            );
                        token.Dispose();
                        token = dupToken;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error: Could not duplicate own token: " + ex.Message);
                        Exit(Marshal.GetLastWin32Error());
                    }
                }
            }

            if (args.ContainsKey("-s"))
            {
                int sessionId = int.Parse(args["-s"]);

                try
                {
                    token.SessionId = sessionId;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: Could not set token session ID: " + ex.Message);
                }
            }

            if (args.ContainsKey("-c") || args.ContainsKey("-f"))
            {
                if (!args.ContainsKey("-e"))
                {
                    EnvironmentBlock environment;
                    StartupInfo startupInfo = new StartupInfo();
                    ProcessHandle processHandle;
                    ThreadHandle threadHandle;
                    ClientId clientId;

                    environment = new EnvironmentBlock(token);
                    startupInfo.Desktop = "WinSta0\\Default";

                    try
                    {
                        processHandle = ProcessHandle.CreateWin32(
                            token,
                            args.ContainsKey("-f") ? args["-f"] : null,
                            args.ContainsKey("-c") ? args["-c"] : null,
                            false,
                            ProcessCreationFlags.CreateUnicodeEnvironment,
                            environment,
                            args.ContainsKey("-d") ? args["-d"] : null,
                            startupInfo,
                            out clientId,
                            out threadHandle
                            );
                        processHandle.Dispose();
                        threadHandle.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error: Could not create process: " + ex.Message);
                        Exit(Marshal.GetLastWin32Error());
                    }
                    finally
                    {
                        environment.Destroy();
                    }
                }
            }

            token.Dispose();

            Exit();
        }
Пример #3
0
        private void restartProcessMenuItem_Click(object sender, EventArgs e)
        {
            if (PhUtils.ShowConfirmMessage(
                "restart",
                "the selected process",
                "The process will be restarted with the same command line and " + 
                "working directory, but if it is running under a different user it " + 
                "will be restarted under the current user.",
                true
                ))
            {
                try
                {
                    using (var phandle = new ProcessHandle(processSelectedPid,
                        Program.MinProcessQueryRights | Program.MinProcessReadMemoryRights))
                    {
                        string currentDirectory = phandle.GetPebString(PebOffset.CurrentDirectoryPath);
                        string cmdLine = phandle.GetPebString(PebOffset.CommandLine);

                        try
                        {
                            using (var phandle2 = new ProcessHandle(processSelectedPid, ProcessAccess.Terminate))
                                phandle2.Terminate();
                        }
                        catch (Exception ex)
                        {
                            PhUtils.ShowException("Unable to terminate the process", ex);
                            return;
                        }

                        try
                        {
                            var startupInfo = new StartupInfo();
                            var procInfo = new ProcessInformation();

                            startupInfo.Size = Marshal.SizeOf(startupInfo);

                            if (!Win32.CreateProcess(null, cmdLine, IntPtr.Zero, IntPtr.Zero, false, 0, IntPtr.Zero, currentDirectory,
                                ref startupInfo, out procInfo))
                                Win32.ThrowLastError();

                            Win32.CloseHandle(procInfo.ProcessHandle);
                            Win32.CloseHandle(procInfo.ThreadHandle);
                        }
                        catch (Exception ex)
                        {
                            PhUtils.ShowException("Unable to start the command '" + cmdLine + "'", ex);
                        }
                    }
                }
                catch (Exception ex)
                {
                    PhUtils.ShowException("Unable to restart the process", ex);
                }
            }
        }
Пример #4
0
        static void Main()
        {
            EnablePrivilege("SeAssignPrimaryTokenPrivilege");
            EnablePrivilege("SeBackupPrivilege");
            EnablePrivilege("SeRestorePrivilege");

            try
            {
                args = ParseArgs(Environment.GetCommandLineArgs());

                bool bad = false;

                if (!args.ContainsKey("-w"))
                {
                    if (!args.ContainsKey("-c") && !args.ContainsKey("-f"))
                        bad = true;

                    if (args.ContainsKey("-c") && args.ContainsKey("-f"))
                        bad = true;

                    if (!args.ContainsKey("-u") && !args.ContainsKey("-P"))
                        bad = true;

                    if (args.ContainsKey("-u") && args.ContainsKey("-P"))
                        bad = true;
                }

                if (args.ContainsKey("-v") || args.ContainsKey("-h"))
                    bad = true;

                if (bad)
                {
                    PrintUsage();
                    Exit();
                }
            }
            catch
            {
                PrintUsage();
                Exit();
            }

            if (args.ContainsKey("-w"))
            {
                try
                {
                    SetDesktopWinStaAccess();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Warning: Could not set desktop and window station access: " + ex.Message);
                }
            }

            IntPtr token = IntPtr.Zero;
            string domain = null;
            string username = "";

            if (args.ContainsKey("-u"))
            {
                string user = args["-u"];

                if (user.Contains("\\"))
                {
                    domain = user.Split('\\')[0];
                    username = user.Split('\\')[1];
                }
                else if (user.Contains("@"))
                {
                    username = user.Split('@')[0];
                    domain = user.Split('@')[1];
                }
                else
                {
                    username = user;
                }

                LogonType type = LogonType.Interactive;

                if (args.ContainsKey("-t"))
                {
                    try
                    {
                        type = (LogonType)Enum.Parse(typeof(LogonType), args["-t"], true);
                    }
                    catch
                    {
                        Console.WriteLine("Error: Invalid logon type.");
                        Exit(-1);
                    }
                }

                if (!Win32.LogonUser(username, domain, args.ContainsKey("-p") ? args["-p"] : "", type,
                    LogonProvider.Default, out token))
                {
                    Console.WriteLine("Error: Could not logon as user: "******"-P"))
                        pid = int.Parse(args["-P"]);
                }
                catch
                {
                    Console.WriteLine("Error: Invalid PID.");
                }

                IntPtr handle = IntPtr.Zero;

                try
                {
                    handle = System.Diagnostics.Process.GetProcessById(pid).Handle;
                }
                catch
                {
                    Console.WriteLine("Error: Could not open process.");
                }


                if (!Win32.OpenProcessToken(handle, TokenAccess.All, out token))
                {
                    Console.WriteLine("Error: Could not open process token: " + Win32.GetLastErrorMessage());
                    Exit(Marshal.GetLastWin32Error());
                }

                if (Environment.OSVersion.Version.Major != 5)
                {
                    IntPtr dupToken;

                    if (!Win32.DuplicateTokenEx(token, TokenAccess.All, IntPtr.Zero, SecurityImpersonationLevel.SecurityImpersonation,
                        TokenType.Primary, out dupToken))
                    {
                        Console.WriteLine("Error: Could not duplicate own token: " + Win32.GetLastErrorMessage());
                        Exit(Marshal.GetLastWin32Error());
                    }

                    Win32.CloseHandle(token);
                    token = dupToken;
                }
            }

            if (args.ContainsKey("-s"))
            {
                int sessionId = int.Parse(args["-s"]);

                if (!Win32.SetTokenInformation(token, TokenInformationClass.TokenSessionId, ref sessionId, 4))
                {
                    Console.WriteLine("Error: Could not set token session Id: " + Win32.GetLastErrorMessage());
                }
            }

            if (args.ContainsKey("-c") || args.ContainsKey("-f"))
            {
                if (!args.ContainsKey("-e"))
                {
                    StartupInfo info = new StartupInfo();
                    ProcessInformation pinfo = new ProcessInformation();
                    IntPtr environment;

                    Win32.CreateEnvironmentBlock(out environment, token, false);

                    info.Size = Marshal.SizeOf(info);
                    info.Desktop = "WinSta0\\Default";

                    if (!Win32.CreateProcessAsUser(token,
                        args.ContainsKey("-f") ? args["-f"] : null,
                        args.ContainsKey("-c") ? args["-c"] : null,
                        IntPtr.Zero, IntPtr.Zero, false, ProcessCreationFlags.CreateUnicodeEnvironment, environment,
                        args.ContainsKey("-d") ? args["-d"] : null,
                        ref info, out pinfo))
                    {
                        Console.WriteLine("Error: Could not create process: " + Win32.GetLastErrorMessage());
                        Exit(Marshal.GetLastWin32Error());
                    }

                    Win32.CloseHandle(token);
                }
            }

            Exit();
        }