为什么我的 windows 进程句柄永远存在?

Why do my windows process handles stick around forever?

我可以在我的系统上找到与任务管理器中未显示的进程关联的进程 ID,因为它们很久以前就终止了,但也不会消失。为了识别它们,我使用这些系统调用:

static int
process_is_zombie(DWORD pid)
{
    DWORD exit_value;
    DWORD dwR;
    HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|SYNCHRONIZE, FALSE, pid);
    if (!process_handle)
        return -1; // no handle attached to pid
    int exit_return = GetExitCodeProcess(process_handle, &exit_value);
    if (!exit_return)
        return -1; // GetExitCodeProcess failed, maybe no permission
    if(exit_value != STILL_ACTIVE)
        return 1; // got a handle, but process is definitely dead
    dwR = WaitForSingleObject(process_handle, 0);
    if(dwR == WAIT_OBJECT_0)
        return 1; // nope, it's really dead
    if(dwR == WAIT_TIMEOUT)
        return 0; // still alive!
    return -1; // WaitForSingleObject failed, maybe no permission
}

在我的系统任务管理器上显示 170 运行 个进程,但是当从 pid 0 扫描到 pid 700_000 时,我发现上述 150_000 个 pid .使用进程 Explorer/Task 管理器检查我系统上活动的进程的句柄没有显示具有超过 2600 个句柄的单个进程,因此 none 我的活动进程似乎让这些僵尸存在。

据我所知,这些 pids 仍然存在,因为它们仍然有句柄。但是,我找不到有关如何找出这些进程 ID 的确切句柄的信息。

这可能吗?如果可以,怎么做?

可以通过三种方式使进程对象(以及进程 ID)保持活动状态。首先,用户模式句柄;您通过检查 Process Explorer and/or 任务管理器中的句柄计数来消除它。其次,内核模式句柄,您使用内核调试器句柄转储消除了它。

最后一种可能性是内核模式引用(在 kd 中又名 "pointers")。这些是使用 ObReferenceObject 和相关函数创建的。

对于一个长期退出的进程,指针计数为 74 表明该引用已被多次泄露。原则上,使用 kd 和 Driver Verifier,可以搜索指向对象的指针并确定哪个驱动程序拥有包含它们的内存。但通过反复试验来识别故障驱动程序可能更实用。祝你好运!