即使 pid 错误,PsLookupProcessByProcessId 也会返回 STATUS_SUCCESS
PsLookupProcessByProcessId is returning STATUS_SUCCESS even if the pid is wrong
我正在从我的驱动程序中检查我的用户模式应用程序是否仍然 运行,
在这样做的同时,我使用 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);
}
抱歉我的英语不好:)
进程退出时,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
枚举进程,检查你的进程是否在链表中。
我正在从我的驱动程序中检查我的用户模式应用程序是否仍然 运行, 在这样做的同时,我使用 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);
}
抱歉我的英语不好:)
进程退出时,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
枚举进程,检查你的进程是否在链表中。