设为首页 加入收藏

TOP

驱动开发:内核遍历进程VAD结构体(一)
2023-07-23 13:31:52 】 浏览:114
Tags: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 <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*/     UL
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++ 标准文档 下一篇驱动开发:内核取ntoskrnl模块基..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目