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);
     }
 }
        /// <summary>
        /// Query a variable buffer from the object.
        /// </summary>
        /// <typeparam name="T">The type of structure to return.</typeparam>
        /// <param name="info_class">The information class to query.</param>
        /// <param name="default_value">A default value for the query.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The result of the query.</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        public virtual NtResult <SafeStructureInOutBuffer <T> > QueryBuffer <T>(Q info_class, T default_value, bool throw_on_error) where T : new()
        {
            NtStatus status;
            int      return_length;

            // First try base size before trying to reallocate.
            using (var buffer = default_value.ToBuffer()) {
                status = QueryInformation(info_class, buffer, out return_length);
                if (status.IsSuccess())
                {
                    return(status.CreateResult(false, () => buffer.Detach()));
                }
            }

            if (!IsInvalidBufferStatus(status))
            {
                return(status.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
            }

            // If the function returned a length then trust it.
            if (return_length > 0 && GetTrustReturnLength(info_class))
            {
                using (var buffer = new SafeStructureInOutBuffer <T>(default_value, return_length, false)) {
                    return(QueryInformation(info_class, buffer, out return_length).CreateResult(throw_on_error, () => buffer.Detach()));
                }
            }

            // Function length can't be trusted, we'll need to brute force it.
            return_length = GetSmallestPower2(Marshal.SizeOf(typeof(T)));
            int max_length = GetMaximumBruteForceLength(info_class);

            while (return_length < max_length)
            {
                using (var buffer = new SafeStructureInOutBuffer <T>(default_value, return_length, false)) {
                    status = QueryInformation(info_class, buffer, out int dummy_length);
                    if (status.IsSuccess())
                    {
                        return(status.CreateResult(throw_on_error, () => buffer.Detach()));
                    }
                    else if (!IsInvalidBufferStatus(status))
                    {
                        return(status.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
                    }
                    return_length *= 2;
                }
            }

            return(NtStatus.STATUS_BUFFER_TOO_SMALL.CreateResultFromError <SafeStructureInOutBuffer <T> >(throw_on_error));
        }
Пример #3
0
        internal FileSystemVolumeInformation(SafeStructureInOutBuffer <FileFsAttributeInformation> attr_info,
                                             SafeStructureInOutBuffer <FileFsVolumeInformation> vol_info)
        {
            var attr_info_res = attr_info.Result;
            var vol_info_res  = vol_info.Result;

            Attributes             = attr_info_res.FileSystemAttributes;
            MaximumComponentLength = attr_info_res.MaximumComponentNameLength;
            Name = attr_info.Data.ReadUnicodeString(attr_info_res.FileSystemNameLength / 2);

            CreationTime    = DateTime.FromFileTime(vol_info_res.VolumeCreationTime.QuadPart);
            SerialNumber    = vol_info_res.VolumeSerialNumber;
            SupportsObjects = vol_info_res.SupportsObjects;
            Label           = vol_info.Data.ReadUnicodeString(vol_info_res.VolumeLabelLength / 2);
        }
Пример #4
0
        /// <summary>
        /// Get a notification synchronously.
        /// </summary>
        /// <param name="timeout">Optional timeout for getting the notification.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The transaction notification.</returns>
        public NtResult <TransactionNotification> GetNotification(NtWaitTimeout timeout, bool throw_on_error)
        {
            NtStatus status = NtSystemCalls.NtGetNotificationResourceManager(Handle,
                                                                             SafeHGlobalBuffer.Null, 0, timeout.ToLargeInteger(), out int return_length, 0, IntPtr.Zero);

            if (status != NtStatus.STATUS_BUFFER_TOO_SMALL)
            {
                return(status.CreateResultFromError <TransactionNotification>(throw_on_error));
            }

            using (var buffer = new SafeStructureInOutBuffer <TransactionNotificationData>(return_length, false)) {
                return(NtSystemCalls.NtGetNotificationResourceManager(Handle,
                                                                      buffer, buffer.Length, timeout.ToLargeInteger(), out return_length, 0, IntPtr.Zero)
                       .CreateResult(throw_on_error, () => new TransactionNotification(buffer)));
            }
        }
        /// <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());
            }
        }
Пример #6
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();
                }
            }
        }
Пример #7
0
 private string TryGetName()
 {
     using (SafeStructureInOutBuffer <FileNameInformation> buffer = new SafeStructureInOutBuffer <FileNameInformation>(32 * 1024, true))
     {
         try
         {
             IoStatus status = new IoStatus();
             NtSystemCalls.NtQueryInformationFile(Handle, status, buffer, buffer.Length, FileInformationClass.FileNameInformation).ToNtException();
             char[] result = new char[buffer.Result.NameLength / 2];
             buffer.Data.ReadArray(0, result, 0, result.Length);
             return(new string(result));
         }
         catch (NtException)
         {
             return(String.Empty);
         }
     }
 }
        private SafeHGlobalBuffer CreateAbsoluteSecurityDescriptor()
        {
            SafeStructureInOutBuffer <SecurityDescriptorStructure> sd_buffer = null;

            try
            {
                byte[] dacl       = Dacl?.ToByteArray();
                byte[] sacl       = Sacl?.ToByteArray();
                byte[] owner      = Owner?.Sid.ToArray();
                byte[] group      = Group?.Sid.ToArray();
                int    total_size = GetLength(dacl) + GetLength(sacl) + GetLength(owner) + GetLength(group);
                sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(total_size, true);
                NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision).ToNtException();
                SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask;
                NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control).ToNtException();
                int current_ofs = 0;
                if (Dacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Dacl.NullAcl ? null : dacl, ref current_ofs);
                    NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, ptr, Dacl.Defaulted).ToNtException();
                }
                if (Sacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Sacl.NullAcl ? null : sacl, ref current_ofs);
                    NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, ptr, Sacl.Defaulted).ToNtException();
                }
                if (Owner != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, owner, ref current_ofs);
                    NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, ptr, Owner.Defaulted);
                }
                if (Group != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, group, ref current_ofs);
                    NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, ptr, Group.Defaulted);
                }

                return(Interlocked.Exchange(ref sd_buffer, null));
            }
            finally
            {
                sd_buffer?.Close();
            }
        }
Пример #9
0
        /// <summary>
        /// For the current process
        /// </summary>
        /// <param name="process_create_flags">Process create flags.</param>
        /// <param name="thread_create_flags">Thread create flags.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The new forked process result</returns>
        public static NtResult <CreateUserProcessResult> Fork(ProcessCreateFlags process_create_flags,
                                                              ThreadCreateFlags thread_create_flags, bool throw_on_error)
        {
            using (var attrs = new DisposableList <ProcessAttribute>()) {
                ProcessCreateInfo create_info = new ProcessCreateInfo();

                SafeStructureInOutBuffer <ClientId> client_id = new SafeStructureInOutBuffer <ClientId>();
                attrs.Add(ProcessAttribute.ClientId(client_id));

                ProcessAttributeList attr_list = new ProcessAttributeList(attrs);

                return(NtSystemCalls.NtCreateUserProcess(
                           out SafeKernelObjectHandle process_handle, out SafeKernelObjectHandle thread_handle,
                           ProcessAccessRights.MaximumAllowed, ThreadAccessRights.MaximumAllowed,
                           null, null, process_create_flags | ProcessCreateFlags.InheritFromParent,
                           thread_create_flags, IntPtr.Zero, create_info, attr_list).CreateResult(throw_on_error,
                                                                                                  () => new CreateUserProcessResult(process_handle, thread_handle,
                                                                                                                                    create_info.Data, new SectionImageInformation(), client_id.Result, false)));
            }
        }
        /// <summary>
        /// Query memory information for a process.
        /// </summary>
        /// <param name="process">The process to query.</param>
        /// <param name="base_address">The base address.</param>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The memory information for the region.</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        public static NtResult <MemoryInformation> QueryMemoryInformation(SafeKernelObjectHandle process, long base_address, bool throw_on_error)
        {
            MemoryBasicInformation basic_info = new MemoryBasicInformation();
            string mapped_image_path          = string.Empty;

            using (var buffer = new SafeStructureInOutBuffer <MemoryBasicInformation>())
            {
                NtStatus status = NtSystemCalls.NtQueryVirtualMemory(process,
                                                                     new IntPtr(base_address), MemoryInformationClass.MemoryBasicInformation,
                                                                     buffer, buffer.LengthIntPtr, out IntPtr ret_length);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <MemoryInformation>(throw_on_error));
                }
                basic_info = buffer.Result;
            }

            MemoryRegionInformation region_info = new MemoryRegionInformation();

            using (var buffer = new SafeStructureInOutBuffer <MemoryRegionInformation>())
            {
                NtStatus status = NtSystemCalls.NtQueryVirtualMemory(process,
                                                                     new IntPtr(base_address), MemoryInformationClass.MemoryRegionInformationEx,
                                                                     buffer, buffer.LengthIntPtr, out IntPtr ret_length);
                if (status.IsSuccess())
                {
                    region_info = buffer.Result;
                }
            }

            if (basic_info.Type == MemoryType.Image || basic_info.Type == MemoryType.Mapped)
            {
                var name = QuerySectionName(process, base_address, false);
                if (name.IsSuccess)
                {
                    mapped_image_path = name.Result;
                }
            }

            return(new MemoryInformation(basic_info, mapped_image_path, region_info).CreateResult());
        }
Пример #11
0
        /// <summary>
        /// Query the directory for a list of entries.
        /// </summary>
        /// <returns>The list of entries.</returns>
        /// <exception cref="NtException">Thrown on error</exception>
        public IEnumerable <ObjectDirectoryInformation> Query()
        {
            string base_path = FullPath.TrimEnd('\\');

            using (SafeStructureInOutBuffer <OBJECT_DIRECTORY_INFORMATION> buffer
                       = new SafeStructureInOutBuffer <OBJECT_DIRECTORY_INFORMATION>(2048, true))
            {
                NtStatus status;
                int      context       = 0;
                int      return_length = 0;
                while ((status = NtSystemCalls.NtQueryDirectoryObject(Handle, buffer, buffer.Length, false,
                                                                      true, ref context, out return_length)) == NtStatus.STATUS_MORE_ENTRIES)
                {
                    buffer.Resize(buffer.Length * 2);
                }

                if (status == NtStatus.STATUS_NO_MORE_ENTRIES)
                {
                    yield break;
                }

                status.ToNtException();
                IntPtr current = buffer.DangerousGetHandle();
                string name    = String.Empty;
                while (true)
                {
                    OBJECT_DIRECTORY_INFORMATION dir_info = (OBJECT_DIRECTORY_INFORMATION)Marshal.PtrToStructure(current, typeof(OBJECT_DIRECTORY_INFORMATION));
                    name = dir_info.Name.ToString();
                    if (name.Length == 0)
                    {
                        break;
                    }
                    yield return(new ObjectDirectoryInformation(this, base_path, dir_info));

                    current += Marshal.SizeOf(dir_info);
                }
            }
        }
        private SafeStructureInOutBuffer <T> Query <T>(ProcessInfoClass info_class) where T : new()
        {
            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 != NtStatus.STATUS_BUFFER_TOO_SMALL)
            {
                throw new NtException(status);
            }

            SafeStructureInOutBuffer <T> buffer = new SafeStructureInOutBuffer <T>(return_length, false);

            try
            {
                NtSystemCalls.NtQueryInformationProcess(Handle, info_class, buffer, buffer.Length, out return_length).ToNtException();
                return(buffer);
            }
            catch
            {
                buffer.Close();
                throw;
            }
        }
        /// <summary>
        /// Query memory information for a process.
        /// </summary>
        /// <param name="process">The process to query.</param>
        /// <param name="base_address">The base address.</param>
        /// <returns>The memory information for the region.</returns>
        /// <exception cref="NtException">Thrown on error.</exception>
        public static MemoryInformation QueryMemoryInformation(SafeKernelObjectHandle process, long base_address)
        {
            MemoryBasicInformation basic_info = new MemoryBasicInformation();
            string mapped_image_path          = String.Empty;

            using (var buffer = new SafeStructureInOutBuffer <MemoryBasicInformation>())
            {
                NtSystemCalls.NtQueryVirtualMemory(process,
                                                   new IntPtr(base_address), MemoryInformationClass.MemoryBasicInformation,
                                                   buffer, buffer.LengthIntPtr, out IntPtr ret_length).ToNtException();
                basic_info = buffer.Result;
            }

            if (basic_info.Type == MemoryType.Image || basic_info.Type == MemoryType.Mapped)
            {
                var name = QuerySectionName(process, base_address, false);
                if (name.IsSuccess)
                {
                    mapped_image_path = name.Result;
                }
            }

            return(new MemoryInformation(basic_info, mapped_image_path));
        }
Пример #14
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();
                }
            }
        }
Пример #15
0
 /// <summary>
 /// Query a fixed structure from the object.
 /// </summary>
 /// <typeparam name="T">The type of structure to return.</typeparam>
 /// <param name="info_class">The information class to query.</param>
 /// <param name="default_value">A default value for the query.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The result of the query.</returns>
 /// <exception cref="NtException">Thrown on error.</exception>
 public virtual NtResult <T> Query <T>(Q info_class, T default_value, bool throw_on_error) where T : new()
 {
     using (var buffer = new SafeStructureInOutBuffer <T>(default_value)) {
         return(QueryInformation(info_class, buffer, out int return_length).CreateResult(throw_on_error, () => buffer.Result));
     }
 }
Пример #16
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();
            }
        }
Пример #17
0
 public static ProcessAttribute ClientId(SafeStructureInOutBuffer <ClientId> client_id)
 {
     return(new ProcessAttribute(ProcessAttributeNum.ClientId, true, false, false, client_id));
 }
Пример #18
0
 public static ProcessAttribute ImageInfo(SafeStructureInOutBuffer <SectionImageInformation> image_information)
 {
     return(new ProcessAttribute(ProcessAttributeNum.ImageInfo, false, false, false, image_information));
 }
        /// <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();
                }
            }
        }
Пример #20
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));
                            }
                        }
                    }
                }
            }
        }
Пример #21
0
        private NtResult <SafeHGlobalBuffer> CreateAbsoluteSecurityDescriptor(bool throw_on_error)
        {
            byte[] dacl       = Dacl?.ToByteArray();
            byte[] sacl       = Sacl?.ToByteArray();
            byte[] owner      = Owner?.Sid.ToArray();
            byte[] group      = Group?.Sid.ToArray();
            int    total_size = GetLength(dacl) + GetLength(sacl) + GetLength(owner) + GetLength(group);

            using (var sd_buffer = new SafeStructureInOutBuffer <SecurityDescriptorStructure>(total_size, true))
            {
                NtStatus status = NtRtl.RtlCreateSecurityDescriptor(sd_buffer, Revision);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                SecurityDescriptorControl control = Control & SecurityDescriptorControl.ValidControlSetMask;
                status = NtRtl.RtlSetControlSecurityDescriptor(sd_buffer, control, control);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                }

                int current_ofs = 0;
                if (Dacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Dacl.NullAcl ? null : dacl, ref current_ofs);
                    status = NtRtl.RtlSetDaclSecurityDescriptor(sd_buffer, true, ptr, Dacl.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Sacl != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, Sacl.NullAcl ? null : sacl, ref current_ofs);
                    status = NtRtl.RtlSetSaclSecurityDescriptor(sd_buffer, true, ptr, Sacl.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Owner != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, owner, ref current_ofs);
                    status = NtRtl.RtlSetOwnerSecurityDescriptor(sd_buffer, ptr, Owner.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                if (Group != null)
                {
                    IntPtr ptr = UpdateBuffer(sd_buffer, group, ref current_ofs);
                    status = NtRtl.RtlSetGroupSecurityDescriptor(sd_buffer, ptr, Group.Defaulted);
                    if (!status.IsSuccess())
                    {
                        return(status.CreateResultFromError <SafeHGlobalBuffer>(throw_on_error));
                    }
                }

                return(status.CreateResult <SafeHGlobalBuffer>(throw_on_error, () => sd_buffer.Detach()));
            }
        }