VadRoot枚举进程模块在Windows7下的完整实现

时间:2022-06-28 05:46:23

原理小伟的小伟在?t=66886说的挺清楚了,Windows7下有一些变化,使用NtQueryVirtualMemory来枚举模块是一个效率很低的事情,自己枚举VadRoot速度是很快的,有N个子节点时,,为log(N),还有我在这里补上的基地址获取和镜像大小获取,废话不多说,完整代码如下,仅给有需要的人参考,大侠飘过……

代码:

typedef struct _MMADDRESS_NODE // 0x14 {     union u1; // +0x0(0x4)     struct _MMADDRESS_NODE* LeftChild; // +0x4(0x4)     struct _MMADDRESS_NODE* RightChild; // +0x8(0x4)     ULONG StartingVpn; // +0xc(0x4)     ULONG EndingVpn; // +0x10(0x4) }MMADDRESS_NODE,*PMMADDRESS_NODE; #pragma pack(push,1) typedef struct _EX_FAST_REF {     union     {         PVOID Object;         ULONG_PTR RefCnt:3;         ULONG_PTR Value;     }; } EX_FAST_REF, *PEX_FAST_REF; #pragma pack(pop) struct _SEGMENT // 0x38 {    struct _CONTROL_AREA* ControlArea; // +0x0(0x4)     ULONG TotalNumberOfPtes; // +0x4(0x4)     ULONG SegmentFlags; // +0x8(0x4)     ULONG NumberOfCommittedPages; // +0xc(0x4)     ULONGLONG SizeOfSegment; // +0x10(0x8)     union     {     struct _MMEXTEND_INFO* ExtendInfo; // +0x18(0x4)     void* BasedAddress; // +0x18(0x4)     };     EX_PUSH_LOCK SegmentLock; // +0x1c(0x4)     ULONG u1; // +0x20(0x4)     ULONG u2; // +0x24(0x4)     struct _MMPTE* PrototypePte; // +0x28(0x4)     //ULONGLONG ThePtes[0x1]; // +0x30(0x8) }; struct _CONTROL_AREA // 0x50 {     struct _SEGMENT* Segment; // +0x0(0x4)     struct _LIST_ENTRY DereferenceList; // +0x4(0x8)     ULONG NumberOfSectionReferences; // +0xc(0x4)     ULONG NumberOfPfnReferences; // +0x10(0x4)     ULONG NumberOfMappedViews; // +0x14(0x4)     ULONG NumberOfUserReferences; // +0x18(0x4)     ULONG  u; // +0x1c(0x4)     ULONG FlushInProgressCount; // +0x20(0x4)     struct _EX_FAST_REF FilePointer; // +0x24(0x4)    }; struct _SUBSECTION // 0x20 {     struct _CONTROL_AREA* ControlArea; // +0x0(0x4)     struct _MMPTE* SubsectionBase; // +0x4(0x4)     struct _SUBSECTION* NextSubsection; // +0x8(0x4)     ULONG PtesInSubsection; // +0xc(0x4)     ULONG UnusedPtes; // +0x10(0x4)     struct _MM_AVL_TABLE* GlobalPerSessionHead; // +0x10(0x4)     union u; // +0x14(0x4)     ULONG StartingSector; // +0x18(0x4)     ULONG NumberOfFullSectors; // +0x1c(0x4) }; typedef struct _MMVAD // 0x3c {     ULONG u1; // +0x0(0x4)     struct _MMVAD* LeftChild; // +0x4(0x4)     struct _MMVAD* RightChild; // +0x8(0x4)     ULONG StartingVpn; // +0xc(0x4)     ULONG EndingVpn; // +0x10(0x4)     ULONG u; // +0x14(0x4)     EX_PUSH_LOCK PushLock; // +0x18(0x4)     ULONG u5; // +0x1c(0x4)     ULONG u2; // +0x20(0x4)     struct _SUBSECTION* Subsection; // +0x24(0x4)     struct _MSUBSECTION* MappedSubsection; // +0x24(0x4)     struct _MMPTE* FirstPrototypePte; // +0x28(0x4)     struct _MMPTE* LastContiguousPte; // +0x2c(0x4)     struct _LIST_ENTRY ViewLinks; // +0x30(0x8)     struct _EPROCESS* VadsProcess; // +0x38(0x4) }MMVAD; typedef struct   tag_MM_AVL_TABLE // 0x20 {     struct _MMADDRESS_NODE BalancedRoot; // +0x0(0x14)     ULONG DepthOfTree; // +0x14(0x4)     ULONG Unused; // +0x14(0x4)     ULONG NumberGenericTableElements; // +0x14(0x4)     void* NodeHint; // +0x18(0x4)     void* NodeFreeHint; // +0x1c(0x4) }MM_AVL_TABLE,*PMMAVL_TABLE; #define GetVadRoot(eprocess)  ((PVOID)((char*)eprocess+0x278)) VOID PrintTree(MMVAD* Root) {   POBJECT_NAME_INFORMATION  Str=(POBJECT_NAME_INFORMATION )ExAllocatePool(PagedPool,800);   ULONG RetLen=0;   if(!Str||!Root)     return ;   RtlZeroMemory(Str,800);//递归要节省堆栈资源,不要大量使用局部变量   __try   {     if(MmIsAddressValid(Root->Subsection)&&MmIsAddressValid(Root->Subsection->ControlArea))     {       if(MmIsAddressValid((PVOID)Root->Subsection->ControlArea->FilePointer.Value))       {         PFILE_OBJECT pFileObj=(PFILE_OBJECT)((Root->Subsection->ControlArea->FilePointer.Value>>3)<<3);         if(MmIsAddressValid(pFileObj))         {           NTSTATUS Status=ObQueryNameString(pFileObj,Str,800,&RetLen);           if(NT_SUCCESS(Status))           {             KdPrint(("Base:%08X Size:%dKb ",Root->Subsection->ControlArea->Segment->BasedAddress,              (Root->Subsection->ControlArea->Segment->SizeOfSegment)/0x1000));             KdPrint(("Name:%ws\n",Str->Name.Buffer));           }           else           {             KdPrint(("不能获取到对象!%08X\n",Status));           }         }       }     }   }   __except(1)   {     KdPrint(("Invalid Address!\n"));   }   ExFreePool(Str);   __try   {   if(MmIsAddressValid(Root->LeftChild))     PrintTree(Root->LeftChild);   if(MmIsAddressValid(Root->RightChild))     PrintTree(Root->RightChild);   }   __except(1)   {     KdPrint(("异常!!"));     return;   } } VOID ShowProcessModule(ULONG Pid) { #ifdef DBG   _asm int 3 #endif    PMMAVL_TABLE Table;   PEPROCESS Epr=0;   if(NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid,&Epr)))   {     KeAttachProcess(Epr);     Table=(PMMAVL_TABLE)GetVadRoot(Epr);     if(Table->BalancedRoot.LeftChild)       PrintTree((MMVAD*)Table->BalancedRoot.LeftChild);     if(Table->BalancedRoot.RightChild)       PrintTree((MMVAD*)Table->BalancedRoot.RightChild);     KeDetachProcess();   } } VOID DriverUnLoad(PDRIVER_OBJECT Driver) {   KdPrint(("Driver UnLoaded!\n")); } extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING Reg) {   KdPrint(("Enter Driver Entry!\n"));   pDriverObject->DriverUnload=DriverUnLoad;   ShowProcessModule(2000);   KdPrint(("Leave Driver Entry!\n"));   return STATUS_SUCCESS; 对记事本的测试结果如下:
Base:75740000 Size:25Kb Name:\Device\HarddiskVolume2\Windows\System32\sechost.dll
Base:00060000 Size:48Kb Name:\Device\HarddiskVolume2\Windows\System32\notepad.exe
Base:00000000 Size:102Kb Name:\Device\HarddiskVolume2\Windows\System32\locale.nls
Base:74140000 Size:414Kb Name:\Device\HarddiskVolume2\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7600.16385_none_421189da2b7fabfc\comctl32.dll
Base:00000000 Size:718Kb Name:\Device\HarddiskVolume2\Windows\Globalization\Sorting\SortDefault.nls
Base:00000000 Size:2368Kb Name:\Device\HarddiskVolume2\Windows\Fonts\StaticCache.dat
Base:70FD0000 Size:81Kb Name:\Device\HarddiskVolume2\Windows\System32\winspool.drv
Base:73FC0000 Size:64Kb Name:\Device\HarddiskVolume2\Windows\System32\uxtheme.dll
Base:75420000 Size:172Kb Name:\Device\HarddiskVolume2\Windows\System32\msvcrt.dll
Base:75210000 Size:74Kb Name:\Device\HarddiskVolume2\Windows\System32\KernelBase.dll
Base:745A0000 Size:9Kb Name:\Device\HarddiskVolume2\Windows\System32\version.dll
Base:74FF0000 Size:12Kb Name:\Device\HarddiskVolume2\Windows\System32\cryptbase.dll
Base:753A0000 Size:123Kb Name:\Device\HarddiskVolume2\Windows\System32\comdlg32.dll
Base:75680000 Size:31Kb Name:\Device\HarddiskVolume2\Windows\System32\imm32.dll
Base:75520000 Size:201Kb Name:\Device\HarddiskVolume2\Windows\System32\user32.dll
Base:756A0000 Size:157Kb Name:\Device\HarddiskVolume2\Windows\System32\usp10.dll
Base:76F50000 Size:316Kb Name:\Device\HarddiskVolume2\Windows\System32\ntdll.dll
Base:75BA0000 Size:160Kb Name:\Device\HarddiskVolume2\Windows\System32\advapi32.dll
Base:75A60000 Size:143Kb Name:\Device\HarddiskVolume2\Windows\System32\oleaut32.dll
Base:75900000 Size:348Kb Name:\Device\HarddiskVolume2\Windows\System32\ole32.dll
Base:757D0000 Size:204Kb Name:\Device\HarddiskVolume2\Windows\System32\msctf.dll
Base:75AF0000 Size:161Kb Name:\Device\HarddiskVolume2\Windows\System32\rpcrt4.dll
Base:76D30000 Size:212Kb Name:\Device\HarddiskVolume2\Windows\System32\kernel32.dll
Base:75C40000 Size:3145Kb Name:\Device\HarddiskVolume2\Windows\System32\shell32.dll
Base:77180000 Size:80Kb Name:\Device\HarddiskVolume2\Windows\System32\apisetschema.dll
Base:770B0000 Size:78Kb Name:\Device\HarddiskVolume2\Windows\System32\gdi32.dll
Base:770A0000 Size:10Kb Name:\Device\HarddiskVolume2\Windows\System32\lpk.dll
Base:77120000 Size:87Kb Name:\Device\HarddiskVolume2\Windows\System32\shlwapi.dll

jpg改rar