The critical phase of process execution that the summary refers to is the period between the time that the new process object instance is created by nt!ObCreateObject and the time the new process object is inserted into the process object type list by nt!ObInsertObject. The reason this phase is so critical is because it is not safe for things to attempt to obtain a handle to the process object, such as can be done by calling nt!ObOpenObjectByPointer. If an application were to attempt to obtain a handle to the process object before it had been inserted into the process object list by nt!ObInsertObject, critical creation state information that is stored in the process object's header would be overwritten with state information that is meant to be used after the process has passed the initial security validation phase that is handled by nt!ObInsertObject. In some cases, overwriting the creation state information prior to calling nt!ObInsertObject can lead to invalid pointer references when nt!ObInsertObject is eventually called, thus leading to an evil blue screen that some users are all too familiar with.
// // If the object is new then we have work to do otherwise // we'll return with NewObject set to false //
if (ObjectHeader->Flags & OB_FLAG_NEW_OBJECT) {
// // Say the object now isn't new //
ObjectHeader->Flags &= ~OB_FLAG_NEW_OBJECT;
// // If there does exist a quota info structure for this // object then calculate what our charge should be from // the information stored in that structure //
// // There isn't any quota information so we're on our own // Paged pool charge is the default for the object plus // the security descriptor if present. Nonpaged pool charge // is the default for the object. //
to wtxpwh:
xp下,CreateThreadNotifyRoutine回调中都是没法在ring3下用openthread打开的。
原因是PsLookupThreadByThreadId调用会失败。
详细见349K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6*7P5Y4A6W2N6X3q4*7P5Y4A6Q4x3V1k6T1L8r3!0Y4i4K6u0r3K9i4c8W2L8g2)9J5c8X3k6S2z5e0N6T1k6U0p5$3x3$3x3H3j5K6u0V1y4e0W2X3x3X3c8W2x3K6u0W2k6W2)9J5k6h3S2@1L8h3H3`.
A file system filter driver can enumerate active threads by calling PsLookupThreadByThreadId to convert a thread ID to an ETHREAD structure. The thread ID is available in the thread create routine. A file system filter driver can set a thread notification callback routine using PsSetCreateThreadNotifyRoutine. In the notification callback routine, the file system filter driver can use the passed in ThreadId parameter and call PsLookupThreadByThreadId to locate the ETHREAD structure.
NTSTATUS
PspCreateThread(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle,
IN PEPROCESS ProcessPointer,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PCONTEXT ThreadContext OPTIONAL,
IN PINITIAL_TEB InitialTeb OPTIONAL,
IN BOOLEAN CreateSuspended,
IN PKSTART_ROUTINE StartRoutine OPTIONAL,
IN PVOID StartContext
)
{
//
// ...... 省略无关代码 ......
//
RtlZeroMemory (Thread, sizeof (ETHREAD));
//
// Initialize rundown protection for cross thread TEB refs etc.
//
ExInitializeRundownProtection (&Thread->RundownProtect);
//
// Assign this thread to the process so that from now on
// we don't have to dereference in error paths.
//
Thread->ThreadsProcess = Process;
for (i = 0; i < PSP_MAX_CREATE_THREAD_NOTIFY; i++) {
CallBack = ExReferenceCallBackBlock (&PspCreateThreadNotifyRoutine[i]);
if (CallBack != NULL) {
Rtn = (PCREATE_THREAD_NOTIFY_ROUTINE) ExGetCallBackBlockRoutine (CallBack);
Rtn (Thread->Cid.UniqueProcess,
Thread->Cid.UniqueThread,
TRUE);
ExDereferenceCallBackBlock (&PspCreateThreadNotifyRoutine[i],
CallBack);
}
}
}
//
// ...... 省略无关代码 ......
//
if ((Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_DEADTHREAD) == 0) {
Status = ObGetObjectSecurity (Thread,
&SecurityDescriptor,
&MemoryAllocated);
if (!NT_SUCCESS (Status)) {
//
// This trick us used so that Dbgk doesn't report
// events for dead threads
//
PS_SET_BITS (&Thread->CrossThreadFlags,
PS_CROSS_THREAD_FLAGS_DEADTHREAD);
NTSTATUS
FsRtlCreateSectionForDataScan(
OUT PHANDLE SectionHandle,
OUT PVOID *SectionObject,
OUT PLARGE_INTEGER SectionFileSize OPTIONAL,
IN PFILE_OBJECT FileObject,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER MaximumSize OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN ULONG Flags
);