diff --git a/trunk/ProcessHacker.Native/Api/Functions.cs b/trunk/ProcessHacker.Native/Api/Functions.cs
index 0cc955ccf..526d682ee 100644
--- a/trunk/ProcessHacker.Native/Api/Functions.cs
+++ b/trunk/ProcessHacker.Native/Api/Functions.cs
@@ -1885,7 +1885,7 @@ namespace ProcessHacker.Native.Api
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueueUserAPC(
[MarshalAs(UnmanagedType.FunctionPtr)]
- [In] Action Written by wj32. 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 ( Related functions:
+ Related types:
+ 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 A special use of user-mode APCs is thread termination, where a thread termination APC
+ ( 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
+ When a kernel-mode APC is inserted: 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 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:
+ An event is a synchronization object that can be explicitly set to the signaled state. There are two
+ types of events: Related functions:
+ Related types:
+ 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:
+ Related types:
+ 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, Related functions:
+ Related types:
+ 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:
+ Related types:
+ 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:
+ 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:
+ 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:
+ Related types:
+ 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:
+ Related types:
+ A thread can wait for one or more objects; the standard system calls are 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 ( 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. 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 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 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. A structure identifying a process or thread.The Definitive Native API Guide
+ The Definitive Native API Guide
Native API
+ NT Concepts
+
+ ALPC Port
+ NtAlpc*
+ system calls). Existing port-related system calls now redirect to the new ALPC port functions.NtCreatePort (server),
+ NtCreateWaitablePort (server),
+ NtConnectPort (client),
+ NtListenPort (server),
+ NtAcceptConnectPort (server),
+ NtRequestWaitReplyPort (client),
+ NtReplyWaitReceivePort (server),
+ NtReplyWaitReplyPort,
+ NtReplyPort.
+ PORT_MESSAGE,
+ PORT_VIEW,
+ REMOTE_PORT_VIEW,
+ LPCP_PORT_OBJECT.
+ Asynchronous Procedure Calls (APCs)
+ 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 will be interrupted. When the system
+ call returns to user-mode, any pending user-mode APCs will be called.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.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.
+
+ 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.Dispatcher Object
+ NtWaitForSingleObject or
+ NtWaitForMultipleObjects. These functions wait until one or more objects are set to
+ a signaled state. The dispatcher objects are:
+
+ DISPATCHER_HEADER.
+ Event
+
+
+ NtCreateEvent,
+ NtOpenEvent,
+ NtClearEvent,
+ NtPulseEvent,
+ NtQueryEvent,
+ NtResetEvent,
+ NtSetEvent,
+ NtSetEventBoostPriority.
+ EVENT_INFORMATION_CLASS,
+ EVENT_BASIC_INFORMATION,
+ KEVENT.
+ Event Pair
+ NtCreateEventPair,
+ NtOpenEventPair,
+ NtSetHighEventPair,
+ NtSetHighWaitLowEventPair,
+ NtSetLowEventPair,
+ NtSetLowWaitHighEventPair,
+ NtWaitHighEvenPair,
+ NtWaitLowEventPair.
+ EEVENT_PAIR.
+ Keyed Event
+ 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.NtCreateKeyedEvent,
+ NtOpenKeyedEvent,
+ NtReleaseKeyedEvent,
+ NtWaitForKeyedEvent.
+ KEYED_EVENT_OBJECT.
+ Mutant
+ NtCreateMutant,
+ NtOpenMutant,
+ NtQueryMutant,
+ NtReleaseMutant
+ MUTANT_INFORMATION_CLASS,
+ MUTANT_BASIC_INFORMATION,
+ KMUTANT.
+ Port
+ Profile
+ NtCreateProfile,
+ NtQueryIntervalProfile,
+ NtSetIntervalProfile,
+ NtStartProfile,
+ NtStopProfile.
+ Section
+
+
+ NtCreateSection,
+ NtOpenSection,
+ NtAreMappedFilesTheSame,
+ NtExtendSection,
+ NtMapViewOfSection,
+ NtQuerySection,
+ NtUnmapViewOfSection.
+ Semaphore
+ NtCreateSemaphore,
+ NtOpenSemaphore,
+ NtQuerySemaphore,
+ NtReleaseSemaphore.
+ SEMAPHORE_INFORMATION_CLASS,
+ SEMAPHORE_BASIC_INFORMATION,
+ KSEMAPHORE.
+ Timer
+
+
+ NtCreateTimer,
+ NtOpenTimer,
+ NtCancelTimer,
+ NtQueryTimer,
+ NtSetTimer.
+ TIMER_INFORMATION_CLASS,
+ TIMER_BASIC_INFORMATION,
+ ETIMER,
+ KTIMER,
+ PTIMER_APC_ROUTINE.
+ Wait
+ 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.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.NT Enumerations
Debug Object Access
@@ -56,8 +330,8 @@ h4 {
#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 DEBUG_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | DEBUG_READ_EVENT | \
+ DEBUG_PROCESS_ASSIGN | DEBUG_SET_INFORMATION | DEBUG_QUERY_INFORMATION)
Directory Object Access
@@ -68,6 +342,99 @@ h4 {
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xf)
+ Event Access
+
+#define EVENT_QUERY_STATE 0x0001
+#define EVENT_MODIFY_STATE 0x0002
+#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
+
+ Event Pair Access
+
+#define EVENT_PAIR_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE)
+
+ Keyed Event Access
+
+#define KEYEDEVENT_WAIT 0x0001
+#define KEYEDEVENT_WAKE 0x0002
+#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | KEYEDEVENT_WAIT | KEYEDEVENT_WAKE)
+
+ Mutant Access
+
+#define MUTANT_QUERY_STATE 0x0001
+
+#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE| MUTANT_QUERY_STATE)
+
+ Object Flags
+
+#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
+ Members
+ OBJ_INHERIT
+ OBJ_PERMANENT
+ SeCreatePermanentPrivilege in order to
+ create permanent objects.OBJ_EXCLUSIVE
+ OBJ_CASE_INSENSITIVE
+ OBJ_OPENIF
+ STATUS_OBJECT_NAME_COLLISION.OBJ_OPENLINK
+ OBJ_KERNEL_HANDLE
+ OBJ_FORCE_ACCESS_CHECK
+ Profile Access
+
+#define PROFILE_CONTROL 0x0001
+#define PROFILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | PROFILE_CONTROL)
+
+ Section Access
+
+#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)
+
+ Semaphore Access
+
+#define SEMAPHORE_QUERY_STATE 0x0001
+#define SEMAPHORE_MODIFY_STATE 0x0002
+
+#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3)
+
+ Timer Access
+
+#define TIMER_QUERY_STATE 0x0001
+#define TIMER_MODIFY_STATE 0x0002
+
+#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ TIMER_QUERY_STATE | TIMER_MODIFY_STATE)
+
+ NT Structures
+
CLIENT_ID
@@ -128,6 +495,33 @@ typedef struct _INITIAL_TEB
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.
@@ -228,6 +622,8 @@ typedef struct _UNICODE_STRING
Buffer
A buffer containing the string.
+ NT System Calls
+
NtAlertThread
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.
@@ -503,7 +899,7 @@ NtCreateThreadEx(
__in_opt ULONG Reserved,
__in_opt ULONG StackCommit,
__in_opt ULONG StackReserve,
- __in_opt PVOID Unknown
+ __in_opt PVOID ProcessContext
);
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 ...
@@ -572,7 +968,7 @@ NtOpenProcess(
Queues a user-mode APC to the specified thread. The APC will execute when the thread performs an alertable wait or
- calls NtTestAlert.
NtTestAlert. Any wait operations will return with STATUS_USER_APC.
NTSYSCALLAPI NTSTATUS