思路
进程EPROCESS结构体中含有进程名ImageFileName(需求处ImageFileName在EPROCESS结构体中的相对偏移)——》获得进程EPROCESS——》通过进程句柄获得EPROCESS——》通过进程PID打开进程获得进程句柄
- 计算ImageFileName在EPROCESS结构体中的相对偏移
方法一 来个判断操作系统,再利用windbg调试得到相应的偏移来对应
方法二 动态获取这些变量的偏移地址 GetProcessNameOffset
原理是 DriverEntry和AddDEVICE例程运行在系统进程System中。当需要加载时这个进程中会有一个线程将驱动程序加载到内核模式地址空间,并调用DriverEntry例程。此时调用PsGetCurrentProcess获得的是System进程的EPROCESS。当然也可以利用PsInitialSystemProcess获得System进程的EPROCESS,因为已知进程名,所以可以在EPROCESS中匹配到对应的字符串,返回此时偏移。
获得进程名两种方法
- 利用函数PsGetProcessImageFileName
- 利用已经计算出来的偏移加上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; }