如何在过滤器驱动程序中获取当前过程映像文件全名?

时间:2016-09-06 12:04:13

标签: c++ c process driver filter-driver

在过滤器驱动程序中,我可以调用IoGetCurrentProcess来获取PEPROCESS结构,然后调用PsGetProcessImageFileName来获取文件名。

我的问题是我如何获得过程图像文件的完整名称?

2 个答案:

答案 0 :(得分: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地址(PsLookupProcessByProcessId可能有帮助)。

  • ZwOpenProcess - 您需要了解目标流程的PID。

但是,在每次调用minifilter的前/后回调时使用此代码可能非常耗时。我通过在使用PID作为键的哈希表中缓存进程名称来解决此问题。在构建和管理这样的表时,通知例程(PsSetXXXNotifyRoutine(Ex))可能非常有用。

答案 1 :(得分:1)

here我找到了像@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);
    }

    // ...
}