ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

VAD树结构体的属性以及遍历

2019-10-26 10:02:36  阅读:337  来源: 互联网

标签:遍历 ULONG 树结构 MMVAD pEprocess VAD 0x000 进程


Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html

VAD树的属性以及遍历

 

前面学习过的PFNDATABSAE是管理物理页的,整个操作系统仅维护一个PFNDATABASE。

现在的VAD是管理虚拟内存的,每一个进程有自己单独的一个VAD树。

VAD树:

  1. 比如你使用VirtualAllocate函数申请一个内存,则会在VAD树上增加一个结点,其是_MMVAD结构体。
  2. 一个VAD结点可以有多个页,这在StartingVpn和EndingVpn会介绍。
  3. 当以MEN_SERVIED保留属性提交时,其只是在VAD树上挂上一个节点,真正提交时这棵树才是由意义的。

 

一、VAD结构体介绍

  kd> dt _MMVAD
  nt!_MMVAD
     +0x000 StartingVpn      : Uint4B
     +0x004 EndingVpn        : Uint4B
     +0x008 Parent           : Ptr32 _MMVAD
     +0x00c LeftChild        : Ptr32 _MMVAD
     +0x010 RightChild       : Ptr32 _MMVAD
     +0x014 u                : __unnamed
     +0x018 ControlArea      : Ptr32 _CONTROL_AREA
     +0x01c FirstPrototypePte : Ptr32 _MMPTE
     +0x020 LastContiguousPte : Ptr32 _MMPTE
     +0x024 u2               : __unnamed

1. StringVpn 起始页 / EndingVpn结束页

  1)两者算法是不同的。起始页:startingVpn*0x1000/结束页:EndVpn*0x1000+0xfff。

2. Parent、LeftChild、RightChild - 其父节点、左子树、右子树。

  1)我们遍历这些树时用到的就是这些结构体成员。

3. u - 其是_MMVAN_FLAGS属性,非常重要的。

  kd> dt _MMVAD_FLAGS
   nt!_MMVAD_FLAGS
      +0x000 CommitCharge     : Pos 0, 19 Bits
      +0x000 PhysicalMapping  : Pos 19, 1 Bit
      +0x000 ImageMap         : Pos 20, 1 Bit
      +0x000 UserPhysicalPages : Pos 21, 1 Bit
      +0x000 NoChange         : Pos 22, 1 Bit
      +0x000 WriteWatch       : Pos 23, 1 Bit
      +0x000 Protection       : Pos 24, 5 Bits
      +0x000 LargePages       : Pos 29, 1 Bit
      +0x000 MemCommit        : Pos 30, 1 Bit
      +0x000 PrivateMemory    : Pos 31, 1 Bit
  1)CommitCharge  实际提交的页数。

    其19Bits,我们内存低字节7ffffff,正好十九位。

    比如我们以MEN_RESERVED保留形式提交了4页大小的内存,此时这里为2,将一页改为EXECUTE属性,这时这里就会变成2。

  2)PyhsicalMapping:内核物理页映射。

  3)UserPhysicalPages:内核物理页映射。

  4)PrivateMemory:如果私有设置为1。

  5)ImageMap:对dll/exe等文件进行保护,防止其被修改(使用映射写拷贝之类的原理)

     如果ImageMap为1,PrivateMemory为0,说明其为DLL。

  6)NoChange:关于锁页技术。当置为1,像VirtualProtect等函数不会改变其页的属性。

  7)LargePage:标志是否为大页。

  8)MemCommit:提交状态,只要提交就会置为1(CommitCharge存储提交了多少页)

  9)Protection:3bit,关于保护(比如页的读写、可执行等)。

    将其定义的值取出,赋值到该位。

4. ContraArea 控制结构

  其指向一个_CONTROL_AREA的数据结构,该结构就暂不表述了。

  1)_CONTROL_AREA+ 0x24 FilePointer,文件指针,指向一个_FILE_OBJECT结构体。

  2)_FILE_OBJECT结构体中,保存着文件对象很多关键的信息。

    a> +0x30 FileName 文件名

      若想知道该页属于哪个文件,可以查看这里。

      将.sys文件伪装成.dll文件,则必须修改这里。

    b> +0x26-0x28 文件保护属性

      比如一个文件被独占无法删除,在内核中你可以将DeleteAccess位置1,之后强制删除。

 

二、利用windbg遍历VAD树

1. 每个进程的VAD树存储在_EPROCESS+0x11c结构体中,其是ROOTVAD根结点。

  

2. 获取每个进程的 _EPROCESS,使用指令!process 0 0,得到PROCESS的值就是指向_EPROCESS的指针。

  

3. 当获取VadRoot之后,可以使用 !vad VadRoot来显示该进程的VAD树。

 

 

 

 

三、使用代码实现VAD树的遍历

代码核心就是先遍历进程找出目标进程(这里默认 test.exe),之后对目标进程的VAD树进行遍历。

 1 #include <ntddk.h>
 2 
 3 
 4 //---------------------//
 5 // MMVAD结构体简单定义 //
 6 //---------------------//
 7 typedef struct _MMVAD {
 8     ULONG StartingVpn;
 9     ULONG EndingVpn;
10     struct _MMVAD * Parent;
11     struct _MMVAD * LeftChild;
12     struct _MMVAD * RightChild;
13 }MMVAD,*PMMVAD;
14 
15 
16 
17 VOID Unload(IN PDRIVER_OBJECT pDriverObject) {
18     DbgPrint("Driver UnLoad!");
19 }
20 
21 //-----------//
22 // 遍历VAD树 //
23 //-----------//
24 VOID vad_enum(PMMVAD pVad) {
25     if (pVad) {
26         DbgPrint("Start: %x | End: %x | \r\n", pVad->StartingVpn, pVad->EndingVpn);
27         if (pVad->LeftChild)
28             vad_enum(pVad->LeftChild);
29         if (pVad->RightChild)
30             vad_enum(pVad->RightChild);
31     }
32 }
33 
34 
35 //-------------------------------------------------------------//
36 //  在内核中进程遍历的原理就是先获取系统进程EPROCESS结构       //
37 //        然后依照其链表来获取其他的进程                         //
38 //        依次遍历出来                                           //
39 //-------------------------------------------------------------//
40 NTSTATUS process_enum() {
41 
42     PEPROCESS pEprocess = NULL; // 得到系统进程地址
43     PEPROCESS pFirstEprocess = NULL;
44     ULONG ulProcessName = 0; // 字符串指针,指向进程名称
45     ULONG ulProcessID = 0;    // 进程ID
46     ANSI_STRING target_str; // 带检测进程的名称
47     ANSI_STRING ansi_string; // 
48     ULONG VadRoot;
49 
50     //----------------------------//
51     // 得到当前系统进程的EPROCESS //
52     //----------------------------//
53     pEprocess = PsGetCurrentProcess();
54     if (pEprocess == NULL) {
55         DbgPrint("获取当前系统进程EPROCESS错误..");
56         return STATUS_SUCCESS;
57     }
58     DbgPrint("pEprocess addr is %x0x8\r\n", pEprocess);
59     pFirstEprocess = pEprocess;
60 
61     while (pEprocess) {
62 
63         ulProcessName = (ULONG)pEprocess + 0x174;
64         ulProcessID = *(ULONG*)((ULONG)pEprocess + 0x84);
65         VadRoot = *(ULONG*)((ULONG)pEprocess + 0x11c);
66 
67         //--------------------------------------//
68         // 将目标进程与当前进程的进程名进行对比 //
69         //--------------------------------------//
70         RtlInitAnsiString(&ansi_string, (PCSTR)ulProcessName);    
71         RtlInitAnsiString(&target_str, "test.exe");
72         if (RtlEqualString(&ansi_string, &target_str, TRUE)) {
73             DbgPrint("检测到进程字符串,%x", ulProcessID);
74             vad_enum((PMMVAD)VadRoot); // 开始遍历目标进程的VAD树
75             return STATUS_SUCCESS;
76         }
77         pEprocess = (PEPROCESS)(*(ULONG*)((ULONG)pEprocess + 0x88) - 0x88);
78 
79         if (pEprocess == pFirstEprocess || *(ULONG*)((ULONG)pEprocess + 0x84) <= 0) {
80             DbgPrint("遍历结束!未检测到进程ID!\r\n");
81             break;
82         }
83     }
84     return STATUS_SUCCESS;
85 }
86 
87 NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING registeryPat) {
88     DbgPrint("Driver Loaded!");
89     pDriverObject->DriverUnload = Unload;
90     process_enum();
91     return STATUS_SUCCESS;
92 }

标签:遍历,ULONG,树结构,MMVAD,pEprocess,VAD,0x000,进程
来源: https://www.cnblogs.com/onetrainee/p/11741909.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有