admin 发表于 2024-2-20 21:54:45

windows 驱动 内核 0环 通过PID 获取进程完整路径

#include<ntifs.h>

NTSTATUS GetDosPathByProcessId(IN ULONG pid, OUT PANSI_STRING pAnsiNtPath);

typedef NTSTATUS(*PfnZwQueryInformationProcess) (
        __in HANDLE ProcessHandle,
        __in PROCESSINFOCLASS ProcessInformationClass,
        __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
        __in ULONG ProcessInformationLength,
        __out_opt PULONG ReturnLength
        );

PfnZwQueryInformationProcess ZwQueryInformationProcess;

//初始化未公开的导出函数
NTSTATUS InitGloableFunction()
{
        UNICODE_STRING UtrZwQueryInformationProcessName =
                RTL_CONSTANT_STRING(L"ZwQueryInformationProcess");
        ZwQueryInformationProcess =
                (PfnZwQueryInformationProcess)MmGetSystemRoutineAddress(&UtrZwQueryInformationProcessName);
        return STATUS_SUCCESS;
}

NTSTATUS GetDosPathByProcessId(IN ULONG pid, OUT PANSI_STRING pAnsiNtPath)
{
        /*
        1.根据PID获取进程句柄
        2.使用ZwQueryInformationProcess 传入HANDLE 使用27号功能获取路径
        */
        HANDLE hProcess = 0;
        CLIENT_ID cid;
        OBJECT_ATTRIBUTES obj;
        NTSTATUS ntStatus;
        ULONG RetLength = 0;
        PVOID pBuffer = NULL;
        HANDLE hFile;
        IO_STATUS_BLOCK iostu;
        PVOID FileObject = NULL;
        PFILE_OBJECT pMyFileObject = NULL;
        UNICODE_STRING DosName;

        UNICODE_STRING FunllPath;

        if (ZwQueryInformationProcess == NULL)
                return STATUS_UNSUCCESSFUL;

        cid.UniqueProcess = (HANDLE)pid;
        cid.UniqueThread = 0;
        InitializeObjectAttributes(&obj, 0, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
        ntStatus = ZwOpenProcess(&hProcess, PROCESS_ALL_ACCESS, &obj, &cid);
        if (!NT_SUCCESS(ntStatus))
                return STATUS_UNSUCCESSFUL;
        //使用27 号功能遍历

        ntStatus = ZwQueryInformationProcess(hProcess, ProcessImageFileName, NULL, 0, &RetLength);
        if (STATUS_INFO_LENGTH_MISMATCH != ntStatus)
                return STATUS_UNSUCCESSFUL;

        //申请内存继续获取.
        pBuffer = ExAllocatePoolWithTag(PagedPool, RetLength, 'niBI');
        if (NULL == pBuffer)
                return STATUS_UNSUCCESSFUL;
        //重新调用获取.

        ntStatus = ZwQueryInformationProcess(hProcess, ProcessImageFileName, pBuffer, RetLength, &RetLength);
        if (!NT_SUCCESS(ntStatus))
        {
                if (NULL != pBuffer)
                {
                        ExFreePoolWithTag(pBuffer, 'niBI');
                }
                return STATUS_UNSUCCESSFUL;
        }

        //开始转化路径
        InitializeObjectAttributes(&obj, pBuffer, OBJ_KERNEL_HANDLE, 0, 0);
        ntStatus = ZwOpenFile(
                &hFile,
                GENERIC_READ,
                &obj,
                &iostu,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                0);
        if (!NT_SUCCESS(ntStatus))
        {
                if (NULL != pBuffer)
                {
                        ExFreePoolWithTag(pBuffer, 'niBI');
                }
                ZwClose(hFile);
                return STATUS_UNSUCCESSFUL;
        }

        //获得文件对象
        ntStatus = ObReferenceObjectByHandle(
                hFile,
                GENERIC_ALL,
                *IoFileObjectType,
                KernelMode,
                &FileObject,
                NULL);

        if (!NT_SUCCESS(ntStatus))
        {
                if (NULL != pBuffer)
                {
                        ExFreePoolWithTag(pBuffer, 'niBI');
                }

                if(FileObject)                ntStatus = (NTSTATUS) ObDereferenceObject(FileObject);

                ZwClose(hFile);
                return STATUS_UNSUCCESSFUL;
        }

        pMyFileObject = (PFILE_OBJECT)FileObject;

        if (NULL == pMyFileObject)
        {
                if (NULL != pBuffer)
                {
                        ExFreePoolWithTag(pBuffer, 'niBI');
                }
                ntStatus = (NTSTATUS)ObDereferenceObject(FileObject);
                ZwClose(hFile);
                return STATUS_UNSUCCESSFUL;

        }
        //通过 RtlVolumeDeviceToDosName 获取Dos路径 也即是C: D: 等盘符
        RtlVolumeDeviceToDosName(pMyFileObject->DeviceObject, &DosName);

        //获得路径直接直接拼接即可.

        FunllPath.MaximumLength = pMyFileObject->FileName.MaximumLength + DosName.MaximumLength;
        FunllPath.Length = pMyFileObject->FileName.Length + DosName.Length;
        FunllPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, FunllPath.MaximumLength, 0);

        //拼接路径
        RtlCopyUnicodeString(&FunllPath, &DosName);//得到C:
        RtlAppendUnicodeStringToString(&FunllPath, &pMyFileObject->FileName);//得到C:\\xxx路径,转为Asii
        RtlUnicodeStringToAnsiString(pAnsiNtPath, &FunllPath, TRUE); //RtlFreeAnsiString要释放空间.

        if(FunllPath.Buffer)
        ExFreePool(FunllPath.Buffer); //因为传出自动为其分配了内存所以这个进行谁放

        if (NULL != pBuffer)
        {
                ExFreePoolWithTag(pBuffer, 'niBI');
        }

        ntStatus = (NTSTATUS) ObDereferenceObject(FileObject);
        ZwClose(hFile);
        return STATUS_SUCCESS;
}



页: [1]
查看完整版本: windows 驱动 内核 0环 通过PID 获取进程完整路径