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 :)
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.