1

I'm trying to spawn task manager from C# using CreateProcess API. Unfortunately,i always get code 740 from CreateProcess, a little bit of googling, code 740 is : ERROR_ELEVATION_REQUIRED. the creation flags I use are CreateSuspended,CreateDetachedProcess,CreateNoWindow,and CreateUnicodeEnvironment (just in case my parent process has Unicode on lpEnvironment). Normally,Task Manager doesnt need admin privilege right?

This is the code that i use :

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFO
    {
        public uint cb;
        public IntPtr lpReserved;
        public IntPtr lpDesktop;
        public IntPtr lpTitle;
        public uint dwX;
        public uint dwY;
        public uint dwXSize;
        public uint dwYSize;
        public uint dwXCountChars;
        public uint dwYCountChars;
        public uint dwFillAttributes;
        public uint dwFlags;
        public ushort wShowWindow;
        public ushort cbReserved;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdErr;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct STARTUPINFOEX
    {
        public STARTUPINFO StartupInfo;
        public IntPtr lpAttributeList;
    }

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

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public int bInheritHandle;
    }

    [Flags]
    public enum CreationFlags
    {
        CreateSuspended = 0x00000004,
        DetachedProcess = 0x00000008,
        CreateNoWindow = 0x08000000,
        CreateUnicodeEnv = 0x00000400
    }

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);

    public static void Main() {
        string PathToExecutableForProcess = @"C:\Windows\System32\Taskmgr.exe";
        STARTUPINFOEX sInfoEx = new STARTUPINFOEX();
        PROCESS_INFORMATION pInfo = new PROCESS_INFORMATION();
        sInfoEx.StartupInfo.cb = (uint)Marshal.SizeOf(sInfoEx);
        IntPtr lpValue = IntPtr.Zero;
        SECURITY_ATTRIBUTES pSec = new SECURITY_ATTRIBUTES();
        SECURITY_ATTRIBUTES tSec = new SECURITY_ATTRIBUTES();
        pSec.nLength = Marshal.SizeOf(pSec);
        tSec.nLength = Marshal.SizeOf(tSec);
        CreationFlags flags = CreationFlags.CreateSuspended | CreationFlags.DetachedProcess | CreationFlags.CreateNoWindow | CreationFlags.CreateUnicodeEnv;
        // spawn the new process
        bool CreateProcessResult = CreateProcess(PathToExecutableForProcess, null, ref pSec, ref tSec, false, flags, (IntPtr)0, null, ref sInfoEx, out pInfo);
        if (CreateProcessResult) {
            Console.WriteLine("[+] {0}'s process spawned!", PathToExecutableForProcess);
        }else {
            Console.WriteLine("[-] Failed to spawn the new process because of code {0}!", (Marshal.GetLastWin32Error()));
        }
    }

Does anybody know how to solve this?

  • Why do you specify `CreateUnicodeEnv` when not passing an environment block to `CreateProcess`? – Klaus Gütter Jun 24 '21 at 06:47
  • 1
    First things first, you can't use `MarshalGetLastWin32Error` if you don't add `SetLastError=true` to `DllImport` https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute.setlasterror – Simon Mourier Jun 24 '21 at 06:56
  • Thx for telling me that,Simmon.Gotta update the code ASAP – GetRektBoy724 Jun 24 '21 at 10:42
  • 1
    Task manager require admin rights, but its auto elevated, that's why you won't see UAC prompt. – Gray Programmerz Jun 24 '21 at 14:40
  • If you run your code as admin, then ? – Gray Programmerz Jun 24 '21 at 14:40
  • why CreateProcess cant do auto-elevate too? – GetRektBoy724 Jun 24 '21 at 14:48
  • Is there any API that let me get the handle of the process and thread inside the process that also does auto-elevation? – GetRektBoy724 Jun 24 '21 at 15:01
  • 1
    @GetRektBoy724 "*why CreateProcess cant do auto-elevate too?*" - because it is not supposed to. It launches a new process in the same context as the caller, so if the caller is not already elevated, the new process wont be, either. `ERROR_ELEVATION_REQUIRED` means the new process needs to be elevated but the caller is not elevated. If you want an un-elevated process to launch an elevated process, use `ShellExecute/Ex()` with the `"runas"` verb instead. See [How to run application which requires admin rights from one that doesn't have them](https://stackoverflow.com/questions/11586139/) – Remy Lebeau Jun 24 '21 at 16:17
  • @GetRektBoy724 "*Is there any API that let me get the handle of the process and thread inside the process that also does auto-elevation?*" - `ShellExecuteEx()` can run an elevated process, and return a process handle to it via the `SEE_MASK_NOCLOSEPROCESS` flag, but it will not return a thread handle. – Remy Lebeau Jun 24 '21 at 16:19
  • Oh okay thx for the answer @RemyLebeau – GetRektBoy724 Jun 25 '21 at 01:33

0 Answers0