Как получить полное имя файла образа текущего процесса в драйвере фильтра?

В фильтре драйвера я могу позвонить IoGetCurrentProcess чтобы получить PEPROCESS структура, а затем позвоните PsGetProcessImageFileName чтобы получить имя файла.

Мои вопросы, как я могу получить полный имя файла образа процесса?

1

Решение

Ты можешь использовать ZwQueryInformationProcess с информационным классом 27. Следующий код использует эту процедуру для получения полного имени файла изображения из дескриптора процесса.

NTSTATUS GetProcessNameByHandle(_In_ HANDLE ProcessHandle, _Out_ PUNICODE_STRING *Name)
{
ULONG retLength = 0;
ULONG pniSize = 512;
PUNICODE_STRING pni = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;

do {
pni = (PUNICODE_STRING)ExAllocatePoolWithTag(PagedPool, pniSize, POOL_TAG);
if (pni != NULL) {
status = ZwQueryInformationProcess(ProcessHandle, 27, pni, pniSize, &retLength);
if (!NT_SUCCESS(status)) {
ExFreePoolWithTag(pni, POOL_TAG);
pniSize *= 2;
}
} else status = STATUS_INSUFFICIENT_RESOURCES;
} while (status == STATUS_INFO_LENGTH_MISMATCH);

if (NT_SUCCESS(status))
*Name = pni;

return status;
}

Вы можете получить дескриптор процесса следующими способами:

  • ObOpenObjectByPointerВам нужен процесс ‘EPROCESS address (PsLookupProcessByProcessId может помочь).

  • ZwOpenProcess — вам нужно знать PID целевого процесса.

Однако использование этого кода при каждом вызове обратного / обратного вызова вашего минифильтра может занять довольно много времени. Я решаю эту проблему, кэшируя имена процессов в хеш-таблице, в которой в качестве ключа используется PID. Уведомить подпрограммы (PsSetXXXNotifyRoutine(Ex)) может оказаться очень полезным при создании и управлении такой таблицей.

1

Другие решения

Вот Я нашел полный код, как @Martin Drab Code

РЕДАКТИРОВАТЬ: новый фиксированный код

NTSTATUS
GetProcessImageName(
PEPROCESS eProcess,
PUNICODE_STRING* ProcessImageName
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
ULONG returnedLength;
HANDLE hProcess = NULL;

PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process

if (eProcess == NULL)
{
return STATUS_INVALID_PARAMETER_1;
}

status = ObOpenObjectByPointer(eProcess,
0, NULL, 0, 0, KernelMode, &hProcess);
if (!NT_SUCCESS(status))
{
DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
return status;
}

if (ZwQueryInformationProcess == NULL)
{
UNICODE_STRING routineName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess");

ZwQueryInformationProcess =
(QUERY_INFO_PROCESS)MmGetSystemRoutineAddress(&routineName);

if (ZwQueryInformationProcess == NULL)
{
DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
status = STATUS_UNSUCCESSFUL;
goto cleanUp;
}
}

/* Query the actual size of the process path */
status = ZwQueryInformationProcess(hProcess,
ProcessImageFileName,
NULL, // buffer
0,    // buffer size
&returnedLength);

if (STATUS_INFO_LENGTH_MISMATCH != status) {
DbgPrint("ZwQueryInformationProcess status = %x\n", status);
goto cleanUp;
}

*ProcessImageName = kmalloc(returnedLength);

if (ProcessImageName == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanUp;
}

/* Retrieve the process path from the handle to the process */
status = ZwQueryInformationProcess(hProcess,
ProcessImageFileName,
*ProcessImageName,
returnedLength,
&returnedLength);

if (!NT_SUCCESS(status)) kfree(*ProcessImageName);

cleanUp:

ZwClose(hProcess);

return status;
}

FLT_POSTOP_CALLBACK_STATUS
PostCreate(
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
)
{
PUNICODE_STRING pni = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;

status = GetProcessImageName(IoThreadToProcess(Data->Thread), &pni);
if (NT_SUCCESS(status))
{
DbgPrint("ProcessName = %ws\n", pni->Buffer);
kfree(pni);
}
else
{
DbgPrint("GetProcessImageName status = %x\n", status);
}

// ...
}
1

По вопросам рекламы [email protected]