在WINDOWS 7 BETA(BUILD 7000)中,ntoskrnl!ZwTerminateProcess 仍是以KiSystemService stub的形式出现

即:

代码:
mov eax , IdOfZwTerminateProcess
lea edx , [esp+arg_0]
pushf
push 8
call KiSystemService
retn 0x8
但在WINDOWS 7 beta之后的某个版本(我不确定,似乎是在7068)中,该函数发生了变化,并且,WINDOWS 7 RC (build 7100)中保留了这一变化:

即ZwTerminateProcess变成了一个真正实现的函数,而不是一个SSDT函数的转发

该函数大体被实现成了如下形式,即调用PsTerminateProcess实现结束进程,并且在内部称为ZwTerminateProcessAssist:

代码:
NTSTATUS ZwTerminateProcessAssist(HANDLE ProcessHandle, NTSTATUS   ExitStatus)
{
NTSTATUS status ;
PVOID ProcessObject;

if ( ProcessHandle )
{
    status = ObReferenceObjectByHandle(ProcessHandle, PROCESS_TERMINATE, PsProcessType, 0, &ProcessObject, 0);
    if ( NT_SUCESS(stat))
    {
       status = PsTerminateProcess(ProcessObject, ExitCode);
      ObfDereferenceObject(ProcessObject);

    }
}
else
{
     status = STATUS_NOT_SUPPORTED;
}
return status ;
}
于是所有在RING0调用的ZwTerminateProcess都进入了这个函数来处理,而RING3调用ntdll!ZwTerminateProcess并经由SysEnter进入系统服务调用时,调用的却仍是NtTerminateProcess,该函数照旧使用遍历进程线程并挨个调用PspTerminateThreadByPointer来进行结束

等价于RING0的调用绕过了SSDT HOOK对这个函数的拦截,同时,这个函数不允许对ProcessHandle = 0的进程进行结束
而此前ZwTerminateProcess是可以传入ProcessHandle = 0 的,当传入为0,WINDOWS默认认为要结束的是当前进程,即:
代码:
NtTerminateProcess
....
.....

    if (ARGUMENT_PRESENT (ProcessHandle)) {
        ProcessHandleSpecified = TRUE;
    } else {
        ProcessHandleSpecified = FALSE;
        ProcessHandle = NtCurrentProcess();
    }


做这样的修改,可能的原因猜想是WINDOWS希望内核调用此函数时避过一些安全软件的SSDT HOOK,并达到对其的良好兼容

这样做确实是一个比较正确的做法,原因是系统的异常处理时,调用KiDispatchException函数,此函数将实现将内核中检测到的异常分发的到RING3的程序中,如果分发不成功,就调用ZwTerminateProcess结束此进程(也就是当前进程), KiDispatchException认为ZwTerminateProcess必然成功,如果ZwTerminateProcess返回(即未成功自杀),KiDispatchException则立即引发KeBugCheckEx

如果有一些安全软件保护了ZwTerminateProcess调用并拒绝来自KernelMode的请求,又遇到目标程序的异常处理没有正常分发,那么系统就会BSOD

当然,仅为了这一目的,替换KiDispatchException中调用的函数即可,但是可能MS觉得希望自己的调用不受到该死的HIPS的影响(其他WINDOWS组件,例如Windows User Mode framework reflector也使用了这个函数),所以做了这样一个改动

这样的改动使驱动级的进程结束更加轻松,但一些安全产品可能面临需要修改自己代码的问题~如果他们从nt!ZwTerminateProcss来定位ZwTerminateProcess的ID的话,那么就会失败了~
另外,一些使用0号HANDLE结束进程技巧的程序,例如著名的EVA同学的knlps,也将会失效了