VOID
PspExitThread(
IN NTSTATUS ExitStatus
)
{
PETHREAD_S Thread,ForThread;
PEPROCESS_S Process;
ULONG i;
PEX_CALLBACK_ROUTINE_BLOCK CallBack;
PCREATE_THREAD_NOTIFY_ROUTINE Rtn;
PETHREAD_S WaitThread;
PETHREAD_S DerefThread;
BOOLEAN LastThread;
PLIST_ENTRY Entry, FirstEntry;
PTERMINATION_PORT TerminationPort, NextPort;
NTSTATUS Status;
LPC_CLIENT_DIED_MSG CdMsg;
PVOID ExceptionPort;
BOOLEAN bPspUmsUnInitThread;
PTEB Teb;
PPEB Peb;
PACCESS_TOKEN ProcessToken;
PKAPC_S Apc;
BOOLEAN bGetNext;
ULONG_PTR OldValue;
PETHREAD_S CurThreadOr;
Thread = (PETHREAD_S)PsGetCurrentThread();//rdi
Process = Thread->Tcb.Process;
if (Process != (PEPROCESS_S)Thread->Tcb.ApcState.Process)
{
KeBugCheckEx (
INVALID_PROCESS_ATTACH_ATTEMPT,
(ULONG_PTR)Process,
(ULONG_PTR)Thread->Tcb.ApcState.Process,
(ULONG)Thread->Tcb.ApcStateIndex,
(ULONG_PTR)Thread);
}
KeLowerIrql(PASSIVE_LEVEL);
if (Thread->ActiveExWorker) //454
{
KeBugCheckEx (
ACTIVE_EX_WORKER_THREAD_TERMINATION,
(ULONG_PTR)Thread,
0,
0,
0);
}
if (Thread->Tcb.CombinedApcDisable) //1C4
{
KeBugCheckEx (KERNEL_APC_PENDING_DURING_EXIT,
(ULONG_PTR)0,
(ULONG_PTR)Thread->Tcb.CombinedApcDisable,
(ULONG_PTR)0,
1);
}
ExWaitForRundownProtectionRelease ((PEX_RUNDOWN_REF)&Thread->RundownProtect.Ptr);/*0x438*/
if (Thread->LegacyPowerObject)///*0x420*/
{
PoDeletePowerRequest(Thread->LegacyPowerObject);
Thread->LegacyPowerObject = NULL;
}
((Old_WmiTraceThread)EtwTraceThread)(Thread,NULL,FALSE);
//检查到这里OK
Thread->ExitStatus = ExitStatus;/*0x380*/
Thread->Tcb.KernelApcDisable--;
if ((*(PDWORD)((ULONGLONG)PspNotifyEnableMask)) & 8)
{
for (i=0; i < 0x40; i++)
{
CallBack = ((Old_ExReferenceCallBackBlock)ExReferenceCallBackBlock)
(&((PEX_CALLBACK)PspCreateThreadNotifyRoutine)[i]);
if (CallBack)
{
Rtn = (PCREATE_THREAD_NOTIFY_ROUTINE) ((Old_ExGetCallBackBlockRoutine)ExGetCallBackBlockRoutine) (CallBack);
Rtn (Process->UniqueProcessId,
Thread->Cid.UniqueThread,
FALSE);
((Old_ExDereferenceCallBackBlock)ExDereferenceCallBackBlock )
(&((PEX_CALLBACK)PspCreateThreadNotifyRoutine)[i],CallBack);
}
}
}
//检查到这里OK
LastThread = FALSE;
DerefThread = NULL;
ExAcquirePushLockExclusive (&Process->ProcessLock);
//检查到这里OK
Process->ActiveThreads--;
if (Process->ActiveThreads == 0)
{
PS_SET_BITS(&Process->Flags, PS_PROCESS_FLAGS_PROCESS_DELETE);
PS_SET_BITS(&Process->Flags2, PS_PROCESS_FLAGS_OUTSWAPPED);
LastThread = TRUE;
if (ExitStatus == STATUS_THREAD_IS_TERMINATING)
Process->ExitStatus = Process->LastThreadExitStatus;
else
Process->ExitStatus = ExitStatus;
for (Entry = Process->ThreadListHead.Flink;//308
Entry != &Process->ThreadListHead;
Entry = Entry->Flink)
{
WaitThread = CONTAINING_RECORD (Entry, ETHREAD_S, ThreadListEntry);
if (WaitThread != Thread &&
!KeReadStateThread (&WaitThread->Tcb) &&
((Old_ObReferenceObjectSafe)ObReferenceObjectSafe)(WaitThread))
{
ExReleasePushLockExclusive(&Process->ProcessLock);
KeLeaveCriticalRegionThread((PKTHREAD_S)Thread);
KeWaitForSingleObject (WaitThread,
Executive,
KernelMode,
FALSE,
NULL);
if (DerefThread)
ObDereferenceObject (DerefThread);
DerefThread = WaitThread;
Thread->Tcb.KernelApcDisable--;
//PspLockProcessExclusive (Process, Thread);
ExAcquirePushLockExclusive(&Process->ProcessLock);
}
}
}
else
{
if (ExitStatus != STATUS_THREAD_IS_TERMINATING)
{
Process->LastThreadExitStatus = ExitStatus;
}
LastThread = FALSE;
}
ExReleasePushLockExclusive(&Process->ProcessLock);
KeLeaveCriticalRegionThread((PKTHREAD_S)Thread);
if (DerefThread)
ObfDereferenceObject (DerefThread);
if (Process->DebugPort != NULL) /*------ DebugPort -----------*/
//if (MyReturnProcessDbgObject(Process) != NULL) /*------ DebugPort -----------*/
{
if (!_bittest((LONG*)&Thread->Tcb.MiscFlags, 0x0D))
{
if (LastThread)
DbgkExitProcess (Process->ExitStatus);
else
DbgkExitThread (ExitStatus);
}
}
//上面检查没有问题OK
if (KD_DEBUGGER_ENABLED)
{
if (Thread->CrossThreadFlags & PS_CROSS_THREAD_FLAGS_BREAK_ON_TERMINATION)
{
if( !( Process->Flags & 0x40000008))
{
PspCatchCriticalBreak("Critical thread 0x%p (in %s) exited\n",
Thread,
Process->ImageFileName);
}
}
}
if (LastThread && _bittest((const signed long *)&Process->Flags, 0xDu) )
{
if (KD_DEBUGGER_ENABLED)
{
PspCatchCriticalBreak ("Critical process 0x%p (%s) exited\n",
Process,
Process->ImageFileName);
} else
{
KeBugCheckEx (CRITICAL_PROCESS_DIED,
(ULONG_PTR)Process,
0,
0,
0);
}
}
//ASSERT(Thread->Tcb.KernelApcDisable == 0);
//上面检查没有问题OK
TerminationPort = Thread->TerminationPort;
if (TerminationPort)
{
CdMsg.PortMsg.u1.s1.DataLength = sizeof(LARGE_INTEGER);//8
CdMsg.PortMsg.u1.s1.TotalLength = sizeof(LPC_CLIENT_DIED_MSG);//0x30
CdMsg.PortMsg.u2.s2.Type = LPC_CLIENT_DIED;//6
CdMsg.PortMsg.u2.s2.DataInfoOffset = 0;//0
CdMsg.CreateTime.QuadPart = PS_GET_THREAD_CREATE_TIME (Thread);
do
{
while (TRUE)
{
Status = ((Old_LpcRequestPort)LpcRequestPort) (TerminationPort->Port, (PPORT_MESSAGE)&CdMsg);
if (Status == STATUS_NO_MEMORY || Status == STATUS_INSUFFICIENT_RESOURCES)
{
KeDelayExecutionThread (KernelMode, FALSE, (PLARGE_INTEGER)PspShortTime);
continue;
}
break;
}
ObfDereferenceObject (TerminationPort->Port);
NextPort = TerminationPort->Next;
ExFreePoolWithTag (TerminationPort, 'pTsP'|PROTECTED_POOL);
TerminationPort = NextPort;
} while (TerminationPort);
}
//上面检查没有问题OK
if (Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_DEADTHREAD )
{
ExceptionPort = PsCaptureExceptionPort(Process);
if (ExceptionPort)
{
CdMsg.PortMsg.u1.s1.DataLength = sizeof (LARGE_INTEGER);
CdMsg.PortMsg.u1.s1.TotalLength = sizeof (LPC_CLIENT_DIED_MSG);
CdMsg.PortMsg.u2.s2.Type = LPC_CLIENT_DIED;
CdMsg.PortMsg.u2.s2.DataInfoOffset = 0;
CdMsg.CreateTime.QuadPart = PS_GET_THREAD_CREATE_TIME (Thread);
while (TRUE)
{
PETHREAD_S CueThread;
CueThread = PsGetCurrentThread();
CueThread->Tcb.KernelApcDisable--;
Status = ((Old_AlpcpSendMessage)AlpcpSendMessage)(
&ExceptionPort,
&CdMsg.PortMsg.u1.s1.DataLength,
0,
0);
CueThread = PsGetCurrentThread();
KeLeaveCriticalRegionThread((PKTHREAD_S)CueThread);
if (Status != STATUS_NO_MEMORY && Status != STATUS_INSUFFICIENT_RESOURCES)
break;
KeDelayExecutionThread (KernelMode, FALSE, (PLARGE_INTEGER)PspShortTime);
}
ObfDereferenceObject (ExceptionPort);
}
}
//上面检查没有问题OK
if (Thread->Tcb.Win32Thread)
((PKWIN32_THREAD_CALLOUT)(PspW32ThreadCallout)) (Thread, PsW32ThreadCalloutExit);
if (LastThread && Process->Win32Process)
((PKWIN32_PROCESS_CALLOUT)(PspW32ProcessCallout)) (Process, FALSE);
if (!Thread->Tcb.EnableStackSwap)
KeBugCheckEx (KERNEL_STACK_LOCKED_AT_EXIT, 0, 0, 0, 0);
((Old_IoCancelThreadIo)IoCancelThreadIo )(Thread);
((Old_ExTimerRundown)ExTimerRundown) ();
CurThreadOr = Thread;
((Old_CmNotifyRunDown)CmNotifyRunDown) (Thread);
((Old_KeRundownThread)KeRundownThread) ();
//if ((*(PBYTE)((ULONGLONG)Thread+3))&0x40)
//{
// bPspUmsUnInitThread = TRUE;
// ((Old_PspUmsUnInitThread)PspUmsUnInitThread)(Thread);
//}
//else
//{
// bPspUmsUnInitThread = FALSE;
// if ((*(PBYTE)((ULONGLONG)Thread+3))&0x80)
// {
// ((Old_PspUmsUnInitThread)PspUmsUnInitThread)(Thread);
// }
//}
if ((*(PBYTE)((ULONGLONG)Thread + 3)) & 0x40)
bPspUmsUnInitThread = TRUE;
else
{
bPspUmsUnInitThread = FALSE;
if (!((*(PBYTE)((ULONGLONG)Thread + 3)) & 0x80))
goto LABEL_35;
}
((Old_PspUmsUnInitThread)PspUmsUnInitThread)(Thread);
LABEL_35:
bGetNext = FALSE;
if (bPspUmsUnInitThread)
{
Thread->Tcb.KernelApcDisable--;
ExAcquirePushLockExclusive (&Process->ProcessLock);
if ( (Process->UmsScheduledThreads -= 1) == 0)
{
bGetNext = FALSE;
if (Process->Flags&0x40000008)
bGetNext = TRUE;
}
ExReleasePushLockExclusive(&Process->ProcessLock);
KeLeaveCriticalRegionThread((PKTHREAD_S)Thread);
}
//上面检查没有问题OK
if (bGetNext)
{
for (ForThread = PsGetNextProcessThread (Process, NULL);
ForThread != NULL;
ForThread = PsGetNextProcessThread (Process, ForThread))
{
if (ExAcquireRundownProtection(&ForThread->RundownProtect))
{
PETHREAD_S TempThread;
if (ForThread == NULL)
TempThread = PsGetCurrentThread();
else
TempThread = ForThread ;
if ((*(PBYTE)((ULONGLONG)TempThread+3))&0x80)
{
((Old_KeRundownQueueEx)KeRundownQueueEx)(ForThread->Tcb.Ucb->UmsAssociatedQueue,TRUE);
}
ExReleaseRundownProtection(&ForThread->RundownProtect);
}
}
}
Teb = (PTEB)Thread->Tcb.Teb;
Thread->Tcb.Teb = NULL;
Thread->Tcb.KernelApcDisable--;
_InterlockedOr((volatile LONG *)&CurThreadOr, 0);
_mm_lfence();
_InterlockedOr((volatile LONG *)&CurThreadOr, 0);
_mm_lfence();
if (Thread->ThreadLock.Value&1)
{
((Old_ExfAcquirePushLockExclusive)ExfAcquirePushLockExclusive) (&Thread->ThreadLock);
((Old_ExfReleasePushLockExclusive)ExfReleasePushLockExclusive)(&Thread->ThreadLock);
}
//上面检查没有问题OK
KeLeaveCriticalRegionThread((PKTHREAD_S)Thread);
//if (Thread->Tcb.SystemThread == 0)
if (!_bittest((const signed long *)&Thread->Tcb.MiscFlags, 0xDu))
{
if (!(Process->Flags&0x40000008))
{
if (Thread->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_DEADTHREAD)
{
SIZE_T Zero;
PVOID BaseAddress;
Zero = 0;
BaseAddress = Teb->DeallocationStack;
((Old_ZwFreeVirtualMemory)ZwFreeVirtualMemory) (
NtCurrentProcess (),
&BaseAddress,
&Zero,
MEM_RELEASE);
if (Process->Wow64Process)
((Old_RtlFreeUserStack)RtlFreeUserStack)(*(ULONG*)((ULONGLONG)Teb+0x2E0C));
}
if (Teb->DbgSsReserved[1])
ObCloseHandle (Teb->DbgSsReserved[1], UserMode);
((Old_MmDeleteTeb)MmDeleteTeb)(Process,Teb);
}
}
//Thread->ExitStatus = ExitStatus;
KeQuerySystemTime (&Thread->ExitTime);
if (LastThread)
{
Process->ExitTime = Thread->ExitTime;
((Old_PspExitProcess)PspExitProcess) (TRUE, Process);
ProcessToken = ((Old_PsReferencePrimaryToken)PsReferencePrimaryToken) (Process);
if (((Old_SeAuditingWithTokenForSubcategory)SeAuditingWithTokenForSubcategory) (0x82,ProcessToken))
{
((Old_SeAuditProcessExit)SeAuditProcessExit) (Process,ExitStatus);
}
PsDereferencePrimaryTokenEx (Process, ProcessToken);
((Old_ObKillProcess) ObKillProcess) (Process);
if (Process->SectionObject != NULL)
{
ObDereferenceObject (Process->SectionObject);
Process->SectionObject = NULL;
}
if (Process->Job != NULL)
((Old_PspExitProcessFromJob)PspExitProcessFromJob )(Process->Job, Process);
}
//上面检查没有问题OK
Thread->Tcb.KernelApcDisable--;
_interlockedbittestandreset((volatile signed long *)&Thread->Tcb.ThreadFlags, 5u);
((Old_KeForceResumeThread)KeForceResumeThread) (&Thread->Tcb);
KeLeaveCriticalRegionThread((PKTHREAD_S)Thread);
FirstEntry = ((Old_KeFlushQueueApc)KeFlushQueueApc )(Thread, UserMode);
if (FirstEntry != NULL)
{
Entry = FirstEntry;
do
{
Apc =(PKAPC_S) CONTAINING_RECORD (Entry, KAPC, ApcListEntry);
Entry = Entry->Flink;
if (Apc->RundownRoutine)
(Apc->RundownRoutine) (Apc);
else
ExFreePool (Apc);
} while (Entry != FirstEntry);
}
if (LastThread)
{
((Old_MmCleanProcessAddressSpace)MmCleanProcessAddressSpace) (Process);
((Old_MmCleanProcessAddressSpace)LpcExitProcess)(Process);
}
if (Thread->Tcb.LegoData && *(ULONGLONG*)((ULONGLONG)PspLegoNotifyRoutine)) {
((PBBT_NOTIFY_ROUTINE)PspLegoNotifyRoutine) (Thread);
}
FirstEntry = ((Old_KeFlushQueueApc)KeFlushQueueApc ) (Thread, KernelMode);
if (FirstEntry != NULL || Thread->Tcb.KernelApcDisable != 0)
{
KeBugCheckEx (KERNEL_APC_PENDING_DURING_EXIT,
(ULONG_PTR)FirstEntry,
(ULONG_PTR)Thread->Tcb.KernelApcDisable,
(ULONG_PTR)KeGetCurrentIrql(),
0);
}
if (LastThread) {
((Old_KeSetProcess)KeSetProcess )((PRKPROCESS_S)&Process->Pcb, 0, FALSE);
}
((Old_KeTerminateThread)KeTerminateThread) ((PVOID)Thread);
}
PVOID PsCaptureExceptionPort(
IN PEPROCESS_S Process)
{
PKTHREAD_S Thread;
PVOID ExceptionPort;
Thread = (PKTHREAD_S)PsGetCurrentThread();
ExceptionPort = Process->ExceptionPortData;
if (ExceptionPort != NULL)
{
Thread->KernelApcDisable--;
ExAcquirePushLockShared(&Process->ProcessLock);
ExceptionPort = (PVOID)((ULONGLONG)ExceptionPort & ~0x7);
ObfReferenceObject(ExceptionPort);
ExReleasePushLockShared(&Process->ProcessLock);
KeLeaveCriticalRegionThread(Thread);
}
return ExceptionPort;
}
VOID
FORCEINLINE
ExReleasePushLockExclusive (
IN PEX_PUSH_LOCK PushLock
)
{
EX_PUSH_LOCK OldValue;
#if DBG
OldValue = *PushLock;
ASSERT (OldValue.Locked);
ASSERT (OldValue.Waiting || OldValue.Shared == 0);
#endif
OldValue.Value = (ULONG32)InterlockedExchangeAdd64 ((PLONG64)&PushLock->Value, -(LONG64)EX_PUSH_LOCK_LOCK);
if (!OldValue.Waiting || OldValue.Waking) {
return;
}
((Old_ExfTryToWakePushLock)ExfTryToWakePushLock) (PushLock);
}
VOID
FORCEINLINE
ExAcquirePushLockExclusive (
IN PEX_PUSH_LOCK PushLock
)
{
if (InterlockedBitTestAndSet64 ((LONG64 *)&PushLock->Value, EX_PUSH_LOCK_LOCK_V))
((Old_ExfAcquirePushLockExclusive)ExfAcquirePushLockExclusive) (PushLock);
ASSERT (PushLock->Locked);
}
已经逆向完成
但是有一点小BUG:如果窗口是DOS窗口,进程能够关闭,但是DOS窗口居然关闭不了
,哪位大神如果可以修补一下BUG吧,本人已尽力
如果只是单单拿来调试没有任何问题,也不会蓝屏,请放心
如果有哪位仁兄想讨论,可以加企鹅: 肆1六0七七壹
[培训]科锐逆向工程师培训第53期2025年7月8日开班!