一丶简介

我们遇到的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, 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');
}
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路径.

内核中通过进程PID获取进程的全部路径的更多相关文章

  1. 内核中根据进程Pid获取卷的全目录

    目录 一丶简介 二丶原理 3.代码实现. 一丶简介 在内核中有时候想通过PID 获取进程的全路径以达到监控的作用 比如我们设置了进程回调.则可以根据PID看下进程的全路径. 二丶原理 原理就是在内核中 ...

  2. 通过PID获取进程路径的几种方法

    通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...

  3. Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结

    Atitit,通过pid获取进程文件路径 java php  c#.net版本大总结 1. 通过PID获取进程路径的几种方法2 1.1. GetModuleFileNameEx 想获得进程可执行文件的 ...

  4. delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)

    uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...

  5. C#依据进程名称获取进程的句柄?

    C#依据进程名称获取进程的句柄或C#怎样获取其它进程的句柄? 有时候标题名是动态变化的,所以不使用FindWindow方法! [StructLayout(LayoutKind.Sequential)] ...

  6. C#根据进程名称获取进程的句柄?

    C#根据进程名称获取进程的句柄或C#如何获取其他进程的句柄? 有时候标题名是动态变化的,所以不使用FindWindow方法! [StructLayout(LayoutKind.Sequential)] ...

  7. windows中根据进程PID查找进程对象过程深入分析

    这里windows和Linxu系列的PID 管理方式有所不同,windows中进程的PID和句柄没有本质区别,根据句柄索引对象和根据PID或者TID查找进程或者线程的步骤也是一样的.   句柄是针对进 ...

  8. Linux内核中namespace之PID namespace

    前面看了LInux PCI设备初始化,看得有点晕,就转手整理下之前写的笔记,同时休息一下!!~(@^_^@)~ 这片文章是之前写的,其中参考了某些大牛们的博客!! PID框架的设计 一个框架的设计会考 ...

  9. 如何查看Java进程并获取进程ID?

    1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 tomcat 的 to 按 tab).2. ps ...

随机推荐

  1. 14-2 SQL语言简介

    1.结构化查询语言(Structured Query Language,SQL),常被读作sequel,最初是由Microsoft.Sybase和Ashton-Tate这3家公司共同开发的. 2.Wi ...

  2. java之struts2的action的创建方式

    首先action是用来处理请求的, 这里struts2中的action的3中创建方式. 1.无侵入性的创建方式. 无侵入性:使用第三方的框架,不直接继承或实现第三方提供的类或者接口就说是无侵入性的. ...

  3. 并发编程之Callable异步,Future模式

    Callable 在Java中,创建线程一般有两种方式,一种是继承Thread类,一种是实现Runnable接口.然而,这两种方式的缺点是在线程任务执行结束后,无法获取执行结果.我们一般只能采用共享变 ...

  4. 【洛谷 P1659】 [国家集训队]拉拉队排练(manacher)

    题目链接 马拉车+简单膜你 #include <cstdio> #include <cstring> #include <algorithm> using name ...

  5. Flutter裁剪图片

    最近在学习中需要用到裁剪图片,记录一下解决方法 思路: 使用canvas的drawImageRect()方法,对Image进行裁剪,这里的Image需要 'dart:ui' 库中的Image. 1. ...

  6. 【阿里云开发】- 搭建和卸载svn服务器

    Subversion(SVN) 是一个开源的版本控制系統, 也就是说 Subversion 管理着随时间改变的数据. 这些数据放置在一个中央资料档案库(repository) 中.这个档案库很像一个普 ...

  7. linux下安装dotnet core

    windows下安装linux系统需要用到VMware 这个软件,可自行百度下载,然后安装centos7系统安装 centos下安装dotnetcore 在终端输入命令: sudo yum insta ...

  8. springboot2.1.3 + redisTemplate + Lock 操作 redis 3.0.5

    近期在整合springboot + redis 的功能,本来想用原生的jedit api,最后想想有点 low,搜了一把,boot已经提供给我们操作的方法,那就是 使用 redisTemplate 或 ...

  9. IAR为STM32创建工程模板(基于STM32f103zet6)

    今天给小伙伴分享一篇给stm32新建工程模版 1.首先打开IAR,就是这个样子 2.再建一个目录文件夹 3.建立一个工作空间,以及建好工作空间如右图所示 4.接下来建立工程,Project------ ...

  10. 本地安装部署Jira

    https://blog.csdn.net/u013492736/article/details/83315650 1. 首先在官网下自行搭建服务器的版本,有适合于windows的,也有linux版本 ...