Lucifer Morningstar
Lucifer Morningstar

Reputation: 51

PsLookupProcessByProcessId is returning STATUS_SUCCESS even if the pid is wrong

I'm checking from my driver if my usermode application is still running, while doing that, I use PsLookupProcessByProcessId to check if the proccess still exists. and it works at the begining but even after I close my process and no other process have the same pid, I still get STATUS_SUCCESS. Anyone has ever encountered this behaviour before? I'm running on Windows 20h2 for testing my driver

Snippet of my code

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);
}

Sorry in advance for my bad english :)

Upvotes: 1

Views: 1611

Answers (1)

Sprite
Sprite

Reputation: 3763

When a process exits, Windows does not free the EPROCESS immediately, but keeps it for a while (because the reference count has not been reduced to 0).

The following code works well to determine if a process has exited (copied from 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;
}

Combine with your code:

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);
}

If the above code does not work, you can also try:

IsTerminated = PsGetProcessExitStatus(LoaderProccess) != STATUS_PENDING;

If it still doesn't work, the last solution I can provide is to use ZwQuerySystemInformation to enumerate the processes and check if your process is in the linked list.

Upvotes: 2

Related Questions