-
-
[旧帖] [原创]驱动中获得完整进程路径名 0.00雪花
-
发表于: 2013-8-29 13:45 3105
-
调用GetEPROCESSPath函数即可获得完整路径名,需提供Eprocess参数,Eprocess参数可通过PsLookupProcessByProcessId传入进程ID获得。
其中MmGetFileObjectForSection函数找文件对象,各个操作系统版本结构体不同。此代码为2003 x64版本,其它版本需从windbg中获得相关结构体。
//.c
PFILE_OBJECT
NTAPI
MmGetFileObjectForSection(IN PVOID SectionObject) //函数内加入LOCK_PFN
{
PSECTION_OBJECT_2003X64 pSectionObj_2003X64 = SectionObject;
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
ASSERT(SectionObject != NULL);
if(!SectionObject || !MmIsAddressValid(SectionObject))
return NULL;
//x64都是PAE模式,无需区分
if(pSectionObj_2003X64->Segment && MmIsAddressValid(pSectionObj_2003X64->Segment)
&& pSectionObj_2003X64->Segment->ControlArea
&& MmIsAddressValid(pSectionObj_2003X64->Segment->ControlArea)
&& pSectionObj_2003X64->Segment->ControlArea->FilePointer
&& MmIsAddressValid(pSectionObj_2003X64->Segment->ControlArea->FilePointer))
return pSectionObj_2003X64->Segment->ControlArea->FilePointer;
return NULL;
}
VOID GetFullPathByFileObject(PFILE_OBJECT FileObject, PCHAR ProcessImageName)
{
UNICODE_STRING FilePath;
UNICODE_STRING DosName;
STRING AnsiString;
FilePath.Buffer = NULL;
FilePath.Length = 0;
*ProcessImageName = 0;
FilePath.Buffer = ExAllocatePool(PagedPool,0x200);
FilePath.MaximumLength = 0x200;
//KdPrint(("[GetProcessFileName] FilePointer :%wZ\n",&FilePointer->FileName));
ObReferenceObjectByPointer((PVOID)FileObject,0,NULL,KernelMode);//引用计数+1,操作对象
RtlVolumeDeviceToDosName(FileObject->DeviceObject, &DosName);
RtlCopyUnicodeString(&FilePath, &DosName);
RtlAppendUnicodeStringToString(&FilePath, &FileObject->FileName);
ObDereferenceObject(FileObject);
RtlUnicodeStringToAnsiString(&AnsiString, &FilePath, TRUE);
if ( AnsiString.Length >= 216 )
{
memcpy(ProcessImageName, AnsiString.Buffer, 0x100u);
*(ProcessImageName + 215) = 0;
}
else
{
memcpy(ProcessImageName, AnsiString.Buffer, AnsiString.Length);
ProcessImageName[AnsiString.Length] = 0;
}
RtlFreeAnsiString(&AnsiString);
ExFreePool(DosName.Buffer);
ExFreePool(FilePath.Buffer);
}
PFILE_OBJECT GetEPROCESSPath(PEPROCESS pEprocess,CHAR szPath[_MAX_PATH])
{
PVOID pSectionObj = NULL;
PFILE_OBJECT pFileObj=NULL;
if (!pEprocess ||
!MmIsAddressValid((SIZE_T*)((UCHAR*)pEprocess+ SECTION_OBJ_PTR_OFFSET)))
return NULL;
pSectionObj = (PVOID)(*(SIZE_T*)((UCHAR*)pEprocess+ SECTION_OBJ_PTR_OFFSET));
if(!pSectionObj)
return NULL;
pFileObj = MmGetFileObjectForSection(pSectionObj);
if(pFileObj)
GetFullPathByFileObject(pFileObj,&szPath[0]);
return pFileObj;
}
//.h
#ifndef __DECLARE_H__ //防止重复包含头文件
#define __DECLARE_H__
typedef struct _EVENT_COUNTER
{
SINGLE_LIST_ENTRY ListEntry;
ULONG RefCount;
KEVENT Event;
}EVENT_COUNTER,*PEVENT_COUNTER;
typedef struct _CONTROL_AREA_2003X64
{
struct SEGMENT_2003X64 *Segment;
LIST_ENTRY DereferenceList;
ULONG NumberOfSectionReferences;
ULONG NumberOfPfnReferences;
ULONG NumberOfMappedViews;
ULONG NumberOfSystemCacheViews;
ULONG NumberOfUserReferences;
union
{
ULONG UnnamedTag;
} u;
FILE_OBJECT *FilePointer;
EVENT_COUNTER *WaitingForDeletion;
USHORT ModifiedWriteCount;
USHORT FlushInProgressCount;
ULONG WritableUserReferences;
} CONTROL_AREA_2003X64, *PCONTROL_AREA_2003X64;
#define PTE_PER_PAGE_BITS 10 // This handles the case where the page is full
typedef struct _MMPTE_SOFTWARE_X64 {
ULONGLONG Valid : 1;
ULONGLONG PageFileLow : 4;
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1;
ULONGLONG Transition : 1;
ULONGLONG UsedPageTableEntries : PTE_PER_PAGE_BITS;
ULONGLONG Reserved : 20 - PTE_PER_PAGE_BITS;
ULONGLONG PageFileHigh : 32;
} MMPTE_SOFTWARE_X64,*PMMPTE_SOFTWARE_X64;
typedef struct _MMPTE_PROTOTYPE_X64 {
ULONGLONG Valid : 1;
ULONGLONG Unused0: 7;
ULONGLONG ReadOnly : 1;
ULONGLONG Unused1: 1;
ULONGLONG Prototype : 1;
ULONGLONG Protection : 5;
LONGLONG ProtoAddress: 48;
} MMPTE_PROTOTYPE_X64,*PMMPTE_PROTOTYPE_X64;
typedef struct _PAE_MMPTE_TRANSITION
{
ULONGLONG Valid : 1; //Pos 0, 1 Bit
ULONGLONG Write : 1; //Pos 1, 1 Bit
ULONGLONG Owner : 1; //Pos 2, 1 Bit
ULONGLONG WriteThrough : 1; //Pos 3, 1 Bit
ULONGLONG CacheDisable : 1; //Pos 4, 1 Bit
ULONGLONG Protection : 5; //Pos 5, 5 Bits
ULONGLONG Prototype : 1; //Pos 10, 1 Bit
ULONGLONG Transition : 1; //Pos 11, 1 Bit
ULONGLONG PageFrameNumber : 26; //Pos 12, 26 Bits
ULONGLONG Unused : 26; //Pos 38, 26 Bits
}PAE_MMPTE_TRANSITION,*PPAE_MMPTE_TRANSITION;
#define _HARDWARE_PTE_WORKING_SET_BITS 11
typedef struct _MMPTE_HARDWARE_X64 {
ULONGLONG Valid : 1;
#if defined(NT_UP)
ULONGLONG Write : 1; // UP version
#else
ULONGLONG Writable : 1; // changed for MP version
#endif
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Accessed : 1;
ULONGLONG Dirty : 1;
ULONGLONG LargePage : 1;
ULONGLONG Global : 1;
ULONGLONG CopyOnWrite : 1; // software field
ULONGLONG Prototype : 1; // software field
#if defined(NT_UP)
ULONGLONG reserved0 : 1; // software field
#else
ULONGLONG Write : 1; // software field - MP change
#endif
ULONGLONG PageFrameNumber : 28;
ULONG64 reserved1 : 24 - (_HARDWARE_PTE_WORKING_SET_BITS+1);
ULONGLONG SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS;
ULONG64 NoExecute : 1;
} MMPTE_HARDWARE_X64, *PMMPTE_HARDWARE_X64;
typedef struct _MMPTE_HARDWARE_LARGEPAGE_X64 {
ULONGLONG Valid : 1;
ULONGLONG Write : 1;
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Accessed : 1;
ULONGLONG Dirty : 1;
ULONGLONG LargePage : 1;
ULONGLONG Global : 1;
ULONGLONG CopyOnWrite : 1; // software field
ULONGLONG Prototype : 1; // software field
ULONGLONG reserved0 : 1; // software field
ULONGLONG PAT : 1;
ULONGLONG reserved1 : 8; // software field
ULONGLONG PageFrameNumber : 19;
ULONGLONG reserved2 : 24; // software field
} MMPTE_HARDWARE_LARGEPAGE_X64, *PMMPTE_HARDWARE_LARGEPAGE_X64;
typedef struct _HARDWARE_PTE_X64 {
ULONG64 Valid : 1;
ULONG64 Write : 1; // UP version
ULONG64 Owner : 1;
ULONG64 WriteThrough : 1;
ULONG64 CacheDisable : 1;
ULONG64 Accessed : 1;
ULONG64 Dirty : 1;
ULONG64 LargePage : 1;
ULONG64 Global : 1;
ULONG64 CopyOnWrite : 1; // software field
ULONG64 Prototype : 1; // software field
ULONG64 reserved0 : 1; // software field
ULONG64 PageFrameNumber : 28;
ULONG64 reserved1 : 24 - (_HARDWARE_PTE_WORKING_SET_BITS+1);
ULONG64 SoftwareWsIndex : _HARDWARE_PTE_WORKING_SET_BITS;
ULONG64 NoExecute : 1;
} HARDWARE_PTE_X64, *PHARDWARE_PTE_X64;
typedef struct _MMPTE_TRANSITION_X64
{
ULONGLONG Valid : 1;
ULONGLONG Write : 1;
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1;
ULONGLONG Transition : 1;
ULONGLONG PageFrameNumber : 28;
ULONGLONG Unused : 24;
} MMPTE_TRANSITION_X64,*PMMPTE_TRANSITION_X64;
typedef struct _MMPTE_SUBSECTION_X64 {
ULONGLONG Valid : 1;
ULONGLONG Unused0 : 4;
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1;
ULONGLONG Unused1 : 5;
LONGLONG SubsectionAddress : 48;
} MMPTE_SUBSECTION_X64,*PMMPTE_SUBSECTION_X64;
typedef struct _MMPTE_LIST_X64 {
ULONGLONG Valid : 1;
ULONGLONG OneEntry : 1;
ULONGLONG filler0 : 3;
//
// Note the Prototype bit must not be used for lists like freed nonpaged
// pool because lookaside pops can legitimately reference bogus addresses
// (since the pop is unsynchronized) and the fault handler must be able to
// distinguish lists from protos so a retry status can be returned (vs a
// fatal bugcheck).
//
// The same caveat applies to both the Transition and the Protection
// fields as they are similarly examined in the fault handler and would
// be misinterpreted if ever nonzero in the freed nonpaged pool chains.
//
ULONGLONG Protection : 5;
ULONGLONG Prototype : 1; // MUST BE ZERO as per above comment.
ULONGLONG Transition : 1;
ULONGLONG filler1 : 20;
ULONGLONG NextEntry : 32;
} MMPTE_LIST_X64,*PMMPTE_LIST_X64;
typedef struct _MMPTE_X64 {
union
{
ULONG_PTR Long;
MMPTE_HARDWARE_X64 Hard;
MMPTE_HARDWARE_LARGEPAGE_X64 HardLarge;
HARDWARE_PTE_X64 Flush;
MMPTE_PROTOTYPE_X64 Proto;
MMPTE_SOFTWARE_X64 Soft;
MMPTE_TRANSITION_X64 Trans;
MMPTE_SUBSECTION_X64 Subsect;
MMPTE_LIST_X64 List;
} u;
} MMPTE_X64,*PMMPTE_X64;
typedef struct _MMEXTEND_INFO
{
ULONGLONG CommittedSize;
ULONG ReferenceCount;
}MMEXTEND_INFO,*PMMEXTEND_INFO;
typedef struct _SEGMENT_FLAGS
{
ULONG TotalNumberOfPtes4132: 10;
ULONG ExtraSharedWowSubsections: 1;
ULONG LargePages: 1;
ULONG WatchProto: 1;
ULONG DebugSymbolsLoaded: 1;
ULONG WriteCombined: 1;
ULONG NoCache: 1;
ULONG FloppyMedia: 1;
ULONG DefaultProtectionMask: 5;
ULONG ContainsPxeSubsection: 1;
ULONG Spare: 9;
} SEGMENT_FLAGS, *PSEGMENT_FLAGS;
typedef struct _SEGMENT_2003X64
{
struct _CONTROL_AREA_2003X64* ControlArea;
ULONG TotalNumberOfPtes;
ULONG NonExtendedPtes;
ULONG Spare0;
ULONGLONG SizeOfSegment;
MMPTE_X64 SegmentPteTemplate;
ULONGLONG NumberOfCommittedPages;
struct _MMEXTEND_INFO* ExtendInfo;
SEGMENT_FLAGS SegmentFlags;
ULONGLONG BaseAddress;
ULONGLONG u1;
ULONGLONG u2;
struct _MMPTE_X64* PrototypePte;
MMPTE_X64 ThePtes[0x1];
} SEGMENT_2003X64, *PSEGMENT_2003X64;
typedef struct _SECTION_OBJECT_2003X64
{
PVOID StartingVa;
PVOID EndingVa;
struct _SECTION_OBJECT_2003X64 *Parent;
struct _SECTION_OBJECT_2003X64 *LeftChild;
struct _SECTION_OBJECT_2003X64 *RightChild;
struct _SEGMENT_2003X64 *Segment;
} SECTION_OBJECT_2003X64, *PSECTION_OBJECT_2003X64;
#define SECTION_OBJ_PTR_OFFSET 0x1f0
#endif
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!