/// <summary> /// Create a remote thread. /// </summary> /// <param name="process">The process to create the thread in.</param> /// <param name="security_descriptor">The thread security descriptor.</param> /// <param name="inherit_handle">Whether the handle should be inherited.</param> /// <param name="stack_size">The size of the stack. 0 for default.</param> /// <param name="start_address">Start address for the thread.</param> /// <param name="parameter">Parameter to pass to the thread.</param> /// <param name="flags">The flags for the thread creation.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The created thread.</returns> /// <exception cref="NtException">Thrown on error.</exception> public static NtResult <NtThread> CreateRemoteThread( NtProcess process, SecurityDescriptor security_descriptor, bool inherit_handle, long stack_size, long start_address, long parameter, CreateThreadFlags flags, bool throw_on_error) { if (process == null) { throw new ArgumentNullException(nameof(process)); } using (var resources = new DisposableList()) { SECURITY_ATTRIBUTES sec_attr = null; if (security_descriptor != null || inherit_handle) { sec_attr = new SECURITY_ATTRIBUTES { bInheritHandle = inherit_handle, lpSecurityDescriptor = security_descriptor == null ? SafeHGlobalBuffer.Null : resources.AddResource(security_descriptor.ToSafeBuffer()) }; } var handle = Win32NativeMethods.CreateRemoteThreadEx(process.GetHandle(), sec_attr, new IntPtr(stack_size), new IntPtr(start_address), new IntPtr(parameter), flags, SafeHGlobalBuffer.Null, null); if (handle.IsInvalid) { return(NtObjectUtils.CreateResultFromDosError <NtThread>(throw_on_error)); } return(new NtThread(handle).CreateResult()); } }