一丶简介

我们遇到的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. 基于MBT的自动化测试工具——GraphWalker介绍和实际使用

    GraphWalker是一个开源的基于模型的自动化测试工具,它可以用来通过图形测试模型来自动生成测试用例. 本文主要描述了使用yed画出FSM, EFSM模型图(常见的流程图),然后使用GraphWa ...

  2. Mysql之锁的基本介绍

    数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则.对于任何一种数据库来说都需要有相应的锁定机制,所以MySQL自然也不能例外.MySQL数据 ...

  3. WPF 不要给 Window 类设置变换矩阵(分析篇):System.InvalidOperationException: 转换不可逆。

    原文:WPF 不要给 Window 类设置变换矩阵(分析篇):System.InvalidOperationException: 转换不可逆. 最近总是收到一个异常 "System.Inva ...

  4. JS函数的三种方式

    函数,一段能够自动完成某些功能的代码块,函数的出现,既解决了重复使用重一功能的需求,又可以避免代码的臃肿性. 使用函数有两个要求:必须调用后才可以执行;函数名不要和关键字以及系统函数相同; 函数主要有 ...

  5. Java 之 函数式接口

    函数式接口 一.概念 函数式接口在 java 中是指:有且仅有一个抽象方法的接口. 函数式接口,即适用于函数式编程场景的接口. 而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用 ...

  6. net webapi jwt验证授权

    参考文章:https://blog.csdn.net/liwan09/article/details/83820651

  7. c# Directory类的常用方法

  8. c# IComparable与IComparer接口

  9. js中绑定事件处理函数,使用event以及传递额外数据

    IE8中使用attachEvent绑定事件处理函数时,不能直接向event 对象添加数据属性.可以用属性复制的方法,包装新的event对象. 1. 属性复制var ObjectExtend = fun ...

  10. keras模块学习之model层【重点学习】

    本笔记由博客园-圆柱模板 博主整理笔记发布,转载需注明,谢谢合作! model层是keras模块最重要的一个层,所以单独做下笔记,这块比较难理解,本博主自己还在学习这块,还在迷糊中. model的方法 ...