内核中通过进程PID获取进程的全部路径
一丶简介
我们遇到的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获取进程的全部路径的更多相关文章
- 内核中根据进程Pid获取卷的全目录
目录 一丶简介 二丶原理 3.代码实现. 一丶简介 在内核中有时候想通过PID 获取进程的全路径以达到监控的作用 比如我们设置了进程回调.则可以根据PID看下进程的全路径. 二丶原理 原理就是在内核中 ...
- 通过PID获取进程路径的几种方法
通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...
- Atitit,通过pid获取进程文件路径 java php c#.net版本大总结
Atitit,通过pid获取进程文件路径 java php c#.net版本大总结 1. 通过PID获取进程路径的几种方法2 1.1. GetModuleFileNameEx 想获得进程可执行文件的 ...
- delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)
uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...
- C#依据进程名称获取进程的句柄?
C#依据进程名称获取进程的句柄或C#怎样获取其它进程的句柄? 有时候标题名是动态变化的,所以不使用FindWindow方法! [StructLayout(LayoutKind.Sequential)] ...
- C#根据进程名称获取进程的句柄?
C#根据进程名称获取进程的句柄或C#如何获取其他进程的句柄? 有时候标题名是动态变化的,所以不使用FindWindow方法! [StructLayout(LayoutKind.Sequential)] ...
- windows中根据进程PID查找进程对象过程深入分析
这里windows和Linxu系列的PID 管理方式有所不同,windows中进程的PID和句柄没有本质区别,根据句柄索引对象和根据PID或者TID查找进程或者线程的步骤也是一样的. 句柄是针对进 ...
- Linux内核中namespace之PID namespace
前面看了LInux PCI设备初始化,看得有点晕,就转手整理下之前写的笔记,同时休息一下!!~(@^_^@)~ 这片文章是之前写的,其中参考了某些大牛们的博客!! PID框架的设计 一个框架的设计会考 ...
- 如何查看Java进程并获取进程ID?
1. 在 LINUX 命令平台输入 1-2 个字符后按 Tab 键会自动补全后面的部分(前提是要有这个东西,例如在装了 tomcat 的前提下, 输入 tomcat 的 to 按 tab).2. ps ...
随机推荐
- 私有属性和私有方法l
class Woman: def __init__(self, name): self.name=name self.__age=18 def __secret(self): print(" ...
- 修改Excel脚本
批量修改Excel TODO: 批量修改Excel 功能: 将图片防止在本地,读取excel数据,拆分数据之后根本地照片名称对比,然后上传服务器,创建新得excel. #!/usr/bin/pytho ...
- CSSTab栏下划线跟随效果
神奇的 ~ 选择符 对于当前 hover 的 li ,其对应伪元素的下划线的定位是 left: 100%,而对于 li:hover ~ li::before,它们的定位是 left: 0. ul li ...
- springboot超级详细的日志配置(基于logback)
前言 java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日志框架就能够用 slj4f 调用) ...
- @PropertySources和@ImportReSources注解
修改默认加载的配置文件,加载指定的配置文件. @PropertySources 格式:@PropertySources(value={"classpath:xxx.xxx"}) @ ...
- tengine编译安装及nginx高并发内核参数优化
Tengine Tengine介绍 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性. Tengine的性能和稳定性已经在大型的 ...
- python蟒蛇绘制的代码以及目前还不知道怎么用的RGB颜色对照表
#PythonDraw.py import turtle#引入海龟库 turtle.setup(650,350,200,200)#确定窗口大小,长650,高350,确定窗口位置,距离电脑左上角200, ...
- k8s安装之etcd备份还原yaml
etcd备份还原方案,这种比较高级. 使用docker,自动化处理. 如果单节点备份,ETCD_ENDPOINTS一个即可. 如果多节点恢复,依次执行恢复脚本即可. apiVersion: batch ...
- 微信小程序~App.js中登录
(1)初始化项目中App.js登录代码 // 登录 wx.login({ success: res => { // 发送 res.code 到后台换取 openId, sessionKey, u ...
- 2019牛客多校第一场 A.Equivalent Prefixes
题目描述 Two arrays u and v each with m distinct elements are called equivalent if and only if RMQ(u,l,r ...