Ejemplo n.º 1
0
        private static SafeStructureInOutBuffer <T> QueryObject <T>(SafeKernelObjectHandle handle, ObjectInformationClass object_info) where T : new()
        {
            SafeStructureInOutBuffer <T> ret = null;
            NtStatus status = NtStatus.STATUS_BUFFER_TOO_SMALL;

            try
            {
                int return_length;
                status = NtSystemCalls.NtQueryObject(handle, object_info, IntPtr.Zero, 0, out return_length);
                if ((status != NtStatus.STATUS_BUFFER_TOO_SMALL) && (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH))
                {
                    status.ToNtException();
                }
                if (return_length == 0)
                {
                    ret = new SafeStructureInOutBuffer <T>();
                }
                else
                {
                    ret = new SafeStructureInOutBuffer <T>(return_length, false);
                }
                status = NtSystemCalls.NtQueryObject(handle, object_info, ret.DangerousGetHandle(), ret.Length, out return_length);
                status.ToNtException();
            }
            finally
            {
                if (ret != null && !status.IsSuccess())
                {
                    ret.Close();
                    ret = null;
                }
            }
            return(ret);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Query a value by name
        /// </summary>
        /// <param name="value_name">The name of the value</param>
        /// <returns>The value information</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        public NtKeyValue QueryValue(string value_name)
        {
            UnicodeString name        = new UnicodeString(value_name);
            int           return_len  = 0;
            int           query_count = 0;

            while (query_count < 64)
            {
                using (var info = new SafeStructureInOutBuffer <KeyValuePartialInformation>(return_len, false))
                {
                    NtStatus status = NtSystemCalls.NtQueryValueKey(Handle, name, KeyValueInformationClass.KeyValuePartialInformation,
                                                                    info, info.Length, out return_len);
                    if (status.IsSuccess())
                    {
                        KeyValuePartialInformation result = info.Result;
                        return(new NtKeyValue(value_name, info.Result.Type, info.Data.ReadBytes(result.DataLength), result.TitleIndex));
                    }
                    if (status != NtStatus.STATUS_BUFFER_OVERFLOW && status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                    {
                        status.ToNtException();
                    }
                    ;
                }
                query_count++;
            }
            throw new NtException(NtStatus.STATUS_BUFFER_TOO_SMALL);
        }
        /// <summary>
        /// Get a mitigation policy raw value
        /// </summary>
        /// <param name="policy">The policy to get</param>
        /// <returns>The raw policy value</returns>
        public int GetProcessMitigationPolicy(ProcessMitigationPolicy policy)
        {
            switch (policy)
            {
            case ProcessMitigationPolicy.ProcessDEPPolicy:
            case ProcessMitigationPolicy.ProcessReserved1Policy:
            case ProcessMitigationPolicy.ProcessMitigationOptionsMask:
                throw new ArgumentException("Invalid mitigation policy");
            }

            MitigationPolicy p = new MitigationPolicy();

            p.Policy = policy;

            using (var buffer = p.ToBuffer())
            {
                int      return_length;
                NtStatus status = NtSystemCalls.NtQueryInformationProcess(Handle, ProcessInfoClass.ProcessMitigationPolicy, buffer, buffer.Length, out return_length);
                if (!status.IsSuccess())
                {
                    if (status != NtStatus.STATUS_INVALID_PARAMETER && status != NtStatus.STATUS_NOT_SUPPORTED)
                    {
                        status.ToNtException();
                    }
                    return(0);
                }
                return(buffer.Result.Result);
            }
        }
Ejemplo n.º 4
0
        private static IEnumerable <string> EnumNameList(SafeKernelObjectHandle handle)
        {
            int size = 522;

            for (int i = 0; i < 10; ++i)
            {
                using (var buffer = new SafeHGlobalBuffer(size))
                {
                    NtStatus status = NtSystemCalls.NtUserBuildNameList(handle, buffer.Length, buffer, out size);
                    if (!status.IsSuccess())
                    {
                        if (status == NtStatus.STATUS_BUFFER_TOO_SMALL)
                        {
                            continue;
                        }
                        status.ToNtException();
                    }
                    int total_count = buffer.Read <int>(4);
                    int offset      = 8;
                    while (total_count > 0)
                    {
                        string name = buffer.ReadNulTerminatedUnicodeString((ulong)offset);
                        yield return(name);

                        offset += (name.Length + 1) * 2;
                        total_count--;
                    }
                    yield break;
                }
            }
            throw new NtException(NtStatus.STATUS_NO_MEMORY);
        }
Ejemplo n.º 5
0
        private SafeStructureInOutBuffer <T> QueryBuffer <T>(ThreadInformationClass info_class) where T : new()
        {
            SafeStructureInOutBuffer <T> info = new SafeStructureInOutBuffer <T>();

            try
            {
                int      return_length = 0;
                NtStatus status        = NtSystemCalls.NtQueryInformationThread(Handle, info_class,
                                                                                info, info.Length, out return_length);
                if (status == NtStatus.STATUS_INFO_LENGTH_MISMATCH || status == NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    using (SafeBuffer to_close = info)
                    {
                        info = new SafeStructureInOutBuffer <T>(return_length, false);
                    }
                    status = NtSystemCalls.NtQueryInformationThread(Handle, info_class,
                                                                    info, info.Length, out return_length);
                }

                status.ToNtException();
                return(info);
            }
            catch
            {
                info.Close();
                throw;
            }
        }
        /// <summary>
        /// Process Record.
        /// </summary>
        protected override void ProcessRecord()
        {
            if (SecurityDescriptor == null)
            {
                SecurityDescriptor = new SecurityDescriptor();
                if (SecurityInformation.HasFlag(SecurityInformation.Dacl))
                {
                    SecurityDescriptor.Dacl = new Acl();
                }
                if (SecurityInformation.HasFlag(SecurityInformation.Sacl))
                {
                    SecurityDescriptor.Sacl = new Acl();
                }
            }

            bool do_callback            = ShowProgress || PassThru;
            TreeProgressFunction fn     = ProgressFunction;
            NtStatus             status = Win32Security.ResetSecurityInfo(Name, Type, SecurityInformation, SecurityDescriptor, do_callback ? fn : null,
                                                                          ShowProgress ? ProgressInvokeSetting.PrePostError : ProgressInvokeSetting.EveryObject, KeepExplicit, !PassThru);

            if (!PassThru)
            {
                status.ToNtException();
            }
        }
Ejemplo n.º 7
0
        private void SetNamedSecurityInfo()
        {
            bool do_callback = ShowProgress || PassThru;

            if (Type == SeObjectType.Service)
            {
                SecurityInformation &= SecurityInformation.Owner |
                                       SecurityInformation.Group | SecurityInformation.Dacl |
                                       SecurityInformation.Label | SecurityInformation.Sacl;
            }

            string path = Name;

            if (Type == SeObjectType.File)
            {
                path = PSUtils.ResolveWin32Path(SessionState, path, false);
            }

            if (do_callback || Action != TreeSecInfo.Set)
            {
                TreeProgressFunction fn     = ProgressFunction;
                NtStatus             status = Win32Security.SetSecurityInfo(path, Type, SecurityInformation, SecurityDescriptor, Action, do_callback ? fn : null,
                                                                            ShowProgress ? ProgressInvokeSetting.PrePostError : ProgressInvokeSetting.EveryObject, !PassThru);
                if (!PassThru)
                {
                    status.ToNtException();
                }
            }
            else
            {
                Win32Security.SetSecurityInfo(path, Type, SecurityInformation, SecurityDescriptor);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Check if this object is exactly the same as another using NtCompareObject.
        /// </summary>
        /// <param name="obj">The object to compare against.</param>
        /// <returns>True if this is the same object.</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        /// <remarks>This is only supported on Windows 10 and above. For one which works on everything use SameObject.</remarks>
        public bool CompareObject(NtObject obj)
        {
            NtStatus status = NtSystemCalls.NtCompareObjects(Handle, obj.Handle);

            if (status == NtStatus.STATUS_NOT_SAME_OBJECT)
            {
                return(false);
            }
            status.ToNtException();
            return(true);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Write memory to a process.
 /// </summary>
 /// <param name="process">The process to write to.</param>
 /// <param name="base_address">The base address in the process.</param>
 /// <param name="data">The data to write.</param>
 /// <returns>The number of bytes written to the location</returns>
 /// <exception cref="NtException">Thrown on error.</exception>
 public static int WriteMemory(SafeKernelObjectHandle process, long base_address, byte[] data)
 {
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(data)) {
         NtStatus status = NtSystemCalls.NtWriteVirtualMemory(process,
                                                              new IntPtr(base_address), buffer, buffer.Length, out int return_length);
         if (status != NtStatus.STATUS_PARTIAL_COPY)
         {
             status.ToNtException();
         }
         return(return_length);
     }
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Get security descriptor as a byte array
        /// </summary>
        /// <param name="security_information">What parts of the security descriptor to retrieve</param>
        /// <returns>The security descriptor</returns>
        public byte[] GetSecurityDescriptorBytes(SecurityInformation security_information)
        {
            int      return_length;
            NtStatus status = NtSystemCalls.NtQuerySecurityObject(Handle, security_information, null, 0, out return_length);

            if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
            {
                status.ToNtException();
            }
            byte[] buffer = new byte[return_length];
            NtSystemCalls.NtQuerySecurityObject(Handle, security_information, buffer, buffer.Length, out return_length).ToNtException();
            return(buffer);
        }
 private static int GetTypeSize()
 {
     using (var type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>())
     {
         Dictionary <string, NtType> ret = new Dictionary <string, NtType>(StringComparer.OrdinalIgnoreCase);
         NtStatus status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectTypesInformation,
                                                       type_info, type_info.Length, out int return_length);
         if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH)
         {
             status.ToNtException();
         }
         return(return_length);
     }
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Read memory from a process.
 /// </summary>
 /// <param name="process">The process to read from.</param>
 /// <param name="base_address">The base address in the process.</param>
 /// <param name="length">The length to read.</param>
 /// <returns>The array of bytes read from the location.
 /// If a read is short then returns fewer bytes than requested.</returns>
 /// <exception cref="NtException">Thrown on error.</exception>
 public static byte[] ReadMemory(SafeKernelObjectHandle process, long base_address, int length)
 {
     using (SafeHGlobalBuffer buffer = new SafeHGlobalBuffer(length))
     {
         int      return_length;
         NtStatus status = NtSystemCalls.NtReadVirtualMemory(process,
                                                             new IntPtr(base_address), buffer, buffer.Length, out return_length);
         if (status != NtStatus.STATUS_PARTIAL_COPY)
         {
             status.ToNtException();
         }
         return(buffer.ReadBytes(return_length));
     }
 }
        private static void AllocateSafeBuffer(SafeHGlobalBuffer buffer, SystemInformationClass info_class)
        {
            NtStatus status        = 0;
            int      return_length = 0;

            while ((status = NtSystemCalls.NtQuerySystemInformation(info_class,
                                                                    buffer,
                                                                    buffer.Length,
                                                                    out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH)
            {
                int length = buffer.Length * 2;
                buffer.Resize(length);
            }
            status.ToNtException();
        }
        /// <summary>
        /// Get process image file path
        /// </summary>
        /// <param name="native">True to return the native image path, false for a Win32 style path</param>
        /// <returns>The process image file path</returns>
        public string GetImageFilePath(bool native)
        {
            ProcessInfoClass info_class = native ? ProcessInfoClass.ProcessImageFileName : ProcessInfoClass.ProcessImageFileNameWin32;
            int      return_length      = 0;
            NtStatus status             = NtSystemCalls.NtQueryInformationProcess(Handle, info_class, SafeHGlobalBuffer.Null, 0, out return_length);

            if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH)
            {
                status.ToNtException();
            }
            using (SafeStructureInOutBuffer <UnicodeStringOut> buf = new SafeStructureInOutBuffer <UnicodeStringOut>(return_length, false))
            {
                NtSystemCalls.NtQueryInformationProcess(Handle, info_class, buf, buf.Length, out return_length).ToNtException();
                return(buf.Result.ToString());
            }
        }
Ejemplo n.º 15
0
        private static Dictionary <string, NtType> LoadTypes()
        {
            var type_factories = NtTypeFactory.GetAssemblyNtTypeFactories(Assembly.GetExecutingAssembly());
            SafeStructureInOutBuffer <ObjectAllTypesInformation> type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>();

            try
            {
                Dictionary <string, NtType> ret = new Dictionary <string, NtType>(StringComparer.OrdinalIgnoreCase);
                int      return_length;
                NtStatus status = NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation,
                                                              type_info.DangerousGetHandle(), type_info.Length, out return_length);
                if (status != NtStatus.STATUS_INFO_LENGTH_MISMATCH)
                {
                    status.ToNtException();
                }

                type_info.Close();
                type_info = null;
                type_info = new SafeStructureInOutBuffer <ObjectAllTypesInformation>(return_length, false);

                int alignment = IntPtr.Size - 1;
                NtSystemCalls.NtQueryObject(SafeKernelObjectHandle.Null, ObjectInformationClass.ObjectAllInformation,
                                            type_info.DangerousGetHandle(), type_info.Length, out return_length).ToNtException();
                ObjectAllTypesInformation result = type_info.Result;
                IntPtr curr_typeinfo             = type_info.DangerousGetHandle() + IntPtr.Size;
                for (int count = 0; count < result.NumberOfTypes; ++count)
                {
                    ObjectTypeInformation info = (ObjectTypeInformation)Marshal.PtrToStructure(curr_typeinfo, typeof(ObjectTypeInformation));
                    string        name         = info.Name.ToString();
                    NtTypeFactory factory      = type_factories.ContainsKey(name) ? type_factories[name] : _generic_factory;
                    NtType        ti           = new NtType(count + 2, info, factory);
                    ret[ti.Name] = ti;

                    int offset = (info.Name.MaximumLength + alignment) & ~alignment;
                    curr_typeinfo = info.Name.Buffer + offset;
                }

                return(ret);
            }
            finally
            {
                if (type_info != null)
                {
                    type_info.Close();
                }
            }
        }
Ejemplo n.º 16
0
        private void SetNamedSecurityInfo()
        {
            bool do_callback = ShowProgress || PassThru;

            if (do_callback || Action != TreeSecInfo.Set)
            {
                TreeProgressFunction fn     = ProgressFunction;
                NtStatus             status = Win32Security.SetSecurityInfo(Name, Type, SecurityInformation, SecurityDescriptor, Action, do_callback ? fn : null,
                                                                            ShowProgress ? ProgressInvokeSetting.PrePostError : ProgressInvokeSetting.EveryObject, !PassThru);
                if (!PassThru)
                {
                    status.ToNtException();
                }
            }
            else
            {
                Win32Security.SetSecurityInfo(Name, Type, SecurityInformation, SecurityDescriptor);
            }
        }
        /// <summary>
        /// Get a list of handles
        /// </summary>
        /// <param name="pid">A process ID to filter on. If -1 will get all handles</param>
        /// <param name="allow_query">True to allow the handles returned to query for certain properties</param>
        /// <returns>The list of handles</returns>
        public static IEnumerable <NtHandle> GetHandles(int pid, bool allow_query)
        {
            SafeHGlobalBuffer handleInfo = new SafeHGlobalBuffer(0x10000);

            try
            {
                NtStatus status        = 0;
                int      return_length = 0;
                while ((status = NtSystemCalls.NtQuerySystemInformation(SystemInformationClass.SystemHandleInformation,
                                                                        handleInfo.DangerousGetHandle(),
                                                                        handleInfo.Length,
                                                                        out return_length)) == NtStatus.STATUS_INFO_LENGTH_MISMATCH)
                {
                    int length = handleInfo.Length * 2;
                    handleInfo.Close();
                    handleInfo = new SafeHGlobalBuffer(length);
                }
                status.ToNtException();

                IntPtr          handleInfoBuf = handleInfo.DangerousGetHandle();
                int             handle_count  = Marshal.ReadInt32(handleInfoBuf);
                List <NtHandle> ret           = new List <NtHandle>();
                handleInfoBuf += IntPtr.Size;
                for (int i = 0; i < handle_count; ++i)
                {
                    SystemHandleTableInfoEntry entry = (SystemHandleTableInfoEntry)Marshal.PtrToStructure(handleInfoBuf, typeof(SystemHandleTableInfoEntry));

                    if (pid == -1 || entry.UniqueProcessId == pid)
                    {
                        ret.Add(new NtHandle(entry, allow_query));
                    }
                    handleInfoBuf += Marshal.SizeOf(typeof(SystemHandleTableInfoEntry));
                }
                return(ret);
            }
            finally
            {
                handleInfo.Close();
            }
        }
        private SafeHGlobalBuffer CreateRelativeSecurityDescriptor()
        {
            using (var sd_buffer = CreateAbsoluteSecurityDescriptor())
            {
                int      total_length = 0;
                NtStatus status       = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length);
                if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    status.ToNtException();
                }

                var relative_sd = new SafeHGlobalBuffer(total_length);
                try
                {
                    NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException();
                    return(Interlocked.Exchange(ref relative_sd, null));
                }
                finally
                {
                    relative_sd?.Close();
                }
            }
        }
Ejemplo n.º 19
0
        private SafeStructureInOutBuffer <T> QueryKey <T>(KeyInformationClass info_class) where T : new()
        {
            int      return_length;
            NtStatus status = NtSystemCalls.NtQueryKey(Handle, info_class, SafeHGlobalBuffer.Null, 0, out return_length);

            if (status != NtStatus.STATUS_BUFFER_OVERFLOW && status != NtStatus.STATUS_INFO_LENGTH_MISMATCH && status != NtStatus.STATUS_BUFFER_TOO_SMALL)
            {
                status.ToNtException();
            }
            SafeStructureInOutBuffer <T> buffer = new SafeStructureInOutBuffer <T>(return_length, false);

            try
            {
                NtSystemCalls.NtQueryKey(Handle, info_class, buffer, buffer.Length, out return_length).ToNtException();
                return(Interlocked.Exchange(ref buffer, null));
            }
            finally
            {
                if (buffer != null)
                {
                    buffer.Close();
                }
            }
        }
        /// <summary>
        /// Start the new process
        /// </summary>
        /// <param name="image_path">The image path to the file to execute</param>
        /// <returns>The result of the process creation</returns>
        public CreateUserProcessResult Start(string image_path)
        {
            if (image_path == null)
            {
                throw new System.ArgumentNullException("image_path");
            }

            IntPtr process_params = CreateProcessParameters(ImagePath ?? image_path, DllPath, CurrentDirectory,
                                                            CommandLine, Environment, WindowTitle, DesktopInfo, ShellInfo, RuntimeData, 1);
            List <ProcessAttribute> attrs = new List <ProcessAttribute>();

            try
            {
                ProcessCreateInfo      create_info = new ProcessCreateInfo();
                SafeKernelObjectHandle process_handle;
                SafeKernelObjectHandle thread_handle;

                attrs.Add(ProcessAttribute.ImageName(image_path));
                SafeStructureInOutBuffer <SectionImageInformation> image_info = new SafeStructureInOutBuffer <SectionImageInformation>();
                attrs.Add(ProcessAttribute.ImageInfo(image_info));
                SafeStructureInOutBuffer <ClientId> client_id = new SafeStructureInOutBuffer <ClientId>();
                attrs.Add(ProcessAttribute.ClientId(client_id));
                attrs.AddRange(AdditionalAttributes);
                if (ParentProcess != null)
                {
                    attrs.Add(ProcessAttribute.ParentProcess(ParentProcess.Handle));
                }

                if (RestrictChildProcess || OverrideRestrictChildProcess)
                {
                    attrs.Add(ProcessAttribute.ChildProcess(RestrictChildProcess, OverrideRestrictChildProcess));
                }

                ProcessAttributeList attr_list = new ProcessAttributeList(attrs);

                create_info.Data.InitFlags = InitFlags | ProcessCreateInitFlag.WriteOutputOnExit;
                create_info.Data.ProhibitedImageCharacteristics = ProhibitedImageCharacteristics;
                create_info.Data.AdditionalFileAccess           = AdditionalFileAccess;

                NtStatus status = NtSystemCalls.NtCreateUserProcess(
                    out process_handle, out thread_handle,
                    ProcessAccessRights.MaximumAllowed, ThreadAccessRights.MaximumAllowed,
                    null, null, ProcessFlags,
                    ThreadFlags, process_params, create_info, attr_list);

                if (!status.IsSuccess() && !ReturnOnError)
                {
                    // Close handles which come from errors
                    switch (create_info.State)
                    {
                    case ProcessCreateState.FailOnSectionCreate:
                        NtSystemCalls.NtClose(create_info.Data.FileHandle);
                        break;

                    case ProcessCreateState.FailExeName:
                        NtSystemCalls.NtClose(create_info.Data.IFEOKey);
                        break;
                    }

                    status.ToNtException();
                }

                if (create_info.State == ProcessCreateState.Success)
                {
                    return(new CreateUserProcessResult(process_handle, thread_handle,
                                                       create_info.Data, image_info.Result, client_id.Result, TerminateOnDispose));
                }
                else
                {
                    return(new CreateUserProcessResult(status, create_info.Data, create_info.State));
                }
            }
            finally
            {
                NtRtl.RtlDestroyProcessParameters(process_params);
                foreach (ProcessAttribute attr in attrs)
                {
                    attr.Dispose();
                }
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Start the new process
        /// </summary>
        /// <param name="image_path">The image path to the file to execute</param>
        /// <returns>The result of the process creation</returns>
        public CreateUserProcessResult Start(string image_path)
        {
            if (image_path == null)
            {
                throw new ArgumentNullException("image_path");
            }

            using (var process_params = SafeProcessParametersBuffer.Create(ConfigImagePath ?? image_path, DllPath, CurrentDirectory,
                                                                           CommandLine, Environment, WindowTitle, DesktopInfo, ShellInfo, RuntimeData, CreateProcessParametersFlags.Normalize)) {
                using (var attrs = new DisposableList <ProcessAttribute>()) {
                    ProcessCreateInfo create_info = new ProcessCreateInfo();

                    attrs.Add(ProcessAttribute.ImageName(image_path));
                    SafeStructureInOutBuffer <SectionImageInformation> image_info = new SafeStructureInOutBuffer <SectionImageInformation>();
                    attrs.Add(ProcessAttribute.ImageInfo(image_info));
                    SafeStructureInOutBuffer <ClientId> client_id = new SafeStructureInOutBuffer <ClientId>();
                    attrs.Add(ProcessAttribute.ClientId(client_id));
                    attrs.AddRange(AdditionalAttributes);
                    if (ParentProcess != null)
                    {
                        attrs.Add(ProcessAttribute.ParentProcess(ParentProcess.Handle));
                    }

                    if (RestrictChildProcess || OverrideRestrictChildProcess)
                    {
                        attrs.Add(ProcessAttribute.ChildProcess(RestrictChildProcess, OverrideRestrictChildProcess));
                    }

                    if (Token != null)
                    {
                        attrs.Add(ProcessAttribute.Token(Token.Handle));
                    }

                    using (ProcessAttributeList attr_list = ProcessAttributeList.Create(attrs)) {
                        create_info.Data.InitFlags = InitFlags | ProcessCreateInitFlag.WriteOutputOnExit;
                        create_info.Data.ProhibitedImageCharacteristics = ProhibitedImageCharacteristics;
                        create_info.Data.AdditionalFileAccess           = AdditionalFileAccess;

                        using (ObjectAttributes proc_attr = new ObjectAttributes(null, AttributeFlags.None,
                                                                                 SafeKernelObjectHandle.Null, null, ProcessSecurityDescriptor),
                               thread_attr = new ObjectAttributes(null, AttributeFlags.None,
                                                                  SafeKernelObjectHandle.Null, null, ThreadSecurityDescriptor)) {
                            NtStatus status = NtSystemCalls.NtCreateUserProcess(
                                out SafeKernelObjectHandle process_handle, out SafeKernelObjectHandle thread_handle,
                                ProcessDesiredAccess, ThreadDesiredAccess,
                                proc_attr, thread_attr, ProcessFlags,
                                ThreadFlags, process_params.DangerousGetHandle(), create_info, attr_list);

                            if (!status.IsSuccess() && !ReturnOnError)
                            {
                                // Close handles which come from errors
                                switch (create_info.State)
                                {
                                case ProcessCreateState.FailOnSectionCreate:
                                    NtSystemCalls.NtClose(create_info.Data.FileHandle);
                                    break;

                                case ProcessCreateState.FailExeName:
                                    NtSystemCalls.NtClose(create_info.Data.IFEOKey);
                                    break;
                                }

                                status.ToNtException();
                            }

                            if (create_info.State == ProcessCreateState.Success)
                            {
                                return(new CreateUserProcessResult(process_handle, thread_handle,
                                                                   create_info.Data, image_info.Result, client_id.Result, TerminateOnDispose));
                            }
                            else
                            {
                                return(new CreateUserProcessResult(status, create_info.Data, create_info.State));
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Convert an NtStatus to an exception if the status is an error
 /// </summary>
 /// <param name="status">The NtStatus</param>
 /// <returns>The original NtStatus if not an error</returns>
 /// <exception cref="NtException">Thrown if status is an error.</exception>
 public static NtStatus ToNtException(this NtStatus status)
 {
     return(status.ToNtException(true));
 }
Ejemplo n.º 23
0
        /// <summary>
        /// Convert security descriptor to a byte array
        /// </summary>
        /// <returns>The binary security descriptor</returns>
        public byte[] ToByteArray()
        {
            SafeStructureInOutBuffer <SecurityDescriptorStructure> sd_buffer = null;
            SafeHGlobalBuffer   dacl_buffer  = null;
            SafeHGlobalBuffer   sacl_buffer  = null;
            SafeSidBufferHandle owner_buffer = null;
            SafeSidBufferHandle group_buffer = null;

            try
            {
                sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>();
                NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException();
                SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask;
                NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException();
                if (Dacl != null)
                {
                    if (!Dacl.NullAcl)
                    {
                        dacl_buffer = new SafeHGlobalBuffer(Dacl.ToByteArray());
                    }
                    else
                    {
                        dacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false);
                    }

                    NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, dacl_buffer.DangerousGetHandle(), Dacl.Defaulted).ToNtException();
                }
                if (Sacl != null)
                {
                    if (!Sacl.NullAcl)
                    {
                        sacl_buffer = new SafeHGlobalBuffer(Sacl.ToByteArray());
                    }
                    else
                    {
                        sacl_buffer = new SafeHGlobalBuffer(IntPtr.Zero, 0, false);
                    }

                    NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, sacl_buffer.DangerousGetHandle(), Sacl.Defaulted).ToNtException();
                }
                if (Owner != null)
                {
                    owner_buffer = Owner.Sid.ToSafeBuffer();
                    NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, owner_buffer.DangerousGetHandle(), Owner.Defaulted);
                }
                if (Group != null)
                {
                    group_buffer = Group.Sid.ToSafeBuffer();
                    NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, group_buffer.DangerousGetHandle(), Group.Defaulted);
                }

                int      total_length = 0;
                NtStatus status       = NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, new SafeHGlobalBuffer(IntPtr.Zero, 0, false), ref total_length);
                if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
                {
                    status.ToNtException();
                }

                using (SafeHGlobalBuffer relative_sd = new SafeHGlobalBuffer(total_length))
                {
                    NtRtl.RtlAbsoluteToSelfRelativeSD(sd_buffer, relative_sd, ref total_length).ToNtException();
                    return(relative_sd.ToArray());
                }
            }
            finally
            {
                sd_buffer?.Close();
                dacl_buffer?.Close();
                sacl_buffer?.Close();
                owner_buffer?.Close();
                group_buffer?.Close();
            }
        }