驱动下通过进程PID获得进程名 (动态获取ImageFileName在EPROCESS结构体中的相对偏移)

摘要:
当需要加载时这个进程中会有一个线程将驱动程序加载到内核模式地址空间,并调用DriverEntry例程。此时调用PsGetCurrentProcess获得的是System进程的EPROCESS。当然也可以利用PsInitialSystemProcess获得System进程的EPROCESS,因为已知进程名,所以可以在EPROCESS中匹配到对应的字符串,返回此时偏移。获得进程名两种方法利用函数PsGetProcessImageFileName利用已经计算出来的偏移加上EPROCESS首地址得到ImageFileName成员。实测在WIN7X86X64下可用#pragmaonce#include#includeUCHAR*PsGetProcessImageFileName;VOIDDriverUnload{DbgPrint;}ULONGGetProcessNameOffset{PEPROCESScurproc;inti=0;curproc=PsGetCurrentProcess();for{if(!

思路

进程EPROCESS结构体中含有进程名ImageFileName(需求处ImageFileName在EPROCESS结构体中的相对偏移)——》获得进程EPROCESS——》通过进程句柄获得EPROCESS——》通过进程PID打开进程获得进程句柄

  • 计算ImageFileName在EPROCESS结构体中的相对偏移

方法一 来个判断操作系统,再利用windbg调试得到相应的偏移来对应
方法二 动态获取这些变量的偏移地址 GetProcessNameOffset

原理是DriverEntry和AddDEVICE例程运行在系统进程System中。当需要加载时这个进程中会有一个线程将驱动程序加载到内核模式地址空间,并调用DriverEntry例程。此时调用PsGetCurrentProcess获得的是System进程的EPROCESS。当然也可以利用PsInitialSystemProcess获得System进程的EPROCESS,因为已知进程名,所以可以在EPROCESS中匹配到对应的字符串,返回此时偏移。

获得进程名两种方法

  1. 利用函数PsGetProcessImageFileName
  2. 利用已经计算出来的偏移加上EPROCESS首地址得到ImageFileName成员。

实测在 WIN7 X86 X64下可用

#pragma once
#include<ntddk.h>#include<wdm.h>
UCHAR*PsGetProcessImageFileName(PEPROCESS Process);

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
    DbgPrint("DriverUnload()
");
}
ULONG   GetProcessNameOffset ( void)
{
    PEPROCESS curproc;
     int i = 0;
 
     curproc =PsGetCurrentProcess();
    for ( i = 0; i < 3 * PAGE_SIZE; i++) {
       if( !strncmp( "System", (PCHAR)curproc + i, strlen("System") )) {
           DbgPrint("offset:%d",i);
          returni;
        }
    }

    return 0;
 }



voidGetProcessName(ULONG dwPid)
{
        HANDLE ProcessHandle;
    NTSTATUS status;
    OBJECT_ATTRIBUTES  ObjectAttributes;
    CLIENT_ID myCid;
    PEPROCESS EProcess;
    int a=GetProcessNameOffset();
        InitializeObjectAttributes(&ObjectAttributes,0,0,0,0); 

    myCid.UniqueProcess =(HANDLE)dwPid;
    myCid.UniqueThread = 0;

    //打开进程,获取句柄
    status = ZwOpenProcess (&ProcessHandle,PROCESS_ALL_ACCESS,&ObjectAttributes,&myCid);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("error/n");
        return;
    }
    
    //得到EPROCESS,结构中取进程名
    status = ObReferenceObjectByHandle(ProcessHandle,FILE_READ_DATA,0,KernelMode,&EProcess, 0);
    if (status ==STATUS_SUCCESS)
    {
        char *ProcessName = (char*)EProcess +a;
        char *PsName =PsGetProcessImageFileName(EProcess);

        DbgPrint("ProcessName is %s",ProcessName);
        DbgPrint("PsName is %s/n",PsName);
        ObDereferenceObject(EProcess);
        ZwClose(ProcessHandle);
    }
    else{
        DbgPrint("Get ProcessName error");
        ObDereferenceObject(EProcess);
        ZwClose(ProcessHandle);
    }
}

NTSTATUS 
  DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING  RegistryPath
    )
{
    DbgPrint("sucess load/n");
    GetProcessName(2900);
    DriverObject->DriverUnload =DriverUnload;    
    returnSTATUS_SUCCESS;
}

免责声明:文章转载自《驱动下通过进程PID获得进程名 (动态获取ImageFileName在EPROCESS结构体中的相对偏移)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WPF附加属性数据库性能优化下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WCF NetTcpBinding 由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作

背景:WindowsService + WCF + NetTcpBinding 之前一直使用http协议模式,改为net.tcp之后隔段时间出现:由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。 127.0.0.1:9000 记录时间:2016-01-14 10:02:58日志级别:Exception 日志位置:CloudTraPlatSOA....

java第七天

p38~p41: 1、可以通过import 一个自定义类库(或者网上下的)在java中使用c风格的输入输出方式。 2、忘记优先顺序时应该用括号明确规定计算顺序。 3、java的操作符不同于c++,几乎只能操作“基本类型”,例外的是 ==、!=、=能操作所有对象,除此之外,String类支持“+”和“+=”。 4、System.out.print()语句中包...

C#-执行cmd命令,获取结果

using System; using System.Threading.Tasks; using System.Windows.Forms; namespace EFDemo { public partial class ExecCmd : Form { public ExecCmd() { Initi...

注册表比较工具

RegShot 是一种注册表比较工具,它通过两次抓取注册表而快速地比较出答案。它还可以将您的注册表以纯文本方式记录下来,便于浏览;还可以监察 Win.ini,System.ini 中的键值;还可以监察您 Windows 目录和 System 目录中文件的变化,为您手工卸载某些软件创造条件。 1.下载地址 https://sourceforge.net/pr...

17.异常(三)之 e.printStackTrace()介绍

一、关于printStackTrace()方法 public void printStackTrace()方法将此throwable对象的堆栈追踪输出至标准错误输出流,作为System.err的值。输出的第一行是此对象的toString()方法的结果,剩余行表示以前由方法 fillinStackTrace() 记录的数据。此信息的格式取决于实现,但以下示例...

c# 获取相对路径

c# 获取相对路径 一、获取当前文件的路径1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName获取模块的完整路径,包括文件名。2. System.Environment.CurrentDirectory获取和设置当前目录(该进程从中启动的目录)的完全限定目录。3. Sy...