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.
NtAlertThread ... KeAlertThread ... KiUnwaitThread ... KiReadyThread
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.
NT headers.
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.
NtAlertResumeThread ... KeAlertResumeThread ... KiUnwaitThread ... KiReadyThread
ntdll
See notes in NtAlertThread.
NT headers.
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.
NtClose ... ObpCloseHandle ... ObpCloseHandleTableEntry ... ExDestroyHandle ... ExpFreeHandleTableEntry
ntdll, ntoskrnl
NT headers.
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
NtCreateDebugObject ... ObCreateObject ...
ntdll
NT headers
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.
NtCreateDirectoryObject ... ObCreateObject ...
ntdll; ZwCreateDirectoryObject is exported by ntoskrnl
NT headers
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.
NtCreateProcess ... NtCreateProcessEx ... PspCreateProcess ...
PspAllocateProcess ... KeInitializeProcess
ntdll
The new process does not have any threads. You can create one using NtCreateThread or
RtlCreateUserThread.
NT headers.
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.
NtCreateProcessEx ... PspCreateProcess ... PspAllocateProcess ...
KeInitializeProcess
ntdll
NT headers.
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.
NtCreateThread ... PspCreateThread ... PspAllocateThread ...
KeInitThread ...
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.
NT headers.
The documentation for this function has been produced by reverse-engineering and may be incorrect.
Creates a thread.
NTSYSCALLAPI
NTSTATUS
NTAPI
NtCreateThreadEx(
__out PHANDLE ThreadHandle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_ATTRIBUTES ObjectAttributes,
__in HANDLE ProcessHandle,
__in PVOID StartAddress,
__in PVOID Parameter,
__in ULONG Flags,
__in_opt ULONG Reserved,
__in_opt ULONG StackCommit,
__in_opt ULONG StackReserve,
__in_opt PVOID ProcessContext
);
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 function.
Flags which control the creation of the thread:
#define THREAD_CREATE_FLAGS_SUSPENDED 0x1
This value is ignored by the operating system.
The number of bytes to commit in the thread stack.
The number of bytes to reserve for the thread stack.
An optional structure which is passed to PspBuildCreateProcessContext.
NtCreateThreadEx ... PspCreateThread ... PspAllocateThread ...
KeInitThread ...
ntdll
wj32
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.
NtOpenProcess ... PsOpenProcess ... ObOpenObjectByPointer ...
ntdll, ntoskrnl
NT headers.
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.
NtQueueApcThread ... KeInsertQueueApc ... KiInsertQueueApc ... InsertHeadList
ntdll; KeInsertQueueApc is exported by ntoskrnl
NT headers.
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
NT headers.
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.
NtResumeProcess ... PsResumeProcess ... KeResumeThread ...
KiWaitTest ...
ntdll; PsResumeProcess is exported by ntoskrnl
NT headers.
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).
NtResumeThread ... KeResumeThread ... KiWaitTest ...
ntdll
NT headers.
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.
NtSuspendProcess ... PsSuspendProcess ... PsSuspendThread ...
KeSuspendThread ... KiInsertQueueApc ... KiSuspendThread ...
KeWaitForSingleObject ...
ntdll; PsSuspendProcess is exported by ntoskrnl
NT headers.
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).
NtSuspendThread ... PsSuspendThread ... KeSuspendThread ...
KiInsertQueueApc ... KiSuspendThread ... KeWaitForSingleObject ...
ntdll
NT headers.
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.
NtTerminateProcess ... PspTerminateAllThreads ... PspTerminateThreadByPointer ...
KeInsertQueueApc ... PspExitNormalApc ... PsExitSpecialApc ...
PspExitThread ... PspExitProcess ...
ntdll; ZwTerminateProcess is exported by ntoskrnl
NT headers.
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.
NtTerminateThread ... PspTerminateThreadByPointer ... KeInsertQueueApc ...
PspExitNormalApc ... PsExitSpecialApc ... PspExitThread ...
KeTerminateThread ... KiInsertQueue ... [PspReaper] KeDeleteThread ...
ntdll
NT headers.
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
);
NtTestAlert ... KeTestAlertThread
ntdll; KeTestAlertThread is exported by ntoskrnl
See notes in NtAlertThread.
NT headers.
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;
RtlCreateUserProcess ... NtCreateProcess ...
ntdll
This RtlCreateUserProcess does not notify CSR of the new process, so the process' use of the
Windows API is limited.
NT headers.
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.
RtlCreateUserThread ... NtCreateThread ...
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
Windows API.
NT headers.