目录
KernelBase.dll - > TerminateThread
Ntkrnlpa.exe - > NtTerminateThread
前言
异步过程调用中提到线程是不会被结束的,线程是自己结束自己。通过逆向分析TerminateThread论证.
KernelBase.dll - > TerminateThread
参数校验、环境校验后调用NtTerminateThread
Ntkrnlpa.exe - > NtTerminateThread
线程handle为0时,会通过线程KTHREAD结构中成员ApcState.Process获取当前线程所属进程.再判断进程下活动线程数,如果活动线程数为1(主线程),设置错误码C00000DB跳转返回.如果活动线程数不为1(大于1)执行PspTerminateThreadByPointer参数3为1.
线程handle非0时,首先通过handle获取线程内核对象,如果结束线程为当前核运行线程或结束自身执行PspTerminateThreadByPointer参数3为1,反之为0.
PspTerminateThreadByPointer
函数原型
NTSTATUS
PspTerminateThreadByPointer(
IN PETHREAD Thread, //线程内核结构
IN NTSTATUS ExitStatus, //退出码
IN BOOLEAN DirectTerminate //是否直接结束
);
当参数DirectTerminate为1时,当前运行线程和结束线程相同情况下执行PspExitThread.
当参数DirectTerminate为0时,可以看出并没有发现任何结束线程代码,而且通过ExAllocatePoolWithTag申请一块内存存储KAPC,调用KeInitializeApc初始化APC、KeInsertQueueApc插入APC.
线程切换和系统调用都会检查线程是否有APC等待处理,如果A线程调用TerminateThread结束B线程,当B线程执行时检查APC队列发现有"结束APC"它会自己结束掉自己.
上述分析可以得知线程是自己干掉自己......