其实这个已经是一个很老的技巧了,今天挖出来写到blog上。windows在强制结束进程的时候会先结束掉所有的线程,而结束线程调用的是:PspTerminateThreadByPointer,这个函数很有意思。看看就知道了。
它判断ETHREAD里面的CrossThreadFlags;的值,如果这个值等于PS_CROSS_THREAD_FLAGS_SYSTEM ,即是一个系统线程,那么直接返回拒绝访问,那么进程就无法结束了。所以我们把程序的线程改成系统线程,那么就可以达到防杀的目的。当然要杀还是很快的,把值修改回去或者投递一个ExitThread的APC就OK了。当然,觉得不够刺激可以改成PS_CROSS_THREAD_FLAGS_BREAK_ON_TERMINATION,那么结束线程的时候,系统会中断下来,一般是因为没有调试器附加而产生一个bugcheck,即蓝屏。
NTSTATUS
PspTerminateThreadByPointer(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN DirectTerminate
)
/**/ /**/ /**/ /*++
Routine Description:
This function causes the specified thread to terminate.
Arguments:
ThreadHandle - Supplies a referenced pointer to the thread to terminate.
ExitStatus - Supplies the exit status associated with the thread.
DirectTerminate - TRUE is its ok to exit without queing an APC, FALSE otherwise
--*/
... ... {
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) ",
Thread,
THREAD_TO_PROCESS(Thread)->ImageFileName);
}
if (DirectTerminate && Thread == PsGetCurrentThread()) ......{
ASSERT (KeGetCurrentIrql() < APC_LEVEL);
<
PspTerminateThreadByPointer(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN DirectTerminate
)
/**/ /**/ /**/ /*++
Routine Description:
This function causes the specified thread to terminate.
Arguments:
ThreadHandle - Supplies a referenced pointer to the thread to terminate.
ExitStatus - Supplies the exit status associated with the thread.
DirectTerminate - TRUE is its ok to exit without queing an APC, FALSE otherwise
--*/
... ... {
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) ",
Thread,
THREAD_TO_PROCESS(Thread)->ImageFileName);
}
if (DirectTerminate && Thread == PsGetCurrentThread()) ......{
ASSERT (KeGetCurrentIrql() < APC_LEVEL);
<