爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

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

      首页 知识中心 软件开发 文章详情页

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

      2024-07-01 01:32:23 阅读次数:497

      结构

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

      VAD结构的遍历效果如下:

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

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

       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结构体

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

       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中可看到。

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

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

       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结构时,只需要使用!vad ffffe28fbb0860c0 + 0x658来显示该进程的VAD树。

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

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

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

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

      #pragma once
      #include <ntifs.h>
      
      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 <ntifs.h>
      
      // 定义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;
      }
      

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

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

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://my.oschina.net/lyshark/blog/5587451,作者:LyShark,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:驱动开发:内核R3与R0内存映射拷贝

      下一篇:手写Node模块系统-执行字符串中的代码

      相关文章

      2025-05-14 10:02:58

      30天拿下Rust之结构体

      在Rust语言中,结构体是一种用户自定义的数据类型,它允许你将多个相关的值组合成一个单一的类型。结构体是一种复合数据类型,可以用来封装多个不同类型的字段,这些字段可以是基本数据类型、其他结构体、枚举类型等。通过使用结构体,你可以创建更复杂的数据结构,并定义它们的行为。

      2025-05-14 10:02:58
      Rust , 使用 , 字段 , 实例 , 方法 , 示例 , 结构
      2025-05-09 09:30:05

      相同结构的两个类赋值

      相同结构的两个类赋值

      2025-05-09 09:30:05
      两个 , 相同 , 结构 , 赋值
      2025-05-09 08:20:32

      MySQL——索引(概述和结构介绍)

      索引(index)是帮助 MySQL 高效获取数据的数据结构(是一种有序的数据结构)。

      2025-05-09 08:20:32
      Tree , 存储 , 引擎 , 数据结构 , 查询 , 索引 , 结构
      2025-05-07 09:10:01

      C语言:自定义类型——结构体

      数组是一组相同类型元素的集合,而结构体同样也是一些值的集合,不同的是,在结构体中,这些值被称为成员变量,而结构体的每个成员变量可以是不同类型的变量:如: 标量、数组、指针,甚⾄是其他结构体。

      2025-05-07 09:10:01
      位段 , 内存 , 字节 , 对齐 , 成员 , 类型 , 结构
      2025-05-07 09:08:23

      C语言三大结构和函数

      顺序结构是根据代码的执行顺序根据运算符的优先级对程序顺序执行的结构。

      2025-05-07 09:08:23
      分支 , 循环 , 执行 , 结构 , 语句
      2025-04-22 09:44:09

      【C语言:自定义类型(结构体、位段、共用体、枚举)】

      【C语言:自定义类型(结构体、位段、共用体、枚举)】

      2025-04-22 09:44:09
      位段 , 对齐 , 成员 , 枚举 , 结构
      2025-04-15 09:25:57

      软件设计师教程(第5版)第3章 数据结构(更新中)

      【数据结构】是指数据元素的集合及元素间的相互关系和构造方法。

      2025-04-15 09:25:57
      二叉树 , 存储 , 排序 , 矩阵 , 结构
      2025-04-14 09:26:51

      深入理解 tree 命令行工具:目录结构可视化的利器

      在日常开发或系统管理中,我们经常需要查看目录的结构。虽然 ls 命令可以列出目录内容,但当目录层级较深时,ls 的输出可能不够直观。这时,tree 命令行工具就派上了用场。它能够以树状结构展示目录内容,帮助我们更清晰地理解目录的组织方式。

      2025-04-14 09:26:51
      tree , 文件 , 目录 , 结构
      2025-04-09 09:14:12

      试探回溯法解决八皇后的问题

      从零开始,尝试逐步增加候选解的长度(本质上是成批的考察具有特定前缀的所有候选解),这种从长度上逐渐向目标解靠近的尝试叫做试探

      2025-04-09 09:14:12
      列表 , 回溯 , 算法 , 结构 , 节点
      2025-03-24 08:45:46

      第四章:程序的描述方式和程序代码流程的结构

      第四章:程序的描述方式和程序代码流程的结构

      2025-03-24 08:45:46
      Python , 代码 , 描述 , 程序 , 结构
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5226915

      查看更多

      最新文章

      C语言:自定义类型——结构体

      2025-05-07 09:10:01

      C语言三大结构和函数

      2025-05-07 09:08:23

      【C语言:自定义类型(结构体、位段、共用体、枚举)】

      2025-04-22 09:44:09

      软件设计师教程(第5版)第3章 数据结构(更新中)

      2025-04-15 09:25:57

      第四章:程序的描述方式和程序代码流程的结构

      2025-03-24 08:45:46

      python中顺序结构

      2025-03-21 08:23:07

      查看更多

      热门文章

      C语言结构体与结构体指针的使用

      2023-03-08 10:38:36

      驱动开发:摘链DKOM进程隐藏

      2023-06-21 06:37:08

      驱动开发:内核中枚举进线程与模块

      2023-06-16 06:08:43

      C语言的结构体与联合体

      2024-11-07 08:22:07

      C语言高级数据表示(C Primer Plus 第六版)

      2024-10-22 07:47:36

      【C语言】循环结构

      2024-12-05 08:49:34

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      【C语言】循环结构

      c语言回顾-结构体

      【第三章:流程控制语句】3.4 Python循环结构

      初始Python篇(2)——逻辑控制、序列

      C语言:自定义类型——结构体

      Python循环结构

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号