windows 内核下获取进程路径
windows 内核下获取进程路径
思路:
1):在EPROCESS结构中获取。
此时要用到一个导出函数:PsGetProcessImageFileName,申明如下:
NTSYSAPI
UCHAR *
PsGetProcessImageFileName(
__in PEPROCESS Process
);
此函数获取的是一个简单的进程名,并不是绝对路径。
2):ZwQueryInformationProcess。
要想获取进程的绝对路径,可用一个未公开的函数:ZwQueryInformationProcess。MSDN上说win8以后此函数不支持了,但笔者在win7,win8
的x86,x64都试过了,都可以正常使用。笔者一般使用的时候用MmGetSystenRoutineAddress来找此函数的地址,找到后查找ProcessImageFileName(27号功能)信息,就可以得到UNICODE_STRING
类型的绝对进程路径,但此绝对路径并不是我我们在应用层看到的类似"C:\windows\abc.exe"这样的路径,而是这样的表示方法"\Device\harddiskvolume1\windows\abc.exe".
3):从FILE_OBJECT中获取
如果得到FILE_OBJECT的话可以从FILE_OBJECT中获取。
typedef struct _FILE_OBJECT {
CSHORT Type;
CSHORT Size;
PDEVICE_OBJECT DeviceObject;
PVPB Vpb;
PVOID FsContext;
PVOID FsContext2;
PSECTION_OBJECT_POINTERS SectionObjectPointer;
PVOID PrivateCacheMap;
NTSTATUS FinalStatus;
struct _FILE_OBJECT *RelatedFileObject;
BOOLEAN LockOperation;
BOOLEAN DeletePending;
BOOLEAN ReadAccess;
BOOLEAN WriteAccess;
BOOLEAN DeleteAccess;
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
BOOLEAN SharedDelete;
ULONG Flags;
UNICODE_STRING FileName;
LARGE_INTEGER CurrentByteOffset;
__volatile ULONG Waiters;
__volatile ULONG Busy;
PVOID LastLock;
KEVENT Lock;
KEVENT Event;
__volatile PIO_COMPLETION_CONTEXT CompletionContext;
KSPIN_LOCK IrpListLock;
LIST_ENTRY IrpList;
__volatile PVOID FileObjectExtension;
} FILE_OBJECT, *PFILE_OBJECT;
FILE_OBJECT中两个重要的成员:FileName中含有除驱动器外的路径,比如是这样的"\WINDOWS\system32\notepad.exe"
此时再用另外一个函数IoVolumeDeviceToDosName,就可以将传入的DeviceObject转化为驱动器路径。
NTSTATUS IoVolumeDeviceToDosName(
_In_ PVOID VolumeDeviceObject,
_Out_ PUNICODE_STRING DosName
);
将DosName和FileName拼接起来就可以得到绝对路径"C:|windows\system32\notepad.exe".
最后用完后记得要把DosName的Buffer空间释放掉。
MSDN如是说:
IoVolumeDeviceToDosName allocates the string buffer pointed to by the Buffer member of the UNICODE_STRING structure that the DosName parameter points to. After this buffer is no longer required, a caller of this routine should call the ExFreePool routine to free the buffer.
Starting with Windows Vista, you must ensure that APCs are not disabled before calling this routine. The KeAreAllApcsDisabled routine can be used to verify that APCs are not disabled
下面说几个常见的类型转换函数:
ObReferenceObjectByHandle
此函数可以将句柄转化成内核对应的结构,例如:
进程句柄(HANDLE)------>进程活动链指针(PEPROCESS)
文件句柄(HANDLE)------>文件对象指针(PFILE_OBJECT)
懒的说了,还是看图吧,一图胜千言:

PsGetProcessId
根据EPROCESS指针获取进程ID
最后贴一段练习的代码片段:
VOID GetProcPath(
IN PRECORD_LIST pRecord,
IN PHANDLE pHandle
)
{
NTSTATUS status = STATUS_SUCCESS;
PUNICODE_STRING pUniImage = NULL;
ULONG ulImageLen; UNICODE_STRING uniFunName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess");
if (NULL == ZwQueryInformationProcess)
{
__try
{
ZwQueryInformationProcess = (PFUN_ZwQueryInformationProcess)MmGetSystemRoutineAddress(&uniFunName);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("exception occured.\n"));
} if (NULL == ZwQueryInformationProcess)
{
KdPrint(("MmGetSystemRoutineAddress failed .\n"));
return;
}
} status = ZwQueryInformationProcess(*pHandle, ProcessImageFileName, pUniImage, 0, &ulImageLen);
if (STATUS_INFO_LENGTH_MISMATCH != status)
{
KdPrint(("ZwQueryInformationProcess error code:(%x).\n", status));
return;
}
pUniImage = ExAllocatePoolWithTag(NonPagedPool, ulImageLen, MEMTAG);
if (NULL == pUniImage)
{
KdPrint((" no enough resources .\n"));
return;
}
status = ZwQueryInformationProcess(*pHandle, ProcessImageFileName, pUniImage, ulImageLen, &ulImageLen);
if (!NT_SUCCESS(status))
{
KdPrint(("ZwQueryInformationProcess error code:(%x).\n", status));
ExFreePool(pUniImage);
return;
}
KdPrint(("ParentProcPath:(%wZ).\n", pUniImage));
ExFreePool(pUniImage);
} NTSTATUS GetProcessIdByHandle(
IN const PHANDLE pHandle,
IN PULONG pPid)
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pEprocess = NULL; status = ObReferenceObjectByHandle(*pHandle, 0, *PsProcessType, KernelMode, &pEprocess, NULL);
if (!NT_SUCCESS(status))
{
KdPrint((" error code:(%08x) \n", status));
return status;
} *pPid = (ULONG)PsGetProcessId(pEprocess);
ObDereferenceObject(pEprocess); return status;
}
windows 内核下获取进程路径的更多相关文章
- 写一个Windows上的守护进程(8)获取进程路径
写一个Windows上的守护进程(8)获取进程路径 要想守护某个进程,就先得知道这个进程在不在.我们假设要守护的进程只会存在一个实例(这也是绝大部分情形). 我是遍历系统上的所有进程,然后判断他们的路 ...
- CMD魔法堂:获取进程路径和PID值的方法集
一.前言 在开发发布更更新工具——更新Weblogic应用模块时,了解到更新Weblogic应用需要先关闭Weblogic应用窗口然后是清缓存.更新应用文件,最后再重启Weblogic应用窗口. ...
- windows内核代码之进程操作
[toc] 一丶简介 整理一下windows内核中.常用的代码.这里只整理下进程的相关代码. 二丶 windows内核之遍历进程 内核中记录进程的结构体是EPROCESS结构.所以只需要遍历这个结构即 ...
- 通过PID获取进程路径的几种方法
通过PID获取进程路径的几种方法 想获得进程可执行文件的路径最常用的方法是通过GetModuleFileNameEx函数获得可执行文件的模块路径这个函数从Windows NT 4.0开始到现在的Vis ...
- Windows内核下操作字符串!
* Windows内核下操作字符串! */ #include <ntddk.h> #include <ntstrsafe.h> #define BUFFER_SIZE 1024 ...
- Delphi 获取进程路径及命令行参数
Delphi 获取进程路径及命令行参数, 但有的进程获取时会报错,不知为啥 type PVOID64 = UINT64; _UNICODE_STRING = packed record Length ...
- [5]windows内核情景分析---进程线程
本篇主要讲述进程的启动过程.线程的调度与切换.进程挂靠 进程的启动过程: BOOL CreateProcess ( LPCTSTR lpApplicationName, ...
- WAS下获取包路径下所有类
最近做javaweb项目的混淆工作,用到proguard,该工具混淆.jar文件比较方便,故把所有项目代码和配置文件打成jar包, 生成的jar包经过proguard处理后,再次打包(解决progua ...
- linux下查看进程路径
在linux下查看进程大家都会想到用 ps -ef|grep XXX可是看到的不是全路径,怎么看全路径呢?每个进程启动之后在 /proc下面有一个于pid对应的路径例如:ps -ef|grep pyt ...
随机推荐
- Centos7.5安装mysql 8.0.11
一.安装前准备 安装采用二进制包方式,软件包8.0.11版本下载地址: https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-linux-gl ...
- CodeForces1249B1/B2-Books Exchange-dfs-一般搜索+记忆化搜索
一般搜索 注意:一般定义成void Books Exchange (easy version) CodeForces - 1249B2 The only difference between eas ...
- 转:CSS盒模型
W3C 组织建议把所有网页上的对像都放在一个盒(box)中,设计师可以通过创建定义来控制这个盒的属性,这些对像包括段落.列表.标题.图片以及层.盒模型主 要定义四个区域:内容(content).边框距 ...
- 码云的使用以及pycharm
码云的使用 下载Git一路next 在码云上新建仓库 建立码云仓库 右键 git bash hero 依次输入 git config --global user.name "用户名&qu ...
- 01、requests 基本使用
requests模块的基本使用 基于网络请求的模块. 环境的安装:pip install requests 作用:模拟浏览器发起请求 分析requests的编码流程: 1.指定url 2.发起了请求 ...
- ThreadPoolTaskExecutor的配置使用
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ft305977550/article/de ...
- js中不同类型作比较
示例: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <met ...
- 关于RSA加密和签名的区别与联系
发现网上对于RSA加密和签名的介绍普遍偏向于使用和概念的说明,今天想说一点不一样的.对于加解密和签名的使用及概念就不再说了,不知道的请自行百度. 签名的本质其实就是加密,但是由于签名无需还原成明文,因 ...
- php多维数组排序方案。按照姓名 首字符 等排序
//定义一个学生数组 $students = array( 256=>array('name'=>'jon','grade'=>98.5), 2=>arra ...
- arc098D Xor Sum 2
题意:给你一个数列,问有多少对(l,r)满足A[l]+A[l+1]+...+A[r]=A[l]^A[l+1]^...^A[r]? 标程: #include<bits/stdc++.h> u ...