PsLookupProcessByProcessId возвращает STATUS_SUCCESS, даже если pid неверен

#c #windows #driver #internals

#c #Windows #драйвер #внутренние компоненты

Вопрос:

Я проверяю из своего драйвера, все ли еще запущено мое приложение пользовательского режима, при этом я использую PsLookupProcessByProcessId, чтобы проверить, существует ли процесс. и это работает в начале, но даже после того, как я закрываю свой процесс, и ни один другой процесс не имеет такого же pid, я все равно получаю STATUS_SUCCESS . Кто-нибудь когда-либо сталкивался с таким поведением раньше? Я использую Windows 20h2 для тестирования моего драйвера

Фрагмент моего кода

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

Заранее извините за мой плохой английский 🙂

Ответ №1:

Когда процесс завершается, 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, amp;zeroTime ) == STATUS_WAIT_0;
}
 

Объединить с вашим кодом:

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

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

Если приведенный выше код не работает, вы также можете попробовать:

 IsTerminated = PsGetProcessExitStatus(LoaderProccess) != STATUS_PENDING;
 

Если это все еще не работает, последнее решение, которое я могу предоставить, — использовать ZwQuerySystemInformation для перечисления процессов и проверки, есть ли ваш процесс в связанном списке.