ToB企服应用市场:ToB评测及商务社交产业平台

标题: 驱动开发:内核遍历进程VAD结构体 [打印本页]

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

那么这个结构在哪?每一个进程都有自己单独的VAD结构树,这个结构通常在EPROCESS结构里面里面,在内核调试模式下使用dt _EPROCESS可得到如下信息。
  1. lyshark.com 1: kd> dt _EPROCESS
  2. ntdll!_EPROCESS
  3.    +0x500 Vm               : _MMSUPPORT_FULL
  4.    +0x640 MmProcessLinks   : _LIST_ENTRY
  5.    +0x650 ModifiedPageCount : Uint4B
  6.    +0x654 ExitStatus       : Int4B
  7.    +0x658 VadRoot          : _RTL_AVL_TREE
  8.    +0x660 VadHint          : Ptr64 Void
  9.    +0x668 VadCount         : Uint8B
  10.    +0x670 VadPhysicalPages : Uint8B
  11.    +0x678 VadPhysicalPagesLimit : Uint8B
复制代码
可以看到在本系统中VAD的偏移是+0x658紧跟其后的还有vadCount的计数等。

VAD结构是如何被添加的?通常情况下系统调用VirtualAllocate等申请一段堆内存时,则会在VAD树上增加一个结点_MMVAD结构体,需要说明的是栈并不受VAD的管理。由系统直接分配空间,并把地址记录在了TEB中。
  1. lyshark.com 0: kd> dt _MMVAD
  2. nt!_MMVAD
  3.    +0x000 Core             : _MMVAD_SHORT
  4.    +0x040 u2               : <anonymous-tag>
  5.    +0x048 Subsection       : Ptr64 _SUBSECTION
  6.    +0x050 FirstPrototypePte : Ptr64 _MMPTE
  7.    +0x058 LastContiguousPte : Ptr64 _MMPTE
  8.    +0x060 ViewLinks        : _LIST_ENTRY
  9.    +0x070 VadsProcess      : Ptr64 _EPROCESS
  10.    +0x078 u4               : <anonymous-tag>
  11.    +0x080 FileObject       : Ptr64 _FILE_OBJECT
复制代码
结构体MMVAD则是每一个VAD内存块的属性,这个内存结构定义在WinDBG中可看到。

如上在EPROCESS结构中可以找到VAD结构的相对偏移+0x658以及进程VAD计数偏移+0x668,我们首先通过!process 0 0指令得到当前所有进程的EPROCESS结构,并选中进程。
  1. lyshark.com 0: kd> !process 0 0
  2. PROCESS ffffe28fbb0860c0
  3.     SessionId: 1  Cid: 11a8    Peb: 0035c000  ParentCid: 11c8
  4.     DirBase: 309f3002  ObjectTable: ffffac87ba3da580  HandleCount: 145.
  5.     Image: x64.exe
复制代码
此处的ffffe28fbb0860c0正是我们所需要的EPROCESS结构。

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

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

既然手动可以遍历出来,那么自动化也并不难,首先定义头文件vad.h同样这是微软定义,如果想要的到最新的,自己下载WinDBG调试内核输入命令。
  1. #pragma once
  2. #include <ntifs.h>
  3. typedef struct _MM_GRAPHICS_VAD_FLAGS        // 15 elements, 0x4 bytes (sizeof)
  4. {
  5.         /*0x000*/     ULONG32      Lock : 1;                   // 0 BitPosition                  
  6.         /*0x000*/     ULONG32      LockContended : 1;          // 1 BitPosition                  
  7.         /*0x000*/     ULONG32      DeleteInProgress : 1;       // 2 BitPosition                  
  8.         /*0x000*/     ULONG32      NoChange : 1;               // 3 BitPosition                  
  9.         /*0x000*/     ULONG32      VadType : 3;                // 4 BitPosition                  
  10.         /*0x000*/     ULONG32      Protection : 5;             // 7 BitPosition                  
  11.         /*0x000*/     ULONG32      PreferredNode : 6;          // 12 BitPosition                  
  12.         /*0x000*/     ULONG32      PageSize : 2;               // 18 BitPosition                  
  13.         /*0x000*/     ULONG32      PrivateMemoryAlwaysSet : 1; // 20 BitPosition                  
  14.         /*0x000*/     ULONG32      WriteWatch : 1;             // 21 BitPosition                  
  15.         /*0x000*/     ULONG32      FixedLargePageSize : 1;     // 22 BitPosition                  
  16.         /*0x000*/     ULONG32      ZeroFillPagesOptional : 1;  // 23 BitPosition                  
  17.         /*0x000*/     ULONG32      GraphicsAlwaysSet : 1;      // 24 BitPosition                  
  18.         /*0x000*/     ULONG32      GraphicsUseCoherentBus : 1; // 25 BitPosition                  
  19.         /*0x000*/     ULONG32      GraphicsPageProtection : 3; // 26 BitPosition                  
  20. }MM_GRAPHICS_VAD_FLAGS, *PMM_GRAPHICS_VAD_FLAGS;
  21. typedef struct _MM_PRIVATE_VAD_FLAGS         // 15 elements, 0x4 bytes (sizeof)
  22. {
  23.         /*0x000*/     ULONG32      Lock : 1;                   // 0 BitPosition                  
  24.         /*0x000*/     ULONG32      LockContended : 1;          // 1 BitPosition                  
  25.         /*0x000*/     ULONG32      DeleteInProgress : 1;       // 2 BitPosition                  
  26.         /*0x000*/     ULONG32      NoChange : 1;               // 3 BitPosition                  
  27.         /*0x000*/     ULONG32      VadType : 3;                // 4 BitPosition                  
  28.         /*0x000*/     ULONG32      Protection : 5;             // 7 BitPosition                  
  29.         /*0x000*/     ULONG32      PreferredNode : 6;          // 12 BitPosition                  
  30.         /*0x000*/     ULONG32      PageSize : 2;               // 18 BitPosition                  
  31.         /*0x000*/     ULONG32      PrivateMemoryAlwaysSet : 1; // 20 BitPosition                  
  32.         /*0x000*/     ULONG32      WriteWatch : 1;             // 21 BitPosition                  
  33.         /*0x000*/     ULONG32      FixedLargePageSize : 1;     // 22 BitPosition                  
  34.         /*0x000*/     ULONG32      ZeroFillPagesOptional : 1;  // 23 BitPosition                  
  35.         /*0x000*/     ULONG32      Graphics : 1;               // 24 BitPosition                  
  36.         /*0x000*/     ULONG32      Enclave : 1;                // 25 BitPosition                  
  37.         /*0x000*/     ULONG32      ShadowStack : 1;            // 26 BitPosition                  
  38. }MM_PRIVATE_VAD_FLAGS, *PMM_PRIVATE_VAD_FLAGS;
  39. typedef struct _MMVAD_FLAGS            // 9 elements, 0x4 bytes (sizeof)
  40. {
  41.         /*0x000*/     ULONG32      Lock : 1;             // 0 BitPosition                  
  42.         /*0x000*/     ULONG32      LockContended : 1;    // 1 BitPosition                  
  43.         /*0x000*/     ULONG32      DeleteInProgress : 1; // 2 BitPosition                  
  44.         /*0x000*/     ULONG32      NoChange : 1;         // 3 BitPosition                  
  45.         /*0x000*/     ULONG32      VadType : 3;          // 4 BitPosition                  
  46.         /*0x000*/     ULONG32      Protection : 5;       // 7 BitPosition                  
  47.         /*0x000*/     ULONG32      PreferredNode : 6;    // 12 BitPosition                 
  48.         /*0x000*/     ULONG32      PageSize : 2;         // 18 BitPosition                 
  49.         /*0x000*/     ULONG32      PrivateMemory : 1;    // 20 BitPosition                 
  50. }MMVAD_FLAGS, *PMMVAD_FLAGS;
  51. typedef struct _MM_SHARED_VAD_FLAGS            // 11 elements, 0x4 bytes (sizeof)
  52. {
  53.         /*0x000*/     ULONG32      Lock : 1;                     // 0 BitPosition                  
  54.         /*0x000*/     ULONG32      LockContended : 1;            // 1 BitPosition                  
  55.         /*0x000*/     ULONG32      DeleteInProgress : 1;         // 2 BitPosition                  
  56.         /*0x000*/     ULONG32      NoChange : 1;                 // 3 BitPosition                  
  57.         /*0x000*/     ULONG32      VadType : 3;                  // 4 BitPosition                  
  58.         /*0x000*/     ULONG32      Protection : 5;               // 7 BitPosition                  
  59.         /*0x000*/     ULONG32      PreferredNode : 6;            // 12 BitPosition                  
  60.         /*0x000*/     ULONG32      PageSize : 2;                 // 18 BitPosition                  
  61.         /*0x000*/     ULONG32      PrivateMemoryAlwaysClear : 1; // 20 BitPosition                  
  62.         /*0x000*/     ULONG32      PrivateFixup : 1;             // 21 BitPosition                  
  63.         /*0x000*/     ULONG32      HotPatchAllowed : 1;          // 22 BitPosition                  
  64. }MM_SHARED_VAD_FLAGS, *PMM_SHARED_VAD_FLAGS;
  65. typedef struct _MMVAD_FLAGS2             // 7 elements, 0x4 bytes (sizeof)
  66. {
  67.         /*0x000*/     ULONG32      FileOffset : 24;        // 0 BitPosition                  
  68.         /*0x000*/     ULONG32      Large : 1;              // 24 BitPosition                 
  69.         /*0x000*/     ULONG32      TrimBehind : 1;         // 25 BitPosition                 
  70.         /*0x000*/     ULONG32      Inherit : 1;            // 26 BitPosition                 
  71.         /*0x000*/     ULONG32      NoValidationNeeded : 1; // 27 BitPosition                 
  72.         /*0x000*/     ULONG32      PrivateDemandZero : 1;  // 28 BitPosition                 
  73.         /*0x000*/     ULONG32      Spare : 3;              // 29 BitPosition                 
  74. }MMVAD_FLAGS2, *PMMVAD_FLAGS2;
  75. typedef struct _MMVAD_SHORT
  76. {
  77.         RTL_BALANCED_NODE VadNode;
  78.         UINT32 StartingVpn;               /*0x18*/
  79.         UINT32 EndingVpn;                 /*0x01C*/
  80.         UCHAR StartingVpnHigh;
  81.         UCHAR EndingVpnHigh;
  82.         UCHAR CommitChargeHigh;
  83.         UCHAR SpareNT64VadUChar;
  84.         INT32 ReferenceCount;
  85.         EX_PUSH_LOCK PushLock;            /*0x028*/
  86.         struct
  87.         {
  88.                 union
  89.                 {
  90.                         ULONG_PTR flag;
  91.                         MM_PRIVATE_VAD_FLAGS PrivateVadFlags;                        /*0x030*/
  92.                         MMVAD_FLAGS  VadFlags;
  93.                         MM_GRAPHICS_VAD_FLAGS GraphicsVadFlags;
  94.                         MM_SHARED_VAD_FLAGS   SharedVadFlags;
  95.                 }Flags;
  96.         }u1;
  97.         PVOID EventList;                        /*0x038*/
  98. }MMVAD_SHORT, *PMMVAD_SHORT;
  99. typedef struct _MMADDRESS_NODE
  100. {
  101.         ULONG64 u1;
  102.         struct _MMADDRESS_NODE* LeftChild;
  103.         struct _MMADDRESS_NODE* RightChild;
  104.         ULONG64 StartingVpn;
  105.         ULONG64 EndingVpn;
  106. }MMADDRESS_NODE, *PMMADDRESS_NODE;
  107. typedef struct _MMEXTEND_INFO     // 2 elements, 0x10 bytes (sizeof)
  108. {
  109.         /*0x000*/     UINT64       CommittedSize;
  110.         /*0x008*/     ULONG32      ReferenceCount;
  111.         /*0x00C*/     UINT8        _PADDING0_[0x4];
  112. }MMEXTEND_INFO, *PMMEXTEND_INFO;
  113. struct _SEGMENT
  114. {
  115.         struct _CONTROL_AREA* ControlArea;
  116.         ULONG TotalNumberOfPtes;
  117.         ULONG SegmentFlags;
  118.         ULONG64 NumberOfCommittedPages;
  119.         ULONG64 SizeOfSegment;
  120.         union
  121.         {
  122.                 struct _MMEXTEND_INFO* ExtendInfo;
  123.                 void* BasedAddress;
  124.         }u;
  125.         ULONG64 SegmentLock;
  126.         ULONG64 u1;
  127.         ULONG64 u2;
  128.         PVOID* PrototypePte;
  129.         ULONGLONG ThePtes[0x1];
  130. };
  131. typedef struct _EX_FAST_REF
  132. {
  133.         union
  134.         {
  135.                 PVOID Object;
  136.                 ULONG_PTR RefCnt : 3;
  137.                 ULONG_PTR Value;
  138.         };
  139. } EX_FAST_REF, *PEX_FAST_REF;
  140. typedef struct _CONTROL_AREA                      // 17 elements, 0x80 bytes (sizeof)
  141. {
  142.         /*0x000*/     struct _SEGMENT* Segment;
  143.         union                                         // 2 elements, 0x10 bytes (sizeof)  
  144.         {
  145.                 /*0x008*/         struct _LIST_ENTRY ListHead;              // 2 elements, 0x10 bytes (sizeof)  
  146.                 /*0x008*/         VOID*        AweContext;
  147.         };
  148.         /*0x018*/     UINT64       NumberOfSectionReferences;
  149.         /*0x020*/     UINT64       NumberOfPfnReferences;
  150.         /*0x028*/     UINT64       NumberOfMappedViews;
  151.         /*0x030*/     UINT64       NumberOfUserReferences;
  152.         /*0x038*/     ULONG32 u;                     // 2 elements, 0x4 bytes (sizeof)   
  153.         /*0x03C*/     ULONG32 u1;                    // 2 elements, 0x4 bytes (sizeof)   
  154.         /*0x040*/     struct _EX_FAST_REF FilePointer;              // 3 elements, 0x8 bytes (sizeof)   
  155.         // 4 elements, 0x8 bytes (sizeof)   
  156. }CONTROL_AREA, *PCONTROL_AREA;
  157. typedef struct _SUBSECTION_
  158. {
  159.         struct _CONTROL_AREA* ControlArea;
  160. }SUBSECTION, *PSUBSECTION;
  161. typedef struct _MMVAD
  162. {
  163.         MMVAD_SHORT Core;
  164.         union                 /*0x040*/
  165.         {
  166.                 UINT32 LongFlags2;
  167.                 //现在用不到省略
  168.                 MMVAD_FLAGS2 VadFlags2;
  169.         }u2;
  170.         PSUBSECTION Subsection;               /*0x048*/
  171.         PVOID FirstPrototypePte;        /*0x050*/
  172.         PVOID LastContiguousPte;        /*0x058*/
  173.         LIST_ENTRY ViewLinks;           /*0x060*/
  174.         PEPROCESS VadsProcess;          /*0x070*/
  175.         PVOID u4;                       /*0x078*/
  176.         PVOID FileObject;               /*0x080*/
  177. }MMVAD, *PMMVAD;
  178. typedef struct _RTL_AVL_TREE         // 1 elements, 0x8 bytes (sizeof)
  179. {
  180.         /*0x000*/     struct _RTL_BALANCED_NODE* Root;
  181. }RTL_AVL_TREE, *PRTL_AVL_TREE;
  182. typedef struct _VAD_INFO_
  183. {
  184.         ULONG_PTR pVad;
  185.         ULONG_PTR startVpn;
  186.         ULONG_PTR endVpn;
  187.         ULONG_PTR pFileObject;
  188.         ULONG_PTR flags;
  189. }VAD_INFO, *PVAD_INFO;
  190. typedef struct _ALL_VADS_
  191. {
  192.         ULONG nCnt;
  193.         VAD_INFO VadInfos[1];
  194. }ALL_VADS, *PALL_VADS;
  195. typedef struct _MMSECTION_FLAGS                        // 27 elements, 0x4 bytes (sizeof)
  196. {
  197.         /*0x000*/     UINT32       BeingDeleted : 1;                     // 0 BitPosition                  
  198.         /*0x000*/     UINT32       BeingCreated : 1;                     // 1 BitPosition                  
  199.         /*0x000*/     UINT32       BeingPurged : 1;                      // 2 BitPosition                  
  200.         /*0x000*/     UINT32       NoModifiedWriting : 1;                // 3 BitPosition                  
  201.         /*0x000*/     UINT32       FailAllIo : 1;                        // 4 BitPosition                  
  202.         /*0x000*/     UINT32       Image : 1;                            // 5 BitPosition                  
  203.         /*0x000*/     UINT32       Based : 1;                            // 6 BitPosition                  
  204.         /*0x000*/     UINT32       File : 1;                             // 7 BitPosition                  
  205.         /*0x000*/     UINT32       AttemptingDelete : 1;                 // 8 BitPosition                  
  206.         /*0x000*/     UINT32       PrefetchCreated : 1;                  // 9 BitPosition                  
  207.         /*0x000*/     UINT32       PhysicalMemory : 1;                   // 10 BitPosition                  
  208.         /*0x000*/     UINT32       ImageControlAreaOnRemovableMedia : 1; // 11 BitPosition                  
  209.         /*0x000*/     UINT32       Reserve : 1;                          // 12 BitPosition                  
  210.         /*0x000*/     UINT32       Commit : 1;                           // 13 BitPosition                  
  211.         /*0x000*/     UINT32       NoChange : 1;                         // 14 BitPosition                  
  212.         /*0x000*/     UINT32       WasPurged : 1;                        // 15 BitPosition                  
  213.         /*0x000*/     UINT32       UserReference : 1;                    // 16 BitPosition                  
  214.         /*0x000*/     UINT32       GlobalMemory : 1;                     // 17 BitPosition                  
  215.         /*0x000*/     UINT32       DeleteOnClose : 1;                    // 18 BitPosition                  
  216.         /*0x000*/     UINT32       FilePointerNull : 1;                  // 19 BitPosition                  
  217.         /*0x000*/     ULONG32      PreferredNode : 6;                    // 20 BitPosition                  
  218.         /*0x000*/     UINT32       GlobalOnlyPerSession : 1;             // 26 BitPosition                  
  219.         /*0x000*/     UINT32       UserWritable : 1;                     // 27 BitPosition                  
  220.         /*0x000*/     UINT32       SystemVaAllocated : 1;                // 28 BitPosition                  
  221.         /*0x000*/     UINT32       PreferredFsCompressionBoundary : 1;   // 29 BitPosition                  
  222.         /*0x000*/     UINT32       UsingFileExtents : 1;                 // 30 BitPosition                  
  223.         /*0x000*/     UINT32       PageSize64K : 1;                      // 31 BitPosition                  
  224. }MMSECTION_FLAGS, *PMMSECTION_FLAGS;
  225. typedef struct _SECTION                          // 9 elements, 0x40 bytes (sizeof)
  226. {
  227.         /*0x000*/     struct _RTL_BALANCED_NODE SectionNode;       // 6 elements, 0x18 bytes (sizeof)
  228.         /*0x018*/     UINT64       StartingVpn;
  229.         /*0x020*/     UINT64       EndingVpn;
  230.         /*0x028*/     union {
  231.                 PCONTROL_AREA   ControlArea;
  232.                 PVOID   FileObject;
  233.         }u1;                   // 4 elements, 0x8 bytes (sizeof)  
  234.         /*0x030*/     UINT64       SizeOfSection;
  235.         /*0x038*/     union {
  236.                 ULONG32 LongFlags;
  237.                 MMSECTION_FLAGS Flags;
  238.         }u;                    // 2 elements, 0x4 bytes (sizeof)  
  239.         struct                                       // 3 elements, 0x4 bytes (sizeof)  
  240.         {
  241.                 /*0x03C*/         ULONG32      InitialPageProtection : 12; // 0 BitPosition                  
  242.                 /*0x03C*/         ULONG32      SessionId : 19;             // 12 BitPosition                  
  243.                 /*0x03C*/         ULONG32      NoValidationNeeded : 1;     // 31 BitPosition                  
  244.         };
  245. }SECTION, *PSECTION;
复制代码
引入vad.h头文件,并写入如下代码,此处的eprocess_offset_VadRoot以及eprocess_offset_VadCount 则是上方得出的相对于EPROCESS结构的偏移值,每个系统都不一样,版本不同偏移值会不同。
  1. #include "vad.h"
  2. #include <ntifs.h>
  3. // 定义VAD相对于EProcess头部偏移值
  4. #define eprocess_offset_VadRoot 0x658
  5. #define eprocess_offset_VadCount 0x668
  6. VOID EnumVad(PMMVAD Root, PALL_VADS pBuffer, ULONG nCnt)
  7. {
  8.         if (!Root || !pBuffer || !nCnt)
  9.         {
  10.                 return;
  11.         }
  12.         __try
  13.         {
  14.                 if (nCnt > pBuffer->nCnt)
  15.                 {
  16.                         // 得到起始页与结束页
  17.                         ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
  18.                         endptr = endptr << 32;
  19.                         ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
  20.                         startptr = startptr << 32;
  21.                         // 得到根节点
  22.                         pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
  23.                         // 起始页: startingVpn * 0x1000
  24.                         pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
  25.                         // 结束页: EndVpn * 0x1000 + 0xfff
  26.                         pBuffer->VadInfos[pBuffer->nCnt].endVpn = ((endptr | Root->Core.EndingVpn) << PAGE_SHIFT) + 0xfff;
  27.                         // VAD标志 928 = Mapped    1049088 = Private   ....
  28.                         pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
  29.                         // 验证节点可读性
  30.                         if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
  31.                         {
  32.                                 if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
  33.                                 {
  34.                                         pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
  35.                                 }
  36.                         }
  37.                         pBuffer->nCnt++;
  38.                 }
  39.                 if (MmIsAddressValid(Root->Core.VadNode.Left))
  40.                 {
  41.                         // 递归枚举左子树
  42.                         EnumVad((PMMVAD)Root->Core.VadNode.Left, pBuffer, nCnt);
  43.                 }
  44.                 if (MmIsAddressValid(Root->Core.VadNode.Right))
  45.                 {
  46.                         // 递归枚举右子树
  47.                         EnumVad((PMMVAD)Root->Core.VadNode.Right, pBuffer, nCnt);
  48.                 }
  49.         }
  50.         __except (1)
  51.         {
  52.         }
  53. }
  54. BOOLEAN EnumProcessVad(ULONG Pid, PALL_VADS pBuffer, ULONG nCnt)
  55. {
  56.         PEPROCESS Peprocess = 0;
  57.         PRTL_AVL_TREE Table = NULL;
  58.         PMMVAD Root = NULL;
  59.         // 通过进程PID得到进程EProcess
  60.         if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)Pid, &Peprocess)))
  61.         {
  62.                 // 与偏移相加得到VAD头节点
  63.                 Table = (PRTL_AVL_TREE)((UCHAR*)Peprocess + eprocess_offset_VadRoot);
  64.                 if (!MmIsAddressValid(Table) || !eprocess_offset_VadRoot)
  65.                 {
  66.                         return FALSE;
  67.                 }
  68.                 __try
  69.                 {
  70.                         // 取出头节点
  71.                         Root = (PMMVAD)Table->Root;
  72.                         if (nCnt > pBuffer->nCnt)
  73.                         {
  74.                                 // 得到起始页与结束页
  75.                                 ULONG64 endptr = (ULONG64)Root->Core.EndingVpnHigh;
  76.                                 endptr = endptr << 32;
  77.                                 ULONG64 startptr = (ULONG64)Root->Core.StartingVpnHigh;
  78.                                 startptr = startptr << 32;
  79.                                 pBuffer->VadInfos[pBuffer->nCnt].pVad = (ULONG_PTR)Root;
  80.                                 // 起始页: startingVpn * 0x1000
  81.                                 pBuffer->VadInfos[pBuffer->nCnt].startVpn = (startptr | Root->Core.StartingVpn) << PAGE_SHIFT;
  82.                                 // 结束页: EndVpn * 0x1000 + 0xfff
  83.                                 pBuffer->VadInfos[pBuffer->nCnt].endVpn = (endptr | Root->Core.EndingVpn) << PAGE_SHIFT;
  84.                                 pBuffer->VadInfos[pBuffer->nCnt].flags = Root->Core.u1.Flags.flag;
  85.                                 if (MmIsAddressValid(Root->Subsection) && MmIsAddressValid(Root->Subsection->ControlArea))
  86.                                 {
  87.                                         if (MmIsAddressValid((PVOID)((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4)))
  88.                                         {
  89.                                                 pBuffer->VadInfos[pBuffer->nCnt].pFileObject = ((Root->Subsection->ControlArea->FilePointer.Value >> 4) << 4);
  90.                                         }
  91.                                 }
  92.                                 pBuffer->nCnt++;
  93.                         }
  94.                         // 枚举左子树
  95.                         if (Table->Root->Left)
  96.                         {
  97.                                 EnumVad((MMVAD*)Table->Root->Left, pBuffer, nCnt);
  98.                         }
  99.                         // 枚举右子树
  100.                         if (Table->Root->Right)
  101.                         {
  102.                                 EnumVad((MMVAD*)Table->Root->Right, pBuffer, nCnt);
  103.                         }
  104.                 }
  105.                 __finally
  106.                 {
  107.                         ObDereferenceObject(Peprocess);
  108.                 }
  109.         }
  110.         else
  111.         {
  112.                 return FALSE;
  113.         }
  114.         return TRUE;
  115. }
  116. VOID UnDriver(PDRIVER_OBJECT driver)
  117. {
  118.         DbgPrint(("Uninstall Driver Is OK \n"));
  119. }
  120. NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
  121. {
  122.         DbgPrint(("hello lyshark \n"));
  123.         typedef struct
  124.         {
  125.                 ULONG nPid;
  126.                 ULONG nSize;
  127.                 PALL_VADS pBuffer;
  128.         }VADProcess;
  129.         __try
  130.         {
  131.                 VADProcess vad = { 0 };
  132.                 vad.nPid = 4520;
  133.                 // 默认有1000个线程
  134.                 vad.nSize = sizeof(VAD_INFO) * 0x5000 + sizeof(ULONG);
  135.                 // 分配临时空间
  136.                 vad.pBuffer = (PALL_VADS)ExAllocatePool(PagedPool, vad.nSize);
  137.                 // 根据传入长度得到枚举数量
  138.                 ULONG nCount = (vad.nSize - sizeof(ULONG)) / sizeof(VAD_INFO);
  139.                 // 枚举VAD
  140.                 EnumProcessVad(vad.nPid, vad.pBuffer, nCount);
  141.                 // 输出VAD
  142.                 for (size_t i = 0; i < vad.pBuffer->nCnt; i++)
  143.                 {
  144.                         DbgPrint("StartVPN = %p | ", vad.pBuffer->VadInfos[i].startVpn);
  145.                         DbgPrint("EndVPN = %p | ", vad.pBuffer->VadInfos[i].endVpn);
  146.                         DbgPrint("PVAD = %p | ", vad.pBuffer->VadInfos[i].pVad);
  147.                         DbgPrint("Flags = %d | ", vad.pBuffer->VadInfos[i].flags);
  148.                         DbgPrint("pFileObject = %p \n", vad.pBuffer->VadInfos[i].pFileObject);
  149.                 }
  150.         }
  151.         __except (1)
  152.         {
  153.         }
  154.         Driver->DriverUnload = UnDriver;
  155.         return STATUS_SUCCESS;
  156. }
复制代码
程序运行后输出效果如下:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4