用Windbg看了遍PspTerminateThreadByPointer,发现和WRK上的一样.哈哈,没有任何出入.这样自己实现起来就方便咯.
btw: XP SP2下是2个参数
NTSTATUS
PspTerminateThreadByPointer(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN DirectTerminate
)
{
NTSTATUS Status;
PKAPC ExitApc=NULL;
ULONG OldMask;
PAGED_CODE();
if (Thread->CrossThreadFlags
& PS_CROSS_THREAD_FLAGS_BREAK_ON_TERMINATION) {
PspCatchCriticalBreak("Terminating critical thread 0x%p (in %s)\n",
Thread,
THREAD_TO_PROCESS(Thread)->ImageFileName);
}
if (DirectTerminate && Thread == PsGetCurrentThread()) {
ASSERT (KeGetCurrentIrql() < APC_LEVEL);
PS_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_TERMINATED);
PspExitThread (ExitStatus);
} else {
// 10h
// 嘿嘿,若thread的flag中有PS_CROSS_THREAD_FLAGS_SYSTEM, 就pass了. =。=||
if (IS_SYSTEM_THREAD (Thread)) {
return STATUS_ACCESS_DENIED;
}
Status = STATUS_SUCCESS;
while (1) {
ExitApc = (PKAPC) ExAllocatePoolWithTag (NonPagedPool,
sizeof(KAPC),
'xEsP');
if (ExitApc != NULL) {
break;
}
KeDelayExecutionThread(KernelMode, FALSE, &ShortTime);
}
// Mark the thread as terminating and call the exit function.
OldMask = PS_TEST_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_TERMINATED);// 01h
// 若之前没有设置过关闭标志,那就插个APC
if ((OldMask & PS_CROSS_THREAD_FLAGS_TERMINATED) == 0) {
KeInitializeApc (ExitApc,
PsGetKernelThread (Thread),
OriginalApcEnvironment,
PsExitSpecialApc,
PspExitApcRundown,
PspExitNormalApc,
KernelMode,
ULongToPtr (ExitStatus));
if (!KeInsertQueueApc (ExitApc, ExitApc, NULL, 2)) {
// 看来可以在KeInsertQueueApc上做手脚啦。
ExFreePool (ExitApc);
Status = STATUS_UNSUCCESSFUL;
} else {
KeForceResumeThread (&Thread->Tcb);
}
} else {
ExFreePool (ExitApc);
}
}
return Status;
}
是自身线程就直接调用PspExitThread,其他情况就插APC。。。
btw:炉子半年前就把这些弄透了,俺现在才开始学习。差距啊
PspTerminateThreadByPointer.txt (6.37 KB)