• 驱动开发:内核遍历进程VAD结构体


    在上一篇文章《驱动开发:内核中实现Dump进程转储》中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍VAD结构,该结构的全程是Virtual Address Descriptor虚拟地址描述符,VAD是一个AVL平衡二叉树,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个VAD节点,由一个MMVAD结构完整描述。

    VAD结构的遍历效果如下:

    那么这个结构在哪?每一个进程都有自己单独的VAD结构树,这个结构通常在EPROCESS结构里面里面,在内核调试模式下使用dt _EPROCESS可得到如下信息。

    lyshark.com 1: kd> dt _EPROCESS
    ntdll!_EPROCESS
       +0x500 Vm               : _MMSUPPORT_FULL
       +0x640 MmProcessLinks   : _LIST_ENTRY
       +0x650 ModifiedPageCount : Uint4B
       +0x654 ExitStatus       : Int4B
       +0x658 VadRoot          : _RTL_AVL_TREE
       +0x660 VadHint          : Ptr64 Void
       +0x668 VadCount         : Uint8B
       +0x670 VadPhysicalPages : Uint8B
       +0x678 VadPhysicalPagesLimit : Uint8B
    

    可以看到在本系统中VAD的偏移是+0x658紧跟其后的还有vadCount的计数等。

    VAD结构是如何被添加的?通常情况下系统调用VirtualAllocate等申请一段堆内存时,则会在VAD树上增加一个结点_MMVAD结构体,需要说明的是栈并不受VAD的管理。由系统直接分配空间,并把地址记录在了TEB中。

    lyshark.com 0: kd> dt _MMVAD
    nt!_MMVAD
       +0x000 Core             : _MMVAD_SHORT
       +0x040 u2               : <anonymous-tag>
       +0x048 Subsection       : Ptr64 _SUBSECTION
       +0x050 FirstPrototypePte : Ptr64 _MMPTE
       +0x058 LastContiguousPte : Ptr64 _MMPTE
       +0x060 ViewLinks        : _LIST_ENTRY
       +0x070 VadsProcess      : Ptr64 _EPROCESS
       +0x078 u4               : <anonymous-tag>
       +0x080 FileObject       : Ptr64 _FILE_OBJECT
    

    结构体MMVAD则是每一个VAD内存块的属性,这个内存结构定义在WinDBG中可看到。

    如上在EPROCESS结构中可以找到VAD结构的相对偏移+0x658以及进程VAD计数偏移+0x668,我们首先通过!process 0 0指令得到当前所有进程的EPROCESS结构,并选中进程。

    lyshark.com 0: kd> !process 0 0
    PROCESS ffffe28fbb0860c0
        SessionId: 1  Cid: 11a8    Peb: 0035c000  ParentCid: 11c8
        DirBase: 309f3002  ObjectTable: ffffac87ba3da580  HandleCount: 145.
        Image: x64.exe
    

    此处的ffffe28fbb0860c0正是我们所需要的EPROCESS结构。

    当需要得到该进程的VAD结构时,只需要使用!vad ffffe28fbb0860c0 + 0x658来显示该进程的VAD树。

    至于获取VAD有多少条,则可以直接使用!vad ffffe28fbb0860c0 + 0x668来获取到。

    既然手动可以遍历出来,那么自动化也并不难,首先定义头文件vad.h同样这是微软定义,如果想要的到最新的,自己下载WinDBG调试内核输入命令。

    #pragma once
    #include 
    
    typedef struct _MM_GRAPHICS_VAD_FLAGS        // 15 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     ULONG32      Lock : 1;                   // 0 BitPosition                   
    	/*0x000*/     ULONG32      LockContended : 1;          // 1 BitPosition                   
    	/*0x000*/     ULONG32      DeleteInProgress : 1;       // 2 BitPosition                   
    	/*0x000*/     ULONG32      NoChange : 1;               // 3 BitPosition                   
    	/*0x000*/     ULONG32      VadType : 3;                // 4 BitPosition                   
    	/*0x000*/     ULONG32      Protection : 5;             // 7 BitPosition                   
    	/*0x000*/     ULONG32      PreferredNode : 6;          // 12 BitPosition                  
    	/*0x000*/     ULONG32      PageSize : 2;               // 18 BitPosition                  
    	/*0x000*/     ULONG32      PrivateMemoryAlwaysSet : 1; // 20 BitPosition                  
    	/*0x000*/     ULONG32      WriteWatch : 1;             // 21 BitPosition                  
    	/*0x000*/     ULONG32      FixedLargePageSize : 1;     // 22 BitPosition                  
    	/*0x000*/     ULONG32      ZeroFillPagesOptional : 1;  // 23 BitPosition                  
    	/*0x000*/     ULONG32      GraphicsAlwaysSet : 1;      // 24 BitPosition                  
    	/*0x000*/     ULONG32      GraphicsUseCoherentBus : 1; // 25 BitPosition                  
    	/*0x000*/     ULONG32      GraphicsPageProtection : 3; // 26 BitPosition                  
    }MM_GRAPHICS_VAD_FLAGS, *PMM_GRAPHICS_VAD_FLAGS;
    typedef struct _MM_PRIVATE_VAD_FLAGS         // 15 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     ULONG32      Lock : 1;                   // 0 BitPosition                   
    	/*0x000*/     ULONG32      LockContended : 1;          // 1 BitPosition                   
    	/*0x000*/     ULONG32      DeleteInProgress : 1;       // 2 BitPosition                   
    	/*0x000*/     ULONG32      NoChange : 1;               // 3 BitPosition                   
    	/*0x000*/     ULONG32      VadType : 3;                // 4 BitPosition                   
    	/*0x000*/     ULONG32      Protection : 5;             // 7 BitPosition                   
    	/*0x000*/     ULONG32      PreferredNode : 6;          // 12 BitPosition                  
    	/*0x000*/     ULONG32      PageSize : 2;               // 18 BitPosition                  
    	/*0x000*/     ULONG32      PrivateMemoryAlwaysSet : 1; // 20 BitPosition                  
    	/*0x000*/     ULONG32      WriteWatch : 1;             // 21 BitPosition                  
    	/*0x000*/     ULONG32      FixedLargePageSize : 1;     // 22 BitPosition                  
    	/*0x000*/     ULONG32      ZeroFillPagesOptional : 1;  // 23 BitPosition                  
    	/*0x000*/     ULONG32      Graphics : 1;               // 24 BitPosition                  
    	/*0x000*/     ULONG32      Enclave : 1;                // 25 BitPosition                  
    	/*0x000*/     ULONG32      ShadowStack : 1;            // 26 BitPosition                  
    }MM_PRIVATE_VAD_FLAGS, *PMM_PRIVATE_VAD_FLAGS;
    
    
    typedef struct _MMVAD_FLAGS            // 9 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     ULONG32      Lock : 1;             // 0 BitPosition                  
    	/*0x000*/     ULONG32      LockContended : 1;    // 1 BitPosition                  
    	/*0x000*/     ULONG32      DeleteInProgress : 1; // 2 BitPosition                  
    	/*0x000*/     ULONG32      NoChange : 1;         // 3 BitPosition                  
    	/*0x000*/     ULONG32      VadType : 3;          // 4 BitPosition                  
    	/*0x000*/     ULONG32      Protection : 5;       // 7 BitPosition                  
    	/*0x000*/     ULONG32      PreferredNode : 6;    // 12 BitPosition                 
    	/*0x000*/     ULONG32      PageSize : 2;         // 18 BitPosition                 
    	/*0x000*/     ULONG32      PrivateMemory : 1;    // 20 BitPosition                 
    }MMVAD_FLAGS, *PMMVAD_FLAGS;
    
    typedef struct _MM_SHARED_VAD_FLAGS            // 11 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     ULONG32      Lock : 1;                     // 0 BitPosition                   
    	/*0x000*/     ULONG32      LockContended : 1;            // 1 BitPosition                   
    	/*0x000*/     ULONG32      DeleteInProgress : 1;         // 2 BitPosition                   
    	/*0x000*/     ULONG32      NoChange : 1;                 // 3 BitPosition                   
    	/*0x000*/     ULONG32      VadType : 3;                  // 4 BitPosition                   
    	/*0x000*/     ULONG32      Protection : 5;               // 7 BitPosition                   
    	/*0x000*/     ULONG32      PreferredNode : 6;            // 12 BitPosition                  
    	/*0x000*/     ULONG32      PageSize : 2;                 // 18 BitPosition                  
    	/*0x000*/     ULONG32      PrivateMemoryAlwaysClear : 1; // 20 BitPosition                  
    	/*0x000*/     ULONG32      PrivateFixup : 1;             // 21 BitPosition                  
    	/*0x000*/     ULONG32      HotPatchAllowed : 1;          // 22 BitPosition                  
    }MM_SHARED_VAD_FLAGS, *PMM_SHARED_VAD_FLAGS;
    
    typedef struct _MMVAD_FLAGS2             // 7 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     ULONG32      FileOffset : 24;        // 0 BitPosition                  
    	/*0x000*/     ULONG32      Large : 1;              // 24 BitPosition                 
    	/*0x000*/     ULONG32      TrimBehind : 1;         // 25 BitPosition                 
    	/*0x000*/     ULONG32      Inherit : 1;            // 26 BitPosition                 
    	/*0x000*/     ULONG32      NoValidationNeeded : 1; // 27 BitPosition                 
    	/*0x000*/     ULONG32      PrivateDemandZero : 1;  // 28 BitPosition                 
    	/*0x000*/     ULONG32      Spare : 3;              // 29 BitPosition                 
    }MMVAD_FLAGS2, *PMMVAD_FLAGS2;
    
    typedef struct _MMVAD_SHORT
    {
    	RTL_BALANCED_NODE VadNode;
    	UINT32 StartingVpn;               /*0x18*/
    	UINT32 EndingVpn;                 /*0x01C*/
    	UCHAR StartingVpnHigh;
    	UCHAR EndingVpnHigh;
    	UCHAR CommitChargeHigh;
    	UCHAR SpareNT64VadUChar;
    	INT32 ReferenceCount;
    	EX_PUSH_LOCK PushLock;            /*0x028*/
    	struct
    	{
    		union
    		{
    			ULONG_PTR flag;
    			MM_PRIVATE_VAD_FLAGS PrivateVadFlags;                        /*0x030*/
    			MMVAD_FLAGS  VadFlags;
    			MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;
    			MM_SHARED_VAD_FLAGS   SharedVadFlags;
    		}Flags;
    
    	}u1;
    
    	PVOID EventList;                        /*0x038*/
    
    }MMVAD_SHORT, *PMMVAD_SHORT;
    
    typedef struct _MMADDRESS_NODE
    {
    	ULONG64 u1;
    	struct _MMADDRESS_NODE* LeftChild;
    	struct _MMADDRESS_NODE* RightChild;
    	ULONG64 StartingVpn;
    	ULONG64 EndingVpn;
    }MMADDRESS_NODE, *PMMADDRESS_NODE;
    
    typedef struct _MMEXTEND_INFO     // 2 elements, 0x10 bytes (sizeof) 
    {
    	/*0x000*/     UINT64       CommittedSize;
    	/*0x008*/     ULONG32      ReferenceCount;
    	/*0x00C*/     UINT8        _PADDING0_[0x4];
    }MMEXTEND_INFO, *PMMEXTEND_INFO;
    struct _SEGMENT
    {
    	struct _CONTROL_AREA* ControlArea;
    	ULONG TotalNumberOfPtes;
    	ULONG SegmentFlags;
    	ULONG64 NumberOfCommittedPages;
    	ULONG64 SizeOfSegment;
    	union
    	{
    		struct _MMEXTEND_INFO* ExtendInfo;
    		void* BasedAddress;
    	}u;
    	ULONG64 SegmentLock;
    	ULONG64 u1;
    	ULONG64 u2;
    	PVOID* PrototypePte;
    	ULONGLONG ThePtes[0x1];
    };
    
    typedef struct _EX_FAST_REF
    {
    	union
    	{
    		PVOID Object;
    		ULONG_PTR RefCnt : 3;
    		ULONG_PTR Value;
    	};
    } EX_FAST_REF, *PEX_FAST_REF;
    
    typedef struct _CONTROL_AREA                      // 17 elements, 0x80 bytes (sizeof) 
    {
    	/*0x000*/     struct _SEGMENT* Segment;
    	union                                         // 2 elements, 0x10 bytes (sizeof)  
    	{
    		/*0x008*/         struct _LIST_ENTRY ListHead;              // 2 elements, 0x10 bytes (sizeof)  
    		/*0x008*/         VOID*        AweContext;
    	};
    	/*0x018*/     UINT64       NumberOfSectionReferences;
    	/*0x020*/     UINT64       NumberOfPfnReferences;
    	/*0x028*/     UINT64       NumberOfMappedViews;
    	/*0x030*/     UINT64       NumberOfUserReferences;
    	/*0x038*/     ULONG32 u;                     // 2 elements, 0x4 bytes (sizeof)   
    	/*0x03C*/     ULONG32 u1;                    // 2 elements, 0x4 bytes (sizeof)   
    	/*0x040*/     struct _EX_FAST_REF FilePointer;              // 3 elements, 0x8 bytes (sizeof)   
    	// 4 elements, 0x8 bytes (sizeof)   
    }CONTROL_AREA, *PCONTROL_AREA;
    
    typedef struct _SUBSECTION_
    {
    	struct _CONTROL_AREA* ControlArea;
    
    }SUBSECTION, *PSUBSECTION;
    
    typedef struct _MMVAD
    {
    	MMVAD_SHORT Core;
    	union                 /*0x040*/
    	{
    		UINT32 LongFlags2;
    		//现在用不到省略
    		MMVAD_FLAGS2 VadFlags2;
    
    	}u2;
    	PSUBSECTION Subsection;               /*0x048*/
    	PVOID FirstPrototypePte;        /*0x050*/
    	PVOID LastContiguousPte;        /*0x058*/
    	LIST_ENTRY ViewLinks;           /*0x060*/
    	PEPROCESS VadsProcess;          /*0x070*/
    	PVOID u4;                       /*0x078*/
    	PVOID FileObject;               /*0x080*/
    }MMVAD, *PMMVAD;
    
    typedef struct _RTL_AVL_TREE         // 1 elements, 0x8 bytes (sizeof) 
    {
    	/*0x000*/     struct _RTL_BALANCED_NODE* Root;
    }RTL_AVL_TREE, *PRTL_AVL_TREE;
    
    typedef struct _VAD_INFO_
    {
    	ULONG_PTR pVad;
    	ULONG_PTR startVpn;
    	ULONG_PTR endVpn;
    	ULONG_PTR pFileObject;
    	ULONG_PTR flags;
    }VAD_INFO, *PVAD_INFO;
    
    typedef struct _ALL_VADS_
    {
    	ULONG nCnt;
    	VAD_INFO VadInfos[1];
    }ALL_VADS, *PALL_VADS;
    
    typedef struct _MMSECTION_FLAGS                        // 27 elements, 0x4 bytes (sizeof) 
    {
    	/*0x000*/     UINT32       BeingDeleted : 1;                     // 0 BitPosition                   
    	/*0x000*/     UINT32       BeingCreated : 1;                     // 1 BitPosition                   
    	/*0x000*/     UINT32       BeingPurged : 1;                      // 2 BitPosition                   
    	/*0x000*/     UINT32       NoModifiedWriting : 1;                // 3 BitPosition                   
    	/*0x000*/     UINT32       FailAllIo : 1;                        // 4 BitPosition                   
    	/*0x000*/     UINT32       Image : 1;                            // 5 BitPosition                   
    	/*0x000*/     UINT32       Based : 1;                            // 6 BitPosition                   
    	/*0x000*/     UINT32       File : 1;                             // 7 BitPosition                   
    	/*0x000*/     UINT32       AttemptingDelete : 1;                 // 8 BitPosition                   
    	/*0x000*/     UINT32       PrefetchCreated : 1;                  // 9 BitPosition                   
    	/*0x000*/     UINT32       PhysicalMemory : 1;                   // 10 BitPosition                  
    	/*0x000*/     UINT32       ImageControlAreaOnRemovableMedia : 1; // 11 BitPosition                  
    	/*0x000*/     UINT32       Reserve : 1;                          // 12 BitPosition                  
    	/*0x000*/     UINT32       Commit : 1;                           // 13 BitPosition                  
    	/*0x000*/     UINT32       NoChange : 1;                         // 14 BitPosition                  
    	/*0x000*/     UINT32       WasPurged : 1;                        // 15 BitPosition                  
    	/*0x000*/     UINT32       UserReference : 1;                    // 16 BitPosition                  
    	/*0x000*/     UINT32       GlobalMemory : 1;                     // 17 BitPosition                  
    	/*0x000*/     UINT32       DeleteOnClose : 1;                    // 18 BitPosition                  
    	/*0x000*/     UINT32       FilePointerNull : 1;                  // 19 BitPosition                  
    	/*0x000*/     ULONG32      PreferredNode : 6;                    // 20 BitPosition                  
    	/*0x000*/     UINT32       GlobalOnlyPerSession : 1;             // 26 BitPosition                  
    	/*0x000*/     UINT32       UserWritable : 1;                     // 27 BitPosition                  
    	/*0x000*/     UINT32       SystemVaAllocated : 1;                // 28 BitPosition                  
    	/*0x000*/     UINT32       PreferredFsCompressionBoundary : 1;   // 29 BitPosition                  
    	/*0x000*/     UINT32       UsingFileExtents : 1;                 // 30 BitPosition                  
    	/*0x000*/     UINT32       PageSize64K : 1;                      // 31 BitPosition                  
    }MMSECTION_FLAGS, *PMMSECTION_FLAGS;
    
    typedef struct _SECTION                          // 9 elements, 0x40 bytes (sizeof) 
    {
    	/*0x000*/     struct _RTL_BALANCED_NODE SectionNode;       // 6 elements, 0x18 bytes (sizeof) 
    	/*0x018*/     UINT64       StartingVpn;
    	/*0x020*/     UINT64       EndingVpn;
    	/*0x028*/     union {
    		PCONTROL_AREA   ControlArea;
    		PVOID   FileObject;
    
    	}u1;                   // 4 elements, 0x8 bytes (sizeof)  
    	/*0x030*/     UINT64       SizeOfSection;
    	/*0x038*/     union {
    		ULONG32 LongFlags;
    		MMSECTION_FLAGS Flags;
    	}u;                    // 2 elements, 0x4 bytes (sizeof)  
    	struct                                       // 3 elements, 0x4 bytes (sizeof)  
    	{
    		/*0x03C*/         ULONG32      InitialPageProtection : 12; // 0 BitPosition                   
    		/*0x03C*/         ULONG32      SessionId : 19;             // 12 BitPosition                  
    		/*0x03C*/         ULONG32      NoValidationNeeded : 1;     // 31 BitPosition                  
    	};
    }SECTION, *PSECTION;
    

    引入vad.h头文件,并写入如下代码,此处的eprocess_offset_VadRoot以及eprocess_offset_VadCount 则是上方得出的相对于EPROCESS结构的偏移值,每个系统都不一样,版本不同偏移值会不同。

    #include "vad.h"
    #include 
    
    // 定义VAD相对于EProcess头部偏移值
    #define eprocess_offset_VadRoot 0x658
    #define eprocess_offset_VadCount 0x668
    
    VOID EnumVad(PMMVAD Root, PALL_VADS pBuffer, ULONG nCnt)
    {
    	if (!Root || !pBuffer || !nCnt)
    	{
    		return;
    	}
    
    	__try
    	{
    		if (nCnt > pBuffer->nCnt)
    		{
    			// 得到起始页与结束页
    			ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
    			endptr = endptr << 32;
    
    			ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
    			startptr = startptr << 32;
    
    			// 得到根节点
    			pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
    
    			// 起始页: startingVpn * 0x1000
    			pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
    
    			// 结束页: EndVpn * 0x1000 + 0xfff
    			pBuffer->VadInfos[pBuffer->nCnt].endVpn = ((endptr | Root->Core.EndingVpn) << PAGE_SHIFT) + 0xfff;
    
    			// VAD标志 928 = Mapped    1049088 = Private   ....
    			pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
    
    			// 验证节点可读性
    			if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
    			{
    				if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
    				{
    					pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
    				}
    			}
    			pBuffer->nCnt++;
    		}
    
    		if (MmIsAddressValid(Root->Core.VadNode.Left))
    		{
    			// 递归枚举左子树
    			EnumVad((PMMVAD)Root->Core.VadNode.Left, pBuffer, nCnt);
    		}
    
    		if (MmIsAddressValid(Root->Core.VadNode.Right))
    		{
    			// 递归枚举右子树
    			EnumVad((PMMVAD)Root->Core.VadNode.Right, pBuffer, nCnt);
    		}
    	}
    	__except (1)
    	{
    	}
    }
    
    BOOLEAN EnumProcessVad(ULONG Pid, PALL_VADS pBuffer, ULONG nCnt)
    {
    	PEPROCESS Peprocess = 0;
    	PRTL_AVL_TREE Table = NULL;
    	PMMVAD Root = NULL;
    
    	// 通过进程PID得到进程EProcess
    	if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid, &Peprocess)))
    	{
    		// 与偏移相加得到VAD头节点
    		Table = (PRTL_AVL_TREE)((UCHAR*)Peprocess + eprocess_offset_VadRoot);
    		if (!MmIsAddressValid(Table) || !eprocess_offset_VadRoot)
    		{
    			return FALSE;
    		}
    
    		__try
    		{
    			// 取出头节点
    			Root = (PMMVAD)Table->Root;
    
    			if (nCnt > pBuffer->nCnt)
    			{
    				// 得到起始页与结束页
    				ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
    				endptr = endptr << 32;
    
    				ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
    				startptr = startptr << 32;
    
    				pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
    
    				// 起始页: startingVpn * 0x1000
    				pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
    
    				// 结束页: EndVpn * 0x1000 + 0xfff
    				pBuffer->VadInfos[pBuffer->nCnt].endVpn = (endptr | Root->Core.EndingVpn) << PAGE_SHIFT;
    				pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
    
    				if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
    				{
    					if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
    					{
    						pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
    					}
    				}
    				pBuffer->nCnt++;
    			}
    
    			// 枚举左子树
    			if (Table->Root->Left)
    			{
    				EnumVad((MMVAD*)Table->Root->Left, pBuffer, nCnt);
    			}
    
    			// 枚举右子树
    			if (Table->Root->Right)
    			{
    				EnumVad((MMVAD*)Table->Root->Right, pBuffer, nCnt);
    			}
    		}
    		__finally
    		{
    			ObDereferenceObject(Peprocess);
    		}
    	}
    	else
    	{
    		return FALSE;
    	}
    
    	return TRUE;
    }
    
    VOID UnDriver(PDRIVER_OBJECT driver)
    {
    	DbgPrint(("Uninstall Driver Is OK \n"));
    }
    
    NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
    {
    	DbgPrint(("hello lyshark \n"));
    
    	typedef struct
    	{
    		ULONG nPid;
    		ULONG nSize;
    		PALL_VADS pBuffer;
    	}VADProcess;
    
    	__try
    	{
    		VADProcess vad = { 0 };
    
    		vad.nPid = 4520;
    
    		// 默认有1000个线程
    		vad.nSize = sizeof(VAD_INFO) * 0x5000 + sizeof(ULONG);
    
    		// 分配临时空间
    		vad.pBuffer = (PALL_VADS)ExAllocatePool(PagedPool, vad.nSize);
    
    		// 根据传入长度得到枚举数量
    		ULONG nCount = (vad.nSize - sizeof(ULONG)) / sizeof(VAD_INFO);
    
    		// 枚举VAD
    		EnumProcessVad(vad.nPid, vad.pBuffer, nCount);
    
    
    		// 输出VAD
    		for (size_t i = 0; i < vad.pBuffer->nCnt; i++)
    		{
    			DbgPrint("StartVPN = %p | ", vad.pBuffer->VadInfos[i].startVpn);
    			DbgPrint("EndVPN = %p | ", vad.pBuffer->VadInfos[i].endVpn);
    			DbgPrint("PVAD = %p | ", vad.pBuffer->VadInfos[i].pVad);
    			DbgPrint("Flags = %d | ", vad.pBuffer->VadInfos[i].flags);
    			DbgPrint("pFileObject = %p \n", vad.pBuffer->VadInfos[i].pFileObject);
    		}
    	}
    	__except (1)
    	{
    	}
    
    	Driver->DriverUnload = UnDriver;
    	return STATUS_SUCCESS;
    }
    

    程序运行后输出效果如下:

  • 相关阅读:
    AVS3:DMVR
    程序员自由创业周记#12:999%
    Abbexa丨Abbexa 脱落酸 (ABA) ELISA试剂盒方案
    groupadd
    基于Java+SpringBoot+Vue前后端分离在线互动学习网站设计和实现
    秒杀系统设计
    前端面试题 10 个「有用」JavaScript 代码片段
    【技术实战】Java开发岗位的八股文积累【一】
    tictoc例子理解
    【例题】逆波兰表达式求值(图解+代码)
  • 原文地址:https://www.cnblogs.com/LyShark/p/16786221.html