Written by wj32.
A thread contains fields for two alertable states, one for kernel-mode and one for user-mode.
When a caller from one of these modes alerts a thread (e.g. using NtAlertThread
),
the thread is put into an alerted state for the mode, and one of several things happen:
STATUS_ALERTED
.Note that if the thread is alerted and then performs an alertable wait, it will be interrupted immediately without performing the wait.
The thread can also call NtTestAlert
to check if it is alerted. In all of these
cases, the thread will be reset to a non-alerted state if it is alerted.
Local Inter-process Communication (LPC) ports are an interprocess communication (IPC) method.
A server process creates a port object and waits for a client to connect to the port. Once
the connection is established, both the client and server receive a handle to a communication
port, a special instance of a port object which can be used to send and receive messages. From
Windows Vista onward, LPC ports have been replaced with ALPC ports (NtAlpc*
system calls). Existing port-related system calls now redirect to the new ALPC port functions.
Related functions:
NtCreatePort
(server),
NtCreateWaitablePort
(server),
NtConnectPort
(client),
NtListenPort
(server),
NtAcceptConnectPort
(server),
NtRequestWaitReplyPort
(client),
NtReplyWaitReceivePort
(server),
NtReplyWaitReplyPort
,
NtReplyPort
.
Related types:
PORT_MESSAGE
,
PORT_VIEW
,
REMOTE_PORT_VIEW
,
LPCP_PORT_OBJECT
.
Asynchronous procedure calls are functions which execute in the context of a specific thread. There are two types of APCs, user-mode and kernel-mode. Each thread has two APC queues, one for each type.
User-mode APCs are queued using NtQueueApcThread
. They will not be called
unless an alertable wait is being performed or NtTestAlert
is called in the
target thread. In those cases, a flag will be set in the target thread's APC state indicating that
one or more user-mode APCs are pending and the wait operation, if any, will be interrupted. When the
system call returns to user-mode, any pending user-mode APCs will be called.
A special use of user-mode APCs is thread termination, where a thread termination APC
(PspExitNormalApc
) is inserted into the target thread. KiInsertQueueApc
contains a special case for thread termination and inserts the APC at the beginning of the
user-mode APC queue so that any wait operations in the target thread are interrupted and
the thread is terminated upon exiting the currently executing system service.
Kernel-mode APCs always preempt user-mode code, including user-mode APCs. There are two types of
kernel-mode APCs, normal and special. Normal APCs can be temporarily disabled by using
KeEnterCriticalRegion
and both types of APCs can be temporarily disabled by using
KeEnterGuardedRegion
or raising the IRQL to APC_LEVEL
or higher.
PASSIVE_LEVEL
and are inserted at the end
of the kernel-mode APC queue.APC_LEVEL
and are inserted after all existing
special APCs in the kernel-mode APC queue.When a kernel-mode APC is inserted:
PASSIVE_LEVEL
and special kernel-mode APCs
are not disabled, the wait will be interrupted with STATUS_KERNEL_APC
. Note that normal
kernel-mode APCs cannot interrupt currently executing kernel-mode APCs which are waiting. Kernel-mode
APCs do not cause wait operations to return; rather, the wait function will be interrupted,
execute any queued kernel-mode APCs, and continue waiting.Normal kernel-mode APCs are used to implement thread suspension.
A dispatcher object is one which has two states: signaled and non-signaled.
These objects can be used with standard wait functions such as NtWaitForSingleObject
or
NtWaitForMultipleObjects
. These functions wait until one or more objects are set to
a signaled state. The dispatcher objects are:
Events and gates are the most basic dispatcher objects, consisting of only a dispatcher header.
Note that the dispatcher header of a dispatcher object uses a signed integer field to represent its signal state. Signal state values greater than 0 are considered to be signaled, while 0 is considered to be non-signaled. This is useful for objects such as mutants and semaphores which can be acquired and released multiple times.
Related types:
DISPATCHER_HEADER
.
An event is a synchronization object that can be explicitly set to the signaled state. There are two types of events:
Related functions:
NtCreateEvent
,
NtOpenEvent
,
NtClearEvent
,
NtPulseEvent
,
NtQueryEvent
,
NtResetEvent
,
NtSetEvent
,
NtSetEventBoostPriority
.
Related types:
EVENT_INFORMATION_CLASS
,
EVENT_BASIC_INFORMATION
,
KEVENT
.
An event pair is a synchronization object containing two events, high and low. The system provides set, wait, and atomic signal-and-wait functions for event pairs. Note that an event pair object is not a dispatcher object and cannot be used with the standard wait functions.
Related functions:
NtCreateEventPair
,
NtOpenEventPair
,
NtSetHighEventPair
,
NtSetHighWaitLowEventPair
,
NtSetLowEventPair
,
NtSetLowWaitHighEventPair
,
NtWaitHighEvenPair
,
NtWaitLowEventPair
.
Related types:
EEVENT_PAIR
.
A keyed event is a dictionary of events. Each key must be even (the lowest bit must be clear). Internally,
the keyed event object is implemented using a linked list of pointers to threads. Every thread object has
two fields, KeyedWaitValue
and KeyedWaitSemaphore
. The KeyedWaitValue
contains the key being waited for by the thread. When a thread attempts to release a key which is not being
waited for, its KeyedWaitValue
will be set to the key OR'ed with 1, to indicate that the thread
is attempting to release the key, and the thread will wait until another thread waits for the key.
Related functions:
NtCreateKeyedEvent
,
NtOpenKeyedEvent
,
NtReleaseKeyedEvent
,
NtWaitForKeyedEvent
.
Related types:
KEYED_EVENT_OBJECT
.
A "mutant" is a standard mutex. When a thread successfully waits for a mutant, it will acquire the mutant and become the owner of the mutant; the mutant will be set to a non-signaled state. When the owning thread releases the mutant the same number of times it has acquired it, the mutant will be set to a signaled state and the mutant will no longer be owned, allowing other threads to acquire the mutant. Note that the mutant can be acquired recursively, i.e. the owning thread can acquire the mutant more than once without causing a deadlock.
Related functions:
NtCreateMutant
,
NtOpenMutant
,
NtQueryMutant
,
NtReleaseMutant
Related types:
MUTANT_INFORMATION_CLASS
,
MUTANT_BASIC_INFORMATION
,
KMUTANT
.
See ALPC Port.
A profile object can be used for performance monitoring. When certain profiling events are triggered, a corresponding counter in a user-allocated buffer is incremented.
Related functions:
NtCreateProfile
,
NtQueryIntervalProfile
,
NtSetIntervalProfile
,
NtStartProfile
,
NtStopProfile
.
Sections are objects describing a region of memory "backed" by a file. There are two types of section objects:
Multiple views of the section can be mapped, and changes will be reflected across processes.
Related functions:
NtCreateSection
,
NtOpenSection
,
NtAreMappedFilesTheSame
,
NtExtendSection
,
NtMapViewOfSection
,
NtQuerySection
,
NtUnmapViewOfSection
.
A semaphore is a synchronization object with a signal state that represents how many times it has been acquired. Each time a semaphore is acquired, its signal state is decremented. Each time a semaphore is released, its signal state is incremented (but cannot be greater than the limit). If a semaphore's signal state is 0 (non-signaled), threads must wait until another thread releases the semaphore before they can acquire the semaphore.
Related functions:
NtCreateSemaphore
,
NtOpenSemaphore
,
NtQuerySemaphore
,
NtReleaseSemaphore
.
Related types:
SEMAPHORE_INFORMATION_CLASS
,
SEMAPHORE_BASIC_INFORMATION
,
KSEMAPHORE
.
A timer is executive object and a wrapper around the kernel timer object. There are two types of timers:
A timer can be configured to be signaled periodically or to insert an APC into the thread that set the timer when the timer is signaled.
Related functions:
NtCreateTimer
,
NtOpenTimer
,
NtCancelTimer
,
NtQueryTimer
,
NtSetTimer
.
Related types:
TIMER_INFORMATION_CLASS
,
TIMER_BASIC_INFORMATION
,
ETIMER
,
KTIMER
,
PTIMER_APC_ROUTINE
.
A thread can wait for one or more objects; the standard system calls are NtWaitForSingleObject
,
NtWaitForMultipleObjects
, NtSignalAndWaitForSingleObject
, and a few type-specific
wait functions. The pointer-based kernel-mode functions are KeWaitForSingleObject
and
KeWaitForMultipleObjects
. These functions will block until a certain condition is met. For
example, *WaitForSingleObject
will return when the specified object is signaled.
*WaitForMultipleObjects
will return when all/any specified objects are signaled.
When a wait function is called, it initializes a wait block for each object to be waited for. The storage for the wait blocks is supplied in the thread object by default, but the caller can allocate storage if they wish. The wait function then checks if the wait can be satisfied immediately. If it could not, the wait function inserts the wait block(s) into the dispatch header(s) of the object(s), sets the thread's state to Waiting and will no longer be considered for execution. It then switches to another ready thread.
When an object is set to a signaled state (such as when an event is set or a mutant is released),
the function performs a wait test (KiWaitTest
) which enumerates the wait blocks in the
object's dispatcher header and unwaits each waiting thread. Each waiting thread will now be ready to run.
A waiting thread regains control due to either a wait test or a kernel-mode APC. It proceeds to call any queued kernel-mode APCs and check if the wait operation has been satisfied (for multiple-object waits, this is when any/all objects have been signaled). If it has not, the wait function continues to repeat the wait process until the wait operation has been satisfied.
For some object types, object state must be modified when a thread is finished waiting for the object. For example, a semaphore's signal state must be decremented. These operations are called side-effects, and are performed when a wait is satisfied.
#define DEBUG_READ_EVENT 0x0001 #define DEBUG_PROCESS_ASSIGN 0x0002 #define DEBUG_SET_INFORMATION 0x0004 #define DEBUG_QUERY_INFORMATION 0x0008 #define DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | DEBUG_READ_EVENT | \ DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | DEBUG_QUERY_INFORMATION)
#define DIRECTORY_QUERY 0x0001 #define DIRECTORY_TRAVERSE 0x0002 #define DIRECTORY_CREATE_OBJECT 0x0004 #define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 #define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xf)
#define EVENT_QUERY_STATE 0x0001 #define EVENT_MODIFY_STATE 0x0002 #define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
#define EVENT_PAIR_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE)
#define KEYEDEVENT_WAIT 0x0001 #define KEYEDEVENT_WAKE 0x0002 #define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
#define MUTANT_QUERY_STATE 0x0001 #define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE| MUTANT_QUERY_STATE)
#define OBJ_INHERIT 0x00000002L #define OBJ_PERMANENT 0x00000010L #define OBJ_EXCLUSIVE 0x00000020L #define OBJ_CASE_INSENSITIVE 0x00000040L #define OBJ_OPENIF 0x00000080L #define OBJ_OPENLINK 0x00000100L #define OBJ_KERNEL_HANDLE 0x00000200L #define OBJ_FORCE_ACCESS_CHECK 0x00000400L #define OBJ_VALID_ATTRIBUTES 0x000007f2L
Specifies that the handle (in the appropriate context) should be inherited by child processes.
Specifies that the object is permanent and should not be freed when all references to it have been
closed. If this flag is not specified, the object is temporary and will be freed when all references
have been closed. User-mode callers must have SeCreatePermanentPrivilege
in order to
create permanent objects.
Specifies that the object should be opened for exclusive access; the object cannot be opened again until the handle is closed.
Specifies that name comparisons should be made case insensitively.
Specifies that if an object with the specified name already exists, the creation routine should
open the existing object. If this flag is not specified and the name already exists, the creation
routine will return STATUS_OBJECT_NAME_COLLISION
.
Not used.
Specifies that the handle should be opened in the context of the System process, i.e. a kernel handle.
Specifies that an access check should be performed, even if the caller is from kernel-mode.
#define PROFILE_CONTROL 0x0001 #define PROFILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | PROFILE_CONTROL)
#define SECTION_QUERY 0x0001 #define SECTION_MAP_WRITE 0x0002 #define SECTION_MAP_READ 0x0004 #define SECTION_MAP_EXECUTE 0x0008 #define SECTION_EXTEND_SIZE 0x0010 #define SECTION_MAP_EXECUTE_EXPLICIT 0x0020 #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | \ SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | \ SECTION_EXTEND_SIZE)
#define SEMAPHORE_QUERY_STATE 0x0001 #define SEMAPHORE_MODIFY_STATE 0x0002 #define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
#define TIMER_QUERY_STATE 0x0001 #define TIMER_MODIFY_STATE 0x0002 #define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \ TIMER_QUERY_STATE | TIMER_MODIFY_STATE)
A structure identifying a process or thread.
typedef struct _CLIENT_ID { HANDLE UniqueProcess; HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID;
A handle to the process, usually a process ID (PID).
A handle to the thread, usually a thread ID (TID).
A structure describing the current directory of a process.
typedef struct _CURDIR { UNICODE_STRING DosPath; HANDLE Handle; } CURDIR, *PCURDIR;
A string containing the current directory name. This path is usually in DOS path format
(e.g. C:\Path\...
).
A handle to the current directory of the process.
A structure describing the initial contents of a TIB.
typedef struct _INITIAL_TEB { struct { PVOID OldStackBase; PVOID OldStackLimit; } OldInitialTeb; PVOID StackBase; PVOID StackLimit; PVOID StackAllocationBase; } INITIAL_TEB, *PINITIAL_TEB;
Reserved for internal use by the operating system, possibly during stack expansion. Initialize this to zero.
Reserved for internal use by the operating system, possibly during stack expansion. Initialize this to zero.
The top of the stack, considering that the stack grows downward.
The bottom limit of the committed stack. This value is always greater than or equal to
StackAllocationBase
.
The bottom of the stack, including the reserved/free space below StackLimit
.
The definition of INITIAL_TEB at NTinternals is incorrect. See this blog post for more details.
A structure describing object properties such as its name, location and security attributes.
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
The length of the OBJECT_ATTRIBUTES
structure; 24 on 32-bit systems and 40 on 64-bit systems.
A handle to a directory object from which to begin searching for the object. If this value is NULL
,
the object manager will use the default root directory.
The name of the object, optional when creating most types of objects.
See Object Flags.
A pointer to a SECURITY_DESCRIPTOR
structure for the object.
A pointer to a SECURITY_QUALITY_OF_SERVICE
structure for the object.
Unknown.
typedef struct _RTL_DRIVE_LETTER_CURDIR { USHORT Flags; USHORT Length; ULONG TimeStamp; STRING DosPath; } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
Possible values are:
#define RTL_USER_PROC_CURDIR_CLOSE 0x00000002 #define RTL_USER_PROC_CURDIR_INHERIT 0x00000003
Unknown.
Unknown.
Unknown.
A structure describing startup parameters for a process.
#define RTL_MAX_DRIVE_LETTERS 32 #define RTL_DRIVE_LETTER_VALID (USHORT)0x0001 typedef struct _RTL_USER_PROCESS_PARAMETERS { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; HANDLE ConsoleHandle; ULONG ConsoleFlags; HANDLE StandardInput; HANDLE StandardOutput; HANDLE StandardError; CURDIR CurrentDirectory; UNICODE_STRING DllPath; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UNICODE_STRING DesktopInfo; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectores[RTL_MAX_DRIVE_LETTERS]; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
A structure describing a counted ANSI string.
typedef struct _STRING { USHORT Length; USHORT MaximumLength; PCHAR Buffer; } STRING, *PSTRING, ANSI_STRING, *PANSI_STRING;
The length, in bytes, of the string (excluding the null terminator, if present).
The number of bytes allocated for the string in Buffer
.
A buffer containing the string.
A structure describing a counted Unicode string.
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
The length, in bytes, of the string (excluding the null terminator, if present).
The number of bytes allocated for the string in Buffer
.
A buffer containing the string.
Alerts the specified thread, causing it to resume execution if it is in an alertable Wait state. Otherwise, the thread is set to an alerted state.
If the specified thread is in a Wait state, it will be unwaited with a status of STATUS_ALERTED
.
If the function is being called from user-mode, it cannot unwait a kernel-mode wait operation.
NTSYSCALLAPI NTSTATUS NTAPI NtAlertThread( __in HANDLE ThreadHandle );
A handle to the thread to alert. The handle must have THREAD_ALERT
access.
ntdll; KeAlertThread
and ZwAlertThread
are exported by ntoskrnl
If this function is called from user-mode, it will set the specified thread's user-mode alert state to alerted. This will not affect kernel-mode code. The same is true when the function is called from kernel-mode.
Alerts the specified thread (see NtAlertThread
) and resumes it.
NTSYSCALLAPI NTSTATUS NTAPI NtAlertResumeThread( __in HANDLE ThreadHandle, __out_opt PULONG PreviousSuspendCount );
A handle to the thread to alert and resume. The handle must have THREAD_SUSPEND_RESUME
access.
ntdll
See notes in NtAlertThread
.
Closes a handle.
NTSYSCALLAPI NTSTATUS NTAPI NtClose( __in HANDLE Handle );
The handle to close. If the object referenced by the handle is temporary and has no references, it will be freed.
ntdll, ntoskrnl
Creates a debug object.
NTSYSCALLAPI NTSTATUS NTAPI NtCreateDebugObject( __out PHANDLE DebugObjectHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in ULONG Flags );
A variable that receives a handle to the new debug object.
The desired access to the new debug object. See Debug Object Access.
See OBJECT_ATTRIBUTES
.
The only flag currently defined is:
#define DEBUG_KILL_ON_CLOSE 0x1
ntdll
Creates a directory object.
NTSYSCALLAPI NTSTATUS NTAPI NtCreateDirectoryObject( __out PHANDLE DirectoryHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes );
A variable that receives a handle to the new directory object.
The desired access to the new directory object. See Directory Object Access.
See OBJECT_ATTRIBUTES
.
ntdll; ZwCreateDirectoryObject
is exported by ntoskrnl
Creates a process (with no threads).
NTSYSCALLAPI NTSTATUS NTAPI NtCreateProcess( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in BOOLEAN InheritObjectTable, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort );
A variable that receives a handle to the new process.
The desired access to the new process.
See OBJECT_ATTRIBUTES
.
A handle to a parent process. If no section (in SectionHandle
) was specified, the new process
will inherit the address space, handles and other characteristics of the parent process. If a section was
specified, the new process will receive a new address space created from the section but will still inherit
handles (if specified in InheritObjectTable
) and other characteristics. The parent process
must be specified unless the new process is the first process to be created on the system (the System process).
Whether ObInitProcess
will duplicate handles with the OBJ_INHERIT
attribute from
the parent process into the new process.
A handle to a section which will be used to create the new process' address space. The handle must have
SECTION_MAP_EXECUTE
access.
A handle to a debug object which the process will be assigned to. The handle must have DEBUG_PROCESS_ASSIGN
access.
A handle to a LPC port which will be notified when an exception occurs in the process.
ntdll
The new process does not have any threads. You can create one using NtCreateThread
or
RtlCreateUserThread
.
Creates a process (with no threads).
NTSYSCALLAPI NTSTATUS NTAPI NtCreateProcessEx( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ParentProcess, __in ULONG Flags, __in_opt HANDLE SectionHandle, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __in ULONG JobMemberLevel );
See NtCreateProcess
.
A combination of flags which control the creation of the new process:
#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 #define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 #define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 #define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 #define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010
The member level within a job set.
ntdll
Creates a thread.
NTSYSCALLAPI NTSTATUS NTAPI NtCreateThread( __out PHANDLE ThreadHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ProcessHandle, __out PCLIENT_ID ClientId, __in PCONTEXT ThreadContext, __in PINITIAL_TEB InitialTeb, __in BOOLEAN CreateSuspended );
A variable which receives a handle to the new thread.
The desired access to the new thread.
See OBJECT_ATTRIBUTES
.
A handle to the process in which the thread is to be created. The handle must have
PROCESS_CREATE_THREAD
access.
A variable which receives the client ID of the new thread.
The initial context for the thread.
A structure which describes the initial state of the thread's TIB. See INITIAL_TEB
.
Whether the thread should be suspended when it is created. You can resume the thread using NtResumeThread
.
ntdll
In the arguments, InitialTeb
actually specifies the initial Thread Information Block (TIB) for the thread.
The TIB is stored in the Thread Environment Block (TEB) of the thread, and can be referenced by the fs
segment register. The name TIB is pre-NT; see
Under The Hood -- MSJ, May 1996. See NT_TIB
for
more information on the TIB.
Creates a thread.
NTSYSCALLAPI NTSTATUS NTAPI NtCreateThreadEx( __out PHANDLE ThreadHandle, __in ACCESS_MASK DesiredAccess, __in_opt POBJECT_ATTRIBUTES ObjectAttributes, __in HANDLE ProcessHandle, __in PVOID StartRoutine, __in_opt PVOID StartContext, __in ULONG Flags, __in_opt ULONG_PTR StackZeroBits, __in_opt SIZE_T StackCommit, __in_opt SIZE_T StackReserve, __in_opt PPROCESS_ATTRIBUTE_LIST AttributeList );
A variable which receives a handle to the new thread.
The desired access to the new thread.
See OBJECT_ATTRIBUTES
.
A handle to the process in which the thread is to be created. The handle must have
PROCESS_CREATE_THREAD
access.
The function to call in the new thread.
The parameter to pass to the start function.
Flags which control the creation of the thread:
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 #define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 #define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 #define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080
The number of bits that must be clear when the thread stack is allocated.
The number of bytes to commit in the thread stack.
The number of bytes to reserve for the thread stack.
See PROCESS_ATTRIBUTE_LIST
.
ntdll
Creates a process and an initial thread.
NTSYSCALLAPI NTSTATUS NTAPI NtCreateUserProcess( __out PHANDLE ProcessHandle, __out PHANDLE ThreadHandle, __in ACCESS_MASK ProcessDesiredAccess, __in ACCESS_MASK ThreadDesiredAccess, __in_opt POBJECT_ATTRIBUTES ProcessObjectAttributes, __in_opt POBJECT_ATTRIBUTES ThreadObjectAttributes, __in ULONG ProcessFlags, __in ULONG ThreadFlags, __in_opt PRTL_USER_PROCESS_PARAMETERS ProcessParameters, __inout PPROCESS_CREATE_INFO CreateInfo, __in_opt PPROCESS_ATTRIBUTE_LIST AttributeList );
A variable which receives a handle to the new process.
A variable which receives a handle to the new thread.
The desired access to the new process.
The desired access to the new thread.
See OBJECT_ATTRIBUTES
.
See OBJECT_ATTRIBUTES
.
Flags used in NtCreateProcessEx
, plus the following:
#define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020
#define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040
#define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080
#define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100
See NtCreateThreadEx
.
See RTL_USER_PROCESS_PARAMETERS
.
See PROCESS_CREATE_INFO
.
See PROCESS_ATTRIBUTE_LIST
.
ntdll
Opens a process.
NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcess( __out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in_opt PCLIENT_ID ClientId );
A variable which receives a handle to a process.
The desired access to the process.
See OBJECT_ATTRIBUTES
. The ObjectName
field must be NULL.
A CLIENT_ID
specifying the process to open. If the UniqueThread
field
is not 0, the function will open the process belonging to the thread specified by the thread ID in
UniqueThread
. Otherwise, the function will open the process specified by the process ID
in the UniqueProcess
field.
ntdll, ntoskrnl
Queues a user-mode APC to the specified thread. The APC will execute when the thread performs an alertable wait or
calls NtTestAlert
. Any wait operations will return with STATUS_USER_APC
.
NTSYSCALLAPI NTSTATUS NTAPI NtQueueApcThread( __in HANDLE ThreadHandle, __in PPS_APC_ROUTINE ApcRoutine, __in_opt PVOID ApcArgument1, __in_opt PVOID ApcArgument2, __in_opt PVOID ApcArgument3 );
A handle to a thread. The handle must have THREAD_SET_CONTEXT
access.
An APC routine to execute:
typedef VOID (*PPS_APC_ROUTINE)( __in_opt PVOID ApcArgument1, __in_opt PVOID ApcArgument2, __in_opt PVOID ApcArgument3 );
The arguments to pass to the APC routine.
ntdll; KeInsertQueueApc
is exported by ntoskrnl
Registers a port which will be notified when the current thread terminates.
NTSYSCALLAPI NTSTATUS NTAPI NtRegisterThreadTerminatePort( __in HANDLE PortHandle );
A handle to the LPC port to be notified when the current thread terminates. The port will be added to a singly linked list of ports which will all be notified when the thread terminates.
ntdll
Resumes each thread in a process.
NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess( __in HANDLE ProcessHandle );
A handle to the process to resume. The handle must have PROCESS_SUSPEND_RESUME
access.
ntdll; PsResumeProcess
is exported by ntoskrnl
Resumes the specified thread. The thread is not actually resumed until the suspend count reaches 0 (i.e. the thread has been resumed the same number of times it has been suspended).
NTSYSCALLAPI NTSTATUS NTAPI NtResumeThread( __in HANDLE ThreadHandle, __out_opt PULONG PreviousSuspendCount );
A handle to the thread to resume. The handle must have THREAD_SUSPEND_RESUME
access.
A variable that receives the previous suspend count (the number of times the thread has been suspended minus the number of times the thread has been resumed).
ntdll
Suspends each thread in a process.
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess( __in HANDLE ProcessHandle );
A handle to the process to suspend. The handle must have PROCESS_SUSPEND_RESUME
access.
ntdll; PsSuspendProcess
is exported by ntoskrnl
Suspends the specified thread.
NTSYSCALLAPI NTSTATUS NTAPI NtSuspendThread( __in HANDLE ThreadHandle, __out_opt PULONG PreviousSuspendCount );
A handle to the thread to suspend. The handle must have THREAD_SUSPEND_RESUME
access.
A variable that receives the previous suspend count (the number of times the thread has been suspended minus the number of times the thread has been resumed).
ntdll
Terminates the specified process.
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess( __in_opt HANDLE ProcessHandle, __in NTSTATUS ExitStatus );
A handle to the process to terminate. The handle must have PROCESS_TERMINATE
access. If this argument
is NULL, the current process will be terminated.
A NT status value that will be saved.
ntdll; ZwTerminateProcess
is exported by ntoskrnl
Terminates the specified thread.
NTSYSCALLAPI NTSTATUS NTAPI NtTerminateThread( __in_opt HANDLE ThreadHandle, __in NTSTATUS ExitStatus );
A handle to the thread to terminate. The handle must have THREAD_TERMINATE
access. If this argument
is NULL, the current thread will be terminated. If the thread is the last in the process, the function will return
STATUS_CANT_TERMINATE_SELF
. The reason for this is that user-mode libraries (such as ntdll) are required to
call NtTerminateProcess
if this function fails with STATUS_CANT_TERMINATE_SELF
.
A NT status value that will be saved.
ntdll
Checks whether the current thread is alerted. If it is, the thread's alerted state will be cleared and
STATUS_ALERTED
will be returned. Otherwise, STATUS_SUCCESS
will be returned.
If the function is being called from user-mode, any user-mode APCs will be called when the system service exits.
NTSYSCALLAPI NTSTATUS NTAPI NtTestAlert( VOID );
ntdll; KeTestAlertThread
is exported by ntoskrnl
See notes in NtAlertThread
.
Creates a process and an initial thread.
NTSYSAPI NTSTATUS NTAPI RtlCreateUserProcess( __in PUNICODE_STRING NtImagePathName, __in ULONG Attributes, __in PRTL_USER_PROCESS_PARAMETERS ProcessParameters, __in_opt PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, __in_opt PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, __in_opt HANDLE ParentProcess, __in BOOLEAN InheritHandles, __in_opt HANDLE DebugPort, __in_opt HANDLE ExceptionPort, __out PRTL_USER_PROCESS_INFORMATION ProcessInformation );
A UNICODE_STRING
which specifies the image file (EXE) from which to create the process. The file name
must be in native format, e.g. \SystemRoot\notepad.exe
.
The object attributes to use when opening the image file, e.g. OBJ_INHERIT
.
See RTL_USER_PROCESS_PARAMETERS
.
A security descriptor for the new process.
A security descriptor for the initial thread in the new process.
A process from which to inherit handles and other characteristics. RtlCreateUserProcess
will also
duplicate standard handles (input, output and error) from the parent process to the new process.
Whether NtCreateProcess
should duplicate handles with the OBJ_INHERIT
attribute.
A handle to a debug object which the process will be assigned to. The handle must have DEBUG_PROCESS_ASSIGN
access.
A handle to a LPC port which will be notified when an exception occurs in the process.
A RTL_USER_PROCESS_INFORMATION
structure which will receive information about the new process:
typedef struct _RTL_USER_PROCESS_INFORMATION { ULONG Length; HANDLE Process; HANDLE Thread; CLIENT_ID ClientId; SECTION_IMAGE_INFORMATION ImageInformation; } RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
ntdll
This RtlCreateUserProcess
does not notify CSR of the new process, so the process' use of the
Win32 API is limited.
Creates a thread.
NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread( __in HANDLE Process, __in_opt PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, __in BOOLEAN CreateSuspended, __in_opt ULONG ZeroBits, __in_opt SIZE_T MaximumStackSize, __in_opt SIZE_T CommittedStackSize, __in PUSER_THREAD_START_ROUTINE StartAddress, __in_opt PVOID Parameter, __out_opt PHANDLE Thread, __out_opt PCLIENT_ID ClientId );
A handle to the process in which the thread will be created. The handle must have PROCESS_CREATE_THREAD
and
PROCESS_VM_OPERATION
access.
A security descriptor for the new thread.
Whether the thread should be suspended when it is created. You can resume the thread using NtResumeThread
.
The number of bits that must be clear when the thread stack is allocated. This value cannot be greater than 21.
The maximum size of the thread stack.
The number of bytes of initially committed thread stack.
The function to call in the new thread:
typedef NTSTATUS (*PUSER_THREAD_START_ROUTINE)( PVOID ThreadParameter );
A value to pass to the function specified by StartAddress
.
A variable which receives a handle to the new thread. The handle will have THREAD_ALL_ACCESS
access.
A variable which receives the client ID of the new thread.
ntdll
This function is not limited to creating threads in processes within the current session, a limitation present in
the CreateRemoteThread
Windows API function. This is due to the fact that RtlCreateUserThread
does not attempt to notify CSR of the new thread, removing the session limitation but also limiting your use of the
Win32 API.