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 ...
随机推荐
- NX二次开发-调系统命令UF_load_library[UFUN调DLL]
此函数可以调DLL,可以调宏,当然也可以调其他内部函数(知道哪个内部函数怎么用的前提下). #include <uf.h> void UFUN_API_Call_DLL(char* dll ...
- ionic-CSS:ionic icon(图标)
ylbtech-ionic-CSS:ionic icon(图标) 1.返回顶部 1. ionic icon(图标) ionic 也默认提供了许多的图标,大概有 700 多个,针对 Android 和 ...
- c++11新特性学习2
noexcept 替代 throw.优点是更安全, 如果noexcept 修饰的函数抛出了异常,编辑器可以直接选择终止程序. C++ 11中析构函数默认为noexcept(true),从而阻止异常的扩 ...
- jsp-application应用
application有两种应用,1是当作map,代码如下 <body> <%! int i=1; %> <% application.setAttribute(&quo ...
- 【POJ】1860 Currency Exchange
真是气skr人..没把d[]换成double...de了一上午的bug// 记得用G++提交啊 题目链接:http://poj.org/problem?id=1860 题意:告诉你n个点,m条路.起始 ...
- POJ1149_PIGS(网络流/EK)
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 15721 Accepted: 7021 Description ...
- Spring MVC @PathVariable注解(3)
下面用代码来演示@PathVariable传参方式 1 @RequestMapping("/user/{id}") 2 public String test(@PathVariab ...
- matlab 求已知概率密度函数的随机数生成
N=10000; %需要随机数的个数 a=zeros(N,1); %存放随机数的数列 n=0; f1=@(t) 1./(1.2*pi*(1+5*(t-7.3).^2)); f2=@(t) 1./(1. ...
- The linux command 之网络
一.检查和检测网络 ping命令——向网络主机发送特殊数据包 [me@linuxbox ~]$ ping www.baidu.com 按Ctrl+C终止程序 tracepath——跟踪网络数据包的传输 ...
- Android开发 retrofit入门讲解 (RxJava模式)
前言 retrofit除了正常使用以外,还支持RxJava的模式来使用,此篇博客讲解如何使用RxJava模式下的retrofit 依赖 implementation 'com.squareup.ret ...