加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

内核中通过进程PID获取进程的全部路径

发布时间:2020-12-15 08:01:13 所属栏目:Java 来源:网络整理
导读:目录 一丶简介 二丶原理 1.原理 2.代码实现. 一丶简介 我们遇到的Dos路径.如果想转化为NT路径(也就是 C:xxxx)类似的格式 需要自己实现. 具体原理如下: 二丶原理 1.原理 1.使用** ZwOpenProcess ** 通过进程PID获取HANDLE 2.使用** ZwQueryInformationProces

目录

  • 一丶简介
    • 二丶原理
      • 1.原理
      • 2.代码实现.

一丶简介

我们遇到的Dos路径.如果想转化为NT路径(也就是 C:xxxx)类似的格式
需要自己实现.
具体原理如下:

二丶原理

1.原理

1.使用** ZwOpenProcess ** 通过进程PID获取HANDLE
2.使用** ZwQueryInformationProcess ** 查询Handle,使用27号(ProcessFileNmae)得到NT路径.
3.使用** ZwOpenFile 打开路径得到Handle
4.使用
ObReferenceObjectByHandle ** 获得 内核对象(FileObject)
5.从FileObject的成员FileName得到其路径
6.使用 RtlVolumeDeviceToDosName 将FileObject设备对象传入.获得Dos路径.也就是盘符
7.拼接路径进行传出

2.代码实现.

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,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,0);
    ntStatus = ZwOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&obj,&cid);
    if (!NT_SUCCESS(ntStatus))
        return STATUS_UNSUCCESSFUL;
    //使用27 号功能遍历
    
    ntStatus = ZwQueryInformationProcess(hProcess,ProcessImageFileName,NULL,&RetLength);
    if (STATUS_INFO_LENGTH_MISMATCH != ntStatus)
        return STATUS_UNSUCCESSFUL;

    //申请内存继续获取.
    pBuffer = ExAllocatePoolWithTag(PagedPool,RetLength,'niBI');
    if (NULL == pBuffer)
        return STATUS_UNSUCCESSFUL;
    //重新调用获取.
    
    ntStatus = ZwQueryInformationProcess(hProcess,pBuffer,&RetLength);
    if (!NT_SUCCESS(ntStatus))
    {
        if (NULL != pBuffer)
        {
            ExFreePoolWithTag(pBuffer,'niBI');
        }
        return STATUS_UNSUCCESSFUL;
    }
    
    //开始转化路径
    InitializeObjectAttributes(&obj,OBJ_KERNEL_HANDLE,0);
    ntStatus = ZwOpenFile(
        &hFile,GENERIC_READ,&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');
        }
        ntStatus = ObDereferenceObject(FileObject);
        ZwClose(hFile);
        return STATUS_UNSUCCESSFUL;
    }
    pMyFileObject = (PFILE_OBJECT)FileObject;
    if (NULL == pMyFileObject)
    {
        if (NULL != pBuffer)
        {
            ExFreePoolWithTag(pBuffer,'niBI');
        }
        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  要释放空间.

    
    ExFreePool(FunllPath.Buffer); //因为传出自动为其分配了内存所以这个进行谁放
    if (NULL != pBuffer)
    {
        ExFreePoolWithTag(pBuffer,'niBI');
    }

    ntStatus = ObDereferenceObject(FileObject);
    ZwClose(hFile);
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegPath)
{


    
    ANSI_STRING AnsiNtPath;
    pDriverObj->DriverUnload = DriverUnLoad;
    InitGloableFunction();
    KdBreakPoint();
    GetDosPathByProcessId(3356,&AnsiNtPath);
    
    return STATUS_SUCCESS;
}

以下为调试的时候的代码截图.
1.得到FileName

2.使用RtlVolumeDeviceToDosName 得到盘符

3.拼接路径为UNICODE_STRING类型

4.为传入的ANSI_STRING 分配空间转换.得到ANSI_STRING路径.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读