For inclusion in Win2kIntrnls.inc :

VAD struct
StartingAddress dd ?
EndingAddress dd ?
ParentLink dd ?
LeftLink dd ?
RightLink dd ?
Flags dd ?
VAD ends

Unfortunately have no clue about the meaning of bits in the 'flags' dword.
Posted on 2001-12-23 09:04:50 by jmp $FCE2
The struct u've posted is not correct/complete, at least for versions >= win2k.
i guess u've read it in Pdabak's book (btw i do not like that book too much....u know ;) ) it's only "valid" for NT4.

I'm reversing win2k ntoskrnl for quite a while now (well to be precise "i was" since i'm too busy atm :( ) : a good source of VAD infos are windbg helper dlls, expecially when running under checked versions; try to reverse commands likes !vad !ca , then check MixxxxVad functions and all should be "clear"... even if the win2k MM is a quite complex/convoluted beast!
well here a barely dump from my idb, hope it'll help u..

side note : in XP some changes are occurred but i've not checked yet.

Merry XMAS,

kill3xx


VAD struct ; // process virtual address space struct
RangeEnd dd ? ; // RangeStart & RangeEnd are expressed as page indexes
Parent dd ?
Left dd ?
Right dd ?
PagesAttributes dd ? ; // 31 30 29...0
; // Type Prot Commit
ControlArea dd ? ; // ptr to control area for Vads related to a section/segment
FirstProtoPte dd ? ; // first and last PPTE entries in the proto PD array
LastProtoPte dd ?
SecAttributes dd ? ; // security masks remaps SEC_xxxx SECTION_xxxx
Secured LIST_ENTRY ?
BankedExtend dd ? ; // ptr to a banked section/segment descriptor
struc_80 ends


; enum PAGES_PROTECTION
PAGE_NOACCESS = 0
PAGE_READONLY = 1000000h
PAGE_EXECUTE = 2000000h
PAGE_EXECUTE_READ = 3000000h
PAGE_READWRITE = 4000000h
PAGE_WRITECOPY = 5000000h
PAGE_EXEC_READWRITE = 6000000h
PAGE_EXEC_WRITECOPY = 7000000h
; ---------------------------------------------------------------------------
; enum SECTION_PROTECTION (bitfield)
SEC_PAGE_NOACCESS = 1
SEC_PAGE_READONLY = 2
SEC_PAGE_READWRITE = 4
SEC_PAGE_WRITECOPY = 8
SEC_PAGE_EXECUTE = 10h
SEC_PAGE_EXECUTE_READ = 20h
SEC_PAGE_EXECUTE_READWRITE = 40h
SEC_PAGE_EXECUTE_WRITECOPY = 80h
SEC_PAGE_GUARD = 100h
SEC_PAGE_NOCACHE = 200h
SEC_PAGE_WRITECOMBINE = 400h
; ---------------------------------------------------------------------------
; remap CreateFileMapping (SEC_xxx) attributes, protections (SECTION_xxx)
; enum VAD_SEC_FLAGS (bitfield)
VAD_SEC_NOCHANGE = 1000000h
VAD_SEC_SINGLE = 2000000h
VAD_SEC_MULTIPLE = 4000000h
VAD_SEC_READONLY = 8000000h
VAD_SEC_STORED = 10000000h
VAD_SEC_FILE = 20000000h
VAD_SEC_IMAGE = 40000000h
VAD_SEC_COW = 80000000h
; ---------------------------------------------------------------------------
; enum VAD_PAGE_FLAGS (bitfield)
VAD_RESERVE = 7FFFFh
VAD_PHYSICAL = 80000h
VAD_IMAGE = 100000h
VAD_NOCHANGE = 400000h
VAD_NOACCESS = 0
VAD_READONLY = 1000000h
VAD_EXECUTE = 2000000h
VAD_EXECUTE_READ = 3000000h
VAD_READWRITE = 4000000h
VAD_EXEC_READWRITE = 6000000h
VAD_EXEC_WRITECOPY = 7000000h
VAD_4M_PAGES = 20000000h
VAD_COMMIT = 40000000h
VAD_PRIVATE = 80000000h
; ---------------------------------------------------------------------------
; enum VAD_INFO_MASKS
VAD_COMMIT_MASK = 7FFFFh
VAD_TYPE_MASK = 0E0FFFFFFh
VAD_TYPEPROT_MASK = 0FFF80000h
Posted on 2001-12-24 10:06:09 by kill3xx
Yes, I took the struct from Undocumented Windows NT, the edition I have covers W2K Beta releases at least. Internal Windows NT is very new to me and this book gave me a good starting point. Well, I have never before written a kernel driver or bothered to even think about NT internal structures. So one might say I'm a complete newbi :grin:

Nevertheless, thanks alot for your valuable information !

I had a problem to figure out whether a given linear address points to a valid region of memory that is at least accessible via 'read'. First I wanted to examine the protection bits given for a particular VAD, but then I got around to use MmIsAddressValid which does just what I need.

Merry Xmas :alright:
Posted on 2001-12-24 10:58:52 by jmp $FCE2