内核中通过进程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 ...
随机推荐
- 14-2 SQL语言简介
1.结构化查询语言(Structured Query Language,SQL),常被读作sequel,最初是由Microsoft.Sybase和Ashton-Tate这3家公司共同开发的. 2.Wi ...
- Git命令和使用
Git & GitHub Git是一个工具,用于命令行操作 GitHub是一个协同工作平台 包括: Remote original Repository - 远程主仓库(上线唯一仓库) Rem ...
- C++ | 使用const std::map,map::[]时遇到的一个bug
原函数简化后如下: void fun(const map<int,vector<int>> &mp, int index) { for (auto tmp : mp[i ...
- iOS 播放系统自带铃声
播放声音代码例子 https://github.com/baitongtong/git-.git 给一个国外网址,苹果系统铃声以及自定义铃声免登陆免费下载:http://www.zedge.net/r ...
- elementui switch 开关,点击确认按钮后在进行开关
<el-table-column label="上头条" align="center"> <template slot-scope=" ...
- H5打开app指定页面(H5+app项目)
H5+app项目,在HBuilderX中设置 详情参考官方 https://ask.dcloud.net.cn/article/64 给h5+app设置scheme值,作用:在其它app和h5页面中启 ...
- Eclipse - servlet显示无法导入javax.servlet包问题的解决方案
项目名-->右键 Property-->选择 Java Build Path-->选择 Add External JARs-->选择 把servlet-api.jar的路径输入 ...
- 离线安装zabbix文档
为了离线安装需要离线安装包,可以通过这个方式获取. 用yum安装软件默认不保存软件包,要保存需修改配置文件 # vi /etc/yum.conf 将keepcache的值改为1 安装版本:rel ...
- IOS模拟器调试ANE
来源:http://www.tuicool.com/articles/AFRJzi 利用iOS模拟器来检测和调试AIR应用程序补充篇 Air3.4来了 除去可以直接往模拟器里面部署应用,还可以往真机里 ...
- ArcEngine二次开发中运行出现There is no Spatial Analyst license currently available or enabled.
只需要在许可控件上勾选空间分析功能即可.