首页 > 解决方案 > 即使 pid 错误,PsLookupProcessByProcessId 也会返回 STATUS_SUCCESS

问题描述

我正在从我的驱动程序检查我的用户模式应用程序是否仍在运行,同时我使用 PsLookupProcessByProcessId 检查进程是否仍然存在。并且它在开始时有效,但即使在我关闭我的进程并且没有其他进程具有相同的 pid 之后,我仍然得到 STATUS_SUCCESS。以前有人遇到过这种行为吗?我在 Windows 20h2 上运行以测试我的驱动程序

我的代码片段

NTSTATUS status = PsLookupProcessByProcessId((HANDLE)UserModePid, &UserModeProcess);
if (status == STATUS_INVALID_PARAMETER) {
    DbgPrintEx(0, 0, "[Driver] Invalid Process\n");
    ExitKernel();
}
else {
    DbgPrintEx(0, 0, "[Driver] Status : %llx", status);
}

提前抱歉我的英语不好:)

标签: cwindowsdriverinternals

解决方案


当一个进程退出时,Windows 不会EPROCESS立即释放它,而是保留一段时间(因为引用计数还没有减少到 0)。

以下代码可以很好地确定进程是否已退出(从Blackbone复制):

/// <summary>
/// Check if process is terminating
/// </summary>
/// <param name="imageBase">Process</param>
/// <returns>If TRUE - terminating</returns>
BOOLEAN BBCheckProcessTermination( PEPROCESS pProcess )
{
    LARGE_INTEGER zeroTime = { 0 };
    return KeWaitForSingleObject( pProcess, Executive, KernelMode, FALSE, &zeroTime ) == STATUS_WAIT_0;
}

结合您的代码:

bool IsTerminated;
NTSTATUS Status = PsLookupProcessByProcessId((HANDLE)LoaderPid, &LoaderProccess);
if (!NT_SUCCESS(Status)) {
    IsTerminated = true;
}
else {
    IsTerminated = BBCheckProcessTermination(LoaderProccess);
    ObDereferenceObject(LoaderProccess);
}

if (IsTerminated) {
    DbgPrintEx(0, 0, "[Driver] Invalid Process\n");
    ExitKernel();
}
else {
    DbgPrintEx(0, 0, "[Driver] Status : %llx", Status);
}

如果上面的代码不起作用,你也可以试试:

IsTerminated = PsGetProcessExitStatus(LoaderProccess) != STATUS_PENDING;

如果它仍然不起作用,我可以提供的最后一个解决方案是使用ZwQuerySystemInformation枚举进程并检查您的进程是否在链接列表中。


推荐阅读