思路

  进程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()\r\n");
}
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);
          return i;
        }
    }

    return 0;
 }



void GetProcessName(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;    
    return STATUS_SUCCESS;
}

 

posted on 2018-01-31 00:06  CrisCzy  阅读(1950)  评论(0编辑  收藏  举报