简体   繁体   中英

How get current process image file full name in filter driver?

In filter driver I can call IoGetCurrentProcess to get an PEPROCESS structure, and than call PsGetProcessImageFileName to get file name.

My questions is how I can get full name of the process image file?

You can use ZwQueryInformationProcess with the information class of 27. THe following code uses this routine to obtain the full image file name from process' handle.

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

You can obtain the process handle by the following ways:

  • ObOpenObjectByPointer , you need process' EPROCESS address ( PsLookupProcessByProcessId may help).

  • ZwOpenProcess – youn need to know PID of the target process.

However, using this code in every invocation of your minifilter's pre/post callback can be quite time-consuming. I solve this problem by caching process names in a hash table that uses PID as a key. Notify routines ( PsSetXXXNotifyRoutine(Ex) ) may prove very useful when building and managing such a table.

here I found full code like @Martin Drab code

EDIT : new fixed 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);
    }

    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM