Virtual Address Descriptor
Virtual Address Descriptor
Virtual Address Descriptor (VAD)는 프로세스의 가상 주소를 관리하는 데이터 구조입니다.
VAD는 AVL 트리(_RTL_AVL_TREE) 구조로 이루어져 있으며, 가상 주소 범위 및 페이지 보호 속성 등을 포함하고 있습니다.
AVL Tree
Adelson-Velsky and Landis라는 개발자가 개발한 자체 균형 이진 탐색 트리입니다.
두 자식 서브트리의 높이는 최대 1만큼 차이나며, 만약 어떤 시점에서 높이 차이가 1보다 커지면 이 속성을 유지하기 위해서 자체적으로 균형을 잡습니다.
해당 알고리즘은 삽입과 탐색, 삭제가 매우 빠른게 장점이며, 아래는 AVL 트리를 소개하는 애니메이션입니다.
VadRoot
VAD는 EPROCESS 구조체에 저장되어 있습니다.
1
2
3
4
5
6
7
14: kd> dt_eprocess ffffdf02ec514080
ntdll!_EPROCESS
+0x7d8 VadRoot : _RTL_AVL_TREE
+0x7e0 VadHint : 0xffffdf02`eb35bc30 Void
+0x7e8 VadCount : 0x29d
+0x7f0 VadPhysicalPages : 0
+0x7f8 VadPhysicalPagesLimit : 0
VadHint는 VadRoot하고 동일한 값을 가지고 있으며, 정확한 사용 용도는 모르겠습니다. (아시는 분은 댓글 부탁드립니다)
1
2
3
14: kd> dqs ffffdf02ec514080+7d8 L? 2
ffffdf02`ec514858 ffffdf02`eb35bc30
ffffdf02`ec514860 ffffdf02`eb35bc30
VadCount는 VAD 내에 존재하는 가상 주소의 개수입니다.
1
2
3
4
5
6
14: kd> !vad
VAD Level Start End Commit
ffffdf02ef26f440 8 7ffe0 7ffe0 1 Private READONLY
ffffdf02ef26f210 7 7ffed 7ffed 1 Private READONLY
...
Total VADs: 669, average level: 8, maximum depth: 10
VadRoot는 VAD 트리의 루트 노드(Root Node)입니다.
1
2
3
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_RTL_AVL_TREE *)0xffffdf02ec514858))
(*((ntkrnlmp!_RTL_AVL_TREE *)0xffffdf02ec514858)) [Type: _RTL_AVL_TREE]
[+0x000] Root : 0xffffdf02eb35bc30 [Type: _RTL_BALANCED_NODE *]
_RTL_BALANCED_NODE
AVL 트리의 노드는 _RTL_BALANCED_NODE라는 구조체로 이루어져 있으며, ParentValue에는 VAD 세부 정보를 나타내는 _MMVAD 구조체의 주소가 저장되어 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 ((ntkrnlmp!_RTL_BALANCED_NODE *)0xffffdf02eb35bc30)
((ntkrnlmp!_RTL_BALANCED_NODE *)0xffffdf02eb35bc30) : 0xffffdf02eb35bc30 [Type: _RTL_BALANCED_NODE *]
[+0x000] Children [Type: _RTL_BALANCED_NODE * [2]]
[+0x000] Left : 0xffffdf02f025c760 [Type: _RTL_BALANCED_NODE *]
[+0x008] Right : 0xffffdf02edda5f20 [Type: _RTL_BALANCED_NODE *]
[+0x010 ( 0: 0)] Red : 0x0 [Type: unsigned char]
[+0x010 ( 1: 0)] Balance : 0x0 [Type: unsigned char]
[+0x010] ParentValue : 0x0 [Type: unsigned __int64]
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_RTL_BALANCED_NODE *)0xffffdf02ef07aba0))
(*((ntkrnlmp!_RTL_BALANCED_NODE *)0xffffdf02ef07aba0)) [Type: _RTL_BALANCED_NODE]
[+0x000] Children [Type: _RTL_BALANCED_NODE * [2]]
[+0x000] Left : 0x0 [Type: _RTL_BALANCED_NODE *]
[+0x008] Right : 0x0 [Type: _RTL_BALANCED_NODE *]
[+0x010 ( 0: 0)] Red : 0x0 [Type: unsigned char]
[+0x010 ( 1: 0)] Balance : 0x0 [Type: unsigned char]
[+0x010] ParentValue : 0xffffdf02ed9669c0 [Type: unsigned __int64]
_MMVAD
해당 구조체는 가상 주소 범위, 페이지 보호 속성, 파일 경로 등 세부 정보를 포함하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
14: kd> dt_mmvad ffffdf02ef07aba0
nt!_MMVAD
+0x000 Core : _MMVAD_SHORT
+0x040 u2 : <unnamed-tag>
+0x048 Subsection : 0xffffdf02`e4534860 _SUBSECTION
+0x050 FirstPrototypePte : 0xffffc789`8cf70b80 _MMPTE
+0x058 LastContiguousPte : 0xffffc789`8cf70c80 _MMPTE
+0x060 ViewLinks : _LIST_ENTRY [ 0xffffdf02`e45347e8 - 0xffffdf02`e45347e8 ]
+0x070 VadsProcess : 0xffffdf02`ec514081 _EPROCESS
+0x078 u4 : <unnamed-tag>
+0x080 FileObject : (null)
_MMVAD_SHORT
_MMVAD의 첫 번째 필드(Core)에는 다음과 같이 가상 메모리의 시작 주소와 끝 주소가 저장되어 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0))
(*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0)) [Type: _MMVAD_SHORT]
[+0x000] NextVad : 0x0 [Type: _MMVAD_SHORT *]
[+0x008] ExtraCreateInfo : 0x0 [Type: void *]
[+0x000] VadNode [Type: _RTL_BALANCED_NODE]
[+0x018] StartingVpn : 0xff763e90 [Type: unsigned long]
[+0x01c] EndingVpn : 0xff763eb0 [Type: unsigned long]
[+0x020] StartingVpnHigh : 0x7 [Type: unsigned char]
[+0x021] EndingVpnHigh : 0x7 [Type: unsigned char]
[+0x022] CommitChargeHigh : 0x0 [Type: unsigned char]
[+0x023] SpareNT64VadUChar : 0x0 [Type: unsigned char]
[+0x024] ReferenceCount : 0 [Type: long]
[+0x028] PushLock [Type: _EX_PUSH_LOCK]
[+0x030] u [Type: <unnamed-tag>]
[+0x034] u1 [Type: <unnamed-tag>]
[+0x038] u5 [Type: <unnamed-tag>]
가상 주소를 계산하는 방식은 다음과 같습니다.
1
2
3
4
5
// 시작 주소
(StartingVpnHigh + StartingVpn) * PAGE_SIZE(0x1000) = 0x7ff763e90000
// 끝 주소
(EndingVpnHigh + EndingVpn) * PAGE_SIZE(0x1000) = 0x7ff763eb0000
!vad 명령을 통해 계산한 주소와 비교합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14: kd> !vad
VAD Level Start End Commit
ffffdf02ef07aba0 9 7ff763e90 7ff763eb0 7 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\dwm.exe
14: kd> db 0x7ff763e90000
00007ff7`63e90000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
00007ff7`63e90010 b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00 ........@.......
00007ff7`63e90020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
00007ff7`63e90030 00 00 00 00 00 00 00 00-00 00 00 00 00 01 00 00 ................
00007ff7`63e90040 0e 1f ba 0e 00 b4 09 cd-21 b8 01 4c cd 21 54 68 ........!..L.!Th
00007ff7`63e90050 69 73 20 70 72 6f 67 72-61 6d 20 63 61 6e 6e 6f is program canno
00007ff7`63e90060 74 20 62 65 20 72 75 6e-20 69 6e 20 44 4f 53 20 t be run in DOS
00007ff7`63e90070 6d 6f 64 65 2e 0d 0d 0a-24 00 00 00 00 00 00 00 mode....$.......
VadFlags
_MMVAD의 u 필드에는 VadFlags라는 데이터가 존재합니다.
VadFlags는 해당 페이지에 대한 보호 속성입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0))
(*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0)) [Type: _MMVAD_SHORT]
[+0x000] NextVad : 0x0 [Type: _MMVAD_SHORT *]
[+0x008] ExtraCreateInfo : 0x0 [Type: void *]
[+0x000] VadNode [Type: _RTL_BALANCED_NODE]
[+0x018] StartingVpn : 0xff763e90 [Type: unsigned long]
[+0x01c] EndingVpn : 0xff763eb0 [Type: unsigned long]
[+0x020] StartingVpnHigh : 0x7 [Type: unsigned char]
[+0x021] EndingVpnHigh : 0x7 [Type: unsigned char]
[+0x022] CommitChargeHigh : 0x0 [Type: unsigned char]
[+0x023] SpareNT64VadUChar : 0x0 [Type: unsigned char]
[+0x024] ReferenceCount : 0 [Type: long]
[+0x028] PushLock [Type: _EX_PUSH_LOCK]
[+0x030] u [Type: <unnamed-tag>]
[+0x034] u1 [Type: <unnamed-tag>]
[+0x038] u5 [Type: <unnamed-tag>]
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0)).u
(*((ntkrnlmp!_MMVAD_SHORT *)0xffffdf02ef07aba0)).u [Type: <unnamed-tag>]
[+0x000] LongFlags : 0x3a0 [Type: unsigned long]
[+0x000] VadFlags [Type: _MMVAD_FLAGS]
[+0x000] PrivateVadFlags [Type: _MM_PRIVATE_VAD_FLAGS]
[+0x000] GraphicsVadFlags [Type: _MM_GRAPHICS_VAD_FLAGS]
[+0x000] SharedVadFlags [Type: _MM_SHARED_VAD_FLAGS]
[+0x000] VolatileVadLong : 0x3a0 [Type: unsigned long]
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_MMVAD_FLAGS *)0xffffdf02ef07abd0))
(*((ntkrnlmp!_MMVAD_FLAGS *)0xffffdf02ef07abd0)) [Type: _MMVAD_FLAGS]
[+0x000 ( 0: 0)] Lock : 0x0 [Type: unsigned long]
[+0x000 ( 1: 1)] LockContended : 0x0 [Type: unsigned long]
[+0x000 ( 2: 2)] DeleteInProgress : 0x0 [Type: unsigned long]
[+0x000 ( 3: 3)] NoChange : 0x0 [Type: unsigned long]
[+0x000 ( 6: 4)] VadType : 0x2 [Type: unsigned long]
[+0x000 (11: 7)] Protection : 0x7 [Type: unsigned long]
[+0x000 (18:12)] PreferredNode : 0x0 [Type: unsigned long]
[+0x000 (20:19)] PageSize : 0x0 [Type: unsigned long]
[+0x000 (21:21)] PrivateMemory : 0x0 [Type: unsigned long]
보호 속성에 대한 값은 다음과 같이 정의되며, 해당 덤프에서는 MM_EXECUTE_WRITECOPY(7)입니다.
Value | Protection Type |
---|---|
0 | MM_ZERO_ACCESS |
1 | MM_READONLY |
2 | MM_EXECUTE |
3 | MM_EXECUTE_READ |
4 | MM_READWRITE |
5 | MM_WRITECOPY |
6 | MM_EXECUTE_READWRITE |
7 | MM_EXECUTE_WRITECOPY |
!vad 명령을 통해 확인한 보호 속성과 동일합니다.
1
2
3
14: kd> !vad
VAD Level Start End Commit
ffffdf02ef07aba0 9 7ff763e90 7ff763eb0 7 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\dwm.exe
_FILE_OBJECT
_MMVAD의 Subsection에는 ControlArea라는 필드가 존재합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
14: kd> dt_mmvad ffffdf02ef07aba0
nt!_MMVAD
+0x000 Core : _MMVAD_SHORT
+0x040 u2 : <unnamed-tag>
+0x048 Subsection : 0xffffdf02`e4534860 _SUBSECTION
+0x050 FirstPrototypePte : 0xffffc789`8cf70b80 _MMPTE
+0x058 LastContiguousPte : 0xffffc789`8cf70c80 _MMPTE
+0x060 ViewLinks : _LIST_ENTRY [ 0xffffdf02`e45347e8 - 0xffffdf02`e45347e8 ]
+0x070 VadsProcess : 0xffffdf02`ec514081 _EPROCESS
+0x078 u4 : <unnamed-tag>
+0x080 FileObject : (null)
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 ((ntkrnlmp!_SUBSECTION *)0xffffdf02e4534860)
((ntkrnlmp!_SUBSECTION *)0xffffdf02e4534860) : 0xffffdf02e4534860 [Type: _SUBSECTION *]
[+0x000] ControlArea : 0xffffdf02e45347e0 [Type: _CONTROL_AREA *]
[+0x008] SubsectionBase : 0xffffc7898cf70b80 [Type: _MMPTE *]
[+0x010] NextSubsection : 0xffffdf02e4534898 [Type: _SUBSECTION *]
[+0x018] GlobalPerSessionHead [Type: _RTL_AVL_TREE]
[+0x018] CreationWaitList : 0x0 [Type: _MI_CONTROL_AREA_WAIT_BLOCK *]
[+0x018] SessionDriverProtos : 0x0 [Type: _MI_PER_SESSION_PROTOS *]
[+0x020] u [Type: <unnamed-tag>]
[+0x024] StartingSector : 0x0 [Type: unsigned long]
[+0x028] NumberOfFullSectors : 0x8 [Type: unsigned long]
[+0x02c] PtesInSubsection : 0x1 [Type: unsigned long]
[+0x030] u1 [Type: <unnamed-tag>]
[+0x034 (29: 0)] UnusedPtes : 0x0 [Type: unsigned long]
[+0x034 (30:30)] ExtentQueryNeeded : 0x0 [Type: unsigned long]
[+0x034 (31:31)] DirtyPages : 0x0 [Type: unsigned long]
해당 필드에는 FilePointer가 존재하며, 매핑된 파일에 대한 정보를 포함하고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 ((ntkrnlmp!_CONTROL_AREA *)0xffffdf02e45347e0)
((ntkrnlmp!_CONTROL_AREA *)0xffffdf02e45347e0) : 0xffffdf02e45347e0 [Type: _CONTROL_AREA *]
[+0x000] Segment : 0xffffc78991510b30 [Type: _SEGMENT *]
[+0x008] ListHead [Type: _LIST_ENTRY]
[+0x008] AweContext : 0xffffdf02ef07ac00 [Type: void *]
[+0x018] NumberOfSectionReferences : 0x1 [Type: unsigned __int64]
[+0x020] NumberOfPfnReferences : 0x17 [Type: unsigned __int64]
[+0x028] NumberOfMappedViews : 0x1 [Type: unsigned __int64]
[+0x030] NumberOfUserReferences : 0x2 [Type: unsigned __int64]
[+0x038] u [Type: <unnamed-tag>]
[+0x03c] u1 [Type: <unnamed-tag>]
[+0x040] FilePointer [Type: _EX_FAST_REF]
[+0x048] ControlAreaLock : 0 [Type: long]
[+0x04c] ModifiedWriteCount : 0x0 [Type: unsigned long]
[+0x050] WaitList : 0x0 [Type: _MI_CONTROL_AREA_WAIT_BLOCK *]
[+0x058] u2 [Type: <unnamed-tag>]
[+0x068] FileObjectLock [Type: _EX_PUSH_LOCK]
[+0x070] LockedPages : 0x1 [Type: unsigned __int64]
[+0x078] u3 [Type: <unnamed-tag>]
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_EX_FAST_REF *)0xffffdf02e4534820))
(*((ntkrnlmp!_EX_FAST_REF *)0xffffdf02e4534820)) [Type: _EX_FAST_REF]
[+0x000] Object : 0xffffdf02e458a36d [Type: void *]
[+0x000 ( 3: 0)] RefCnt : 0xd [Type: unsigned __int64]
[+0x000] Value : 0xffffdf02e458a36d [Type: unsigned __int64]
Object의 마지막 1바이트를 0으로 변경하면 _FILE_OBJECT 구조체에 대한 주소입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_EX_FAST_REF *)0xffffdf02e4534820))
(*((ntkrnlmp!_EX_FAST_REF *)0xffffdf02e4534820)) [Type: _EX_FAST_REF]
[+0x000] Object : 0xffffdf02e458a36d [Type: void *]
[+0x000 ( 3: 0)] RefCnt : 0xd [Type: unsigned __int64]
[+0x000] Value : 0xffffdf02e458a36d [Type: unsigned __int64]
14: kd> dt_file_object 0xffffdf02e458a360
nt!_FILE_OBJECT
+0x000 Type : 0n5
+0x002 Size : 0n216
+0x008 DeviceObject : 0xffffdf02`dbe0cb00 _DEVICE_OBJECT
+0x010 Vpb : 0xffffdf02`dbdf2d80 _VPB
+0x018 FsContext : 0xffffc789`91a04170 Void
+0x020 FsContext2 : 0xffffc789`91a043e8 Void
+0x028 SectionObjectPointer : 0xffffdf02`e43c35e8 _SECTION_OBJECT_POINTERS
+0x030 PrivateCacheMap : (null)
+0x038 FinalStatus : 0n0
+0x040 RelatedFileObject : (null)
+0x048 LockOperation : 0 ''
+0x049 DeletePending : 0 ''
+0x04a ReadAccess : 0x1 ''
+0x04b WriteAccess : 0 ''
+0x04c DeleteAccess : 0 ''
+0x04d SharedRead : 0x1 ''
+0x04e SharedWrite : 0 ''
+0x04f SharedDelete : 0x1 ''
+0x050 Flags : 0x44442
+0x058 FileName : _UNICODE_STRING "\Windows\System32\dwm.exe"
+0x068 CurrentByteOffset : _LARGE_INTEGER 0x0
+0x070 Waiters : 0
+0x074 Busy : 0
+0x078 LastLock : (null)
+0x080 Lock : _KEVENT
+0x098 Event : _KEVENT
+0x0b0 CompletionContext : (null)
+0x0b8 IrpListLock : 0
+0x0c0 IrpList : _LIST_ENTRY [ 0xffffdf02`e458a420 - 0xffffdf02`e458a420 ]
+0x0d0 FileObjectExtension : (null)
해당 오브젝트 정보를 통해, 다음과 같이 매핑된 파일의 경로를 확인할 수 있습니다.
1
2
3
4
5
14: kd> dx -id 0,0,ffffdf02ec514080 -r1 (*((ntkrnlmp!_UNICODE_STRING *)0xffffdf02e458a3b8))
(*((ntkrnlmp!_UNICODE_STRING *)0xffffdf02e458a3b8)) : "\Windows\System32\dwm.exe" [Type: _UNICODE_STRING]
[+0x000] Length : 0x32 [Type: unsigned short]
[+0x002] MaximumLength : 0x38 [Type: unsigned short]
[+0x008] Buffer : 0xffffc7899164cd70 : "\Windows\System32\dwm.exe" [Type: wchar_t *]
!vad 명령을 통해 확인한 파일 경로와 일치합니다.
1
2
3
14: kd> !vad
VAD Level Start End Commit
ffffdf02ef07aba0 9 7ff763e90 7ff763eb0 7 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\dwm.exe
Commands
windbg에서는 다음과 같은 명령어를 통해 VAD 정보를 확인할 수 있습니다.
!vad
!vad는 VAD 트리의 세부 정보를 표시합니다.
가상 주소 및 범위, 페이지 보호 속성, 파일 경로 등을 표시합니다.
1
2
3
4
5
6
7
8
9
10
11
14: kd> !vad
VAD Level Start End Commit
ffffdf02ef26f440 8 7ffe0 7ffe0 1 Private READONLY
ffffdf02ef26f210 7 7ffed 7ffed 1 Private READONLY
ffffdf02ef07aba0 9 7ff763e90 7ff763eb0 7 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\dwm.exe
ffffdf02ed9669c0 8 7ffc715d0 7ffc719cb 38 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_07f8715d556090a8\igd11dxva64.dll
ffffdf02ed9828a0 10 7ffc8a2c0 7ffc8bfea 7 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_07f8715d556090a8\media_bin_64.dll
ffffdf02f0276d40 9 7ffc8bff0 7ffc8d38e 2041 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\DriverStore\FileRepository\iigd_dch.inf_amd64_07f8715d556090a8\igddxvacommon64.dll
ffffdf02e45b7390 10 7ffc9d5d0 7ffc9e7f5 26 Mapped Exe EXECUTE_WRITECOPY \Windows\System32\Windows.UI.Xaml.dll
...
Total VADs: 669, average level: 8, maximum depth: 10
!vad_reload
현재 프로세스의 VAD를 통해 사용자 모듈을 다시 로드합니다.
전체 메모리 덤프에서 모듈 정보가 일치하지 않는 경우, 해당 명령을 통해 다시 로드합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3: kd> !process 0 0
. . .
PROCESS fffffa8007d54450
SessionId: 1 Cid: 115c Peb: 7ffffef6000 ParentCid: 0c58
DirBase: 111bc3000 ObjectTable: fffff8a006ae0960 HandleCount: 229.
Image: SearchProtocolHost.exe
. . .
3: kd> !vad_reload fffffa8007d54450
fffffa80`04f5e8b0: VAD maps 00000000`6c230000 - 00000000`6c26bfff, file cscobj.dll
fffffa80`04e8f890: VAD maps 00000000`6ef90000 - 00000000`6f04afff, file mssvp.dll
fffffa80`07cbb010: VAD maps 00000000`6f910000 - 00000000`6faf5fff, file tquery.dll
fffffa80`08c1f2a0: VAD maps 00000000`6fb80000 - 00000000`6fb9bfff, file mssprxy.dll
fffffa80`07dce8b0: VAD maps 00000000`6fba0000 - 00000000`6fba7fff, file msshooks.dll
fffffa80`04fd2e70: VAD maps 00000000`72a50000 - 00000000`72a6cfff, file userenv.dll
. . .
References
- Windows Internals, 7th edition Part 1
- https://en.wikipedia.org/wiki/AVL_tree
- https://imphash.medium.com/windows-process-internals-a-few-concepts-to-know-before-jumping-on-memory-forensics-part-4-16c47b89e826
- https://learn.microsoft.com/ko-kr/windows-hardware/drivers/debuggercmds/-vad
- https://learn.microsoft.com/ko-kr/windows-hardware/drivers/debuggercmds/-vad-reload
- https://www.unknowncheats.me/forum/anti-cheat-bypass/523104-22h2-_mmvad_short-struct.html