通过GetProcessNameByProcessId得到进程路径

2023-05-16

写主防时,为了拿到进程路径,所以查询发现一种发现一种方式是通过PID,调用PsLookupProcessByProcessId(ProcessId, &ProcessObj)拿到进程的EPROCESS,然后PsGetProcessImageFileName(ProcessObj)拿到进程进程路径。

现在看下PsLookupProcessByProcessId资料

kd> u PsLookupProcessByProcessId l 20
  nt!PsLookupProcessByProcessId:
  805ca38a 8bff            mov     edi,edi
  805ca38c 55              push    ebp
  805ca38d 8bec            mov     ebp,esp
  805ca38f 53              push    ebx
  805ca390 56              push    esi
  805ca391 64a124010000    mov     eax,dword ptr fs:[00000124h]
  805ca397 ff7508          push    dword ptr [ebp+8]
  805ca39a 8bf0            mov     esi,eax
  805ca39c ff8ed4000000    dec     dword ptr [esi+0D4h]
  805ca3a2 ff3560b25580    push    dword ptr [nt!PspCidTable (8055b260)]
  805ca3a8 e84bb50300      call    nt!ExMapHandleToPointer (806058f8)

 PsLookupProcessByHandle首先使APC无效

CurrentThread = PsGetCurrentThread ();

KeEnterCriticalRegionThread (&CurrentThread->Tcb); 

然后调用了函数ExMapHandleToPointer函数,传入的参数就是PspCidTable系统句柄表的指针。

CidEntry = ExMapHandleToPointer(PspCidTable, ProcessId);
      if (CidEntry != NULL) {
          lProcess = (PEPROCESS)CidEntry->Object;
          if (lProcess->Pcb.Header.Type == ProcessObject &&
              lProcess->GrantedAccess != 0) {
              if (ObReferenceObjectSafe(lProcess)) {
                 *Process = lProcess;
                  Status = STATUS_SUCCESS;
              }
         }
 
         ExUnlockHandleTableEntry(PspCidTable, CidEntry);
     }

ExMapHandleToPointer函数调用了ExpLookupHandleTableEntry函数,但是在之前做了参数检查

LocalHandle.GenericHandleOverlay = Handle;  //会判断句柄的有效性
  
      HandleTableEntry = ExpLookupHandleTableEntry( HandleTable,
                                                    LocalHandle );
      if (HandleTableEntry == NULL) {
          return NULL;
     }

ExMapHandleToPointer调用ExpLookupHandleTableEntry所做的事情就是在句柄表的三层结构中找到对应的对象,返回HANDLE_TABLE_ENTRY结构,再返回之后就会调用ExpLockHandleTableEntry函数来锁定当前的HANDLE_TABLE_ENTRY

 HandleTableEntry = ExpLookupHandleTableEntry( HandleTable, LocalHandle ); 
 if (HandleTableEntry == NULL) { return NULL; }

在ExpLockHandleTableEntry中就会调用InterlockedCompareExchangePointer,如果不成功,则可能是进程句柄处于被调试状态,可以通过HandleTableEntry中的debugInfo来判断句柄是否处于调试状态

if ((HandleTableEntry == NULL) ||
          !ExpLockHandleTableEntry( HandleTable, HandleTableEntry)) {
          //
          // If we are debugging handle operations then save away the details
          //
  
          if (HandleTable->DebugInfo != NULL) {
              ExpUpdateDebugInfo(HandleTable, PsGetCurrentThread (), Handle, HANDLE_TRACE_DB_BADREF);
          }
         return NULL;
     }

 如果处于调试状态,则用ExpUpdateDebugInfo函数填充HANDLE_TRACE_DEBUG_INFO结构,保存调试信息,否则返回NULL,调用失败

  当函数调用成功就返回到PsLookupProcessByProcessId中,将HANDLE_TABLE_ENTRY中的Object转化成EPROCESS对象,确保这个对象是ProcessObject且有继承权,则引用计数加1

CidEntry = ExMapHandleToPointer(PspCidTable, ThreadId);
      Status = STATUS_INVALID_PARAMETER;
      if (CidEntry != NULL) {
          lThread = (PETHREAD)CidEntry->Object;
          if (lThread != (PETHREAD)PSP_INVALID_ID && lThread->Tcb.Header.Type == ThreadObject && lThread->GrantedAccess ) {
  
              ObReferenceObject(lThread);
              *Thread = lThread;
              Status = STATUS_SUCCESS;
         }
 
         ExUnlockHandleTableEntry(PspCidTable, CidEntry);
     }

然后装入参数EPROCESS,解锁当前的handle table entry,恢复当前内核线程的APC,成功返回。

PCHAR GetProcessNameByProcessId(HANDLE ProcessId)
{
	NTSTATUS st=STATUS_UNSUCCESSFUL;
	PEPROCESS ProcessObj=NULL;
	PCHAR string=NULL;
	st = PsLookupProcessByProcessId(ProcessId, &ProcessObj);
	if(NT_SUCCESS(st))
	{
		string = PsGetProcessImageFileName(ProcessObj);
		ObfDereferenceObject(ProcessObj);
	}
	return string;
}

然后如上调用PsGetProcessImageFileName,得到进程路径。

参考资料

https://www.cnblogs.com/aliflycoris/p/5271417.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过GetProcessNameByProcessId得到进程路径 的相关文章

随机推荐

  • Github for windows 使用教程(二)

    转载请注明出处 GitHub for windows使用教程 xff08 二 xff09 分支的使用 创建分支 我们创建第一个分支取名为 new masterh 点击Create new branch创建第一个分支 我们发现此时的分支已经切
  • 「leetcode」C++题解:239. 滑动窗口最大值,单调队列的经典题目

    更多精彩文章持续更新 xff0c 微信搜索 代码随想录 第一时间围观 xff0c 本文https github com youngyangyang04 TechCPP 已经收录 xff0c 里面有更多干货等着你 xff0c 欢迎Star x
  • BAT程序员总结的力扣刷题指南,已经在Github了!!刷题顺序,优质题解一网打尽!

    相信很多小伙伴刷题的时候面对力扣上近两千道题目 xff0c 感觉无从下手 xff01 我花费半年时间整理了Github学习项目 力扣刷题攻略 xff1a https github com youngyangyang04 leetcode m
  • 扩展卡尔曼滤波EKF与多传感器融合

    Extended Kalman Filter xff08 扩展卡尔曼滤波 xff09 是卡尔曼滤波的非线性版本 在状态转移方程确定的情况下 xff0c EKF已经成为了非线性系统状态估计的事实标准 本文将简要介绍EKF xff0c 并介绍其
  • 我把年终总结写成了年度回忆录(1)

    写在前面 这大概是我第一次正儿八经的写个年终总结 xff0c 其实 xff0c 更像是一篇很有意思的回忆录 去年元旦的情景我已经记不起来了 但这一年里 xff0c 却是有很多事情让我难以忘记 从去年寒假自己在出租屋里苦学的时光 xff0c
  • .mat文件后缀名消失

    情况说明 xff1a 下载了 mat文件后 xff0c 打开文件发现文件的后缀名缺失了 xff0c 并且文件类型变为Microsoft Access Table Shortcut类型 具体原因 xff1a 这是由于MATLAB和Access
  • lsusb命令

    在 Linux 中我们可以使用 lsusb 来列出 USB 设备和它的属性 xff0c lsusb 会显示驱动和内部连接到你系统的设备 直接在控制台输入 lsusb 即可 如果无法运行 lsusb xff0c 使用以下命令安装 xff08
  • 现代控制理论基础——卡尔曼滤波(kalman filtering)

    现代控制理论基础 卡尔曼滤波 xff08 kalman filtering xff09 什么是卡尔曼滤波 xff1f 在任何含有不确定信息的动态系统中使用卡尔曼滤波 xff0c 对系统下一步的走向做出有根据的预测 xff0c 对系统状态进行
  • C/C++中的'\0'

    在C C 43 43 语言中 xff0c 字符是按其所对应的ASCII码来存储的 xff0c 一个字符占一个字节 xff0c 而 0 就是ASCII码表中的第一个字符 xff0c ASCII码为00000000 xff0c 它被称为空字符
  • OpenCV 创建图像时,CV_8UC1,CV_32FC3,CV_32S等参数的含义

    形式 xff1a CV lt bit depth gt S U F C lt number of channels gt bit depth xff1a 比特数 代表8bite 16bites 32bites 64bites 举个例子吧 比
  • 解决apt-get update更新错误

    sudo apt get update出现解析错误 xff0c 如下 fkuner 64 data3 span class token function sudo span span class token function apt get
  • C++初阶:vector类

    vector 0 vector的介绍 vector是用数组实现的 可变长度的顺序容器 xff0c 本质是一种类模板 span class token keyword template span span class token operat
  • Git之分支创建策略

    分支类型 git上始终保持两个分支 xff0c master分支 develop分支 master分支主要用于发布时使用 xff0c 而develop分支主要用于开发使用 除了以上两个常驻分支外 xff0c 我们还可以适当分支出三种分支 x
  • ubuntu 设置pip源

    前言 在Ubuntu下我们一般使用pip工具去管理我们的Python包 但是在使用pip命令操作的时候一般都是使用的默认设置 xff0c 使用的是国外的镜像 xff0c 这就导致了我们在国内下载安装包的时候很慢 xff08 乌龟慢慢爬 xf
  • 27.串口通信实验源码讲解

    串口通信实验源码讲解 笔记基于正点原子官方视频 视频连接https www bilibili com video BV1Wx411d7wT p 61 71 amp spm id from 61 333 1007 top right bar
  • 国内快速下载keil的pack文件包

    问题 xff1a 国内keil官网下载pack文件包太慢 xff0c 网上很多网盘资源如果没有VIP也是很慢 解决方案 xff1a https www keil com dd2 pack 第一步 xff1a 首先去上面的keil官网找自己需
  • forensics - make virtual machine with E01[ewf] files on OSX ———— 电子取证 MAC OS平台仿真

    forensics make virtual machine with E01 ewf files on OSX 电子取证 MAC OS平台仿真1挂载库安装osxfuselibewf 2 虚拟机存储文件qemu 3 开始实验 amp amp
  • 如何从官网下载 Google Chrome 离线安装包

    Google Chrome 已经是许多人的默认浏览器 xff0c 但由于 你懂的 原因 xff0c 在线安装基本没有成功过 xff0c 他自己的自动更新也多数一直在加载中 xff0c 所以我们会到一些下载站下载安装包 xff0c 但我的多次
  • 腾讯资深3D游戏建模师你不知道的5个3DMAX细节

    首先我们要清楚的是行业划分 3DMAX的用途非常广泛 xff0c 所涉及的行业大致有 xff0c 园林景观 城市规划 建筑设计 室内设计 动漫设计 商业动画制作等 所以我们在入手学3DMAX软件时 xff0c 大家应该分清楚 xff0c 你
  • 通过GetProcessNameByProcessId得到进程路径

    写主防时 xff0c 为了拿到进程路径 xff0c 所以查询发现一种发现一种方式是通过PID xff0c 调用PsLookupProcessByProcessId ProcessId amp ProcessObj 拿到进程的EPROCESS