Author : Souhail Hammou -  https://rce4fun.blogspot.com/  -  Twitter

OS      : Windows 10 (64-bit)

Tag

Type

VAD allocation routine

Flags at initialization

(LongFlags field)

Pool type

Comment

VadF

MMVAD_SHORT

or

MMVAD

MiDeletePartialVad

Variable

NonPagedPoolNx

The VadF node is copied from a source VAD. It is nothing but a temporary storage for the node to be deleted. The pool allocation isn't returned and is always freed.

VadI

[1]

MiAllocateFixupVad

Variable

NonPagedPoolNx

The fields are copied from a source VAD.

MMVAD_SHORT

or

MMVAD

MiAllocateChildVads

Vad

MMVAD

MiMapViewOfDataSection

VadType = 0

PrivateMemory = 0

NonPagedPoolNx

-

MiMapViewOfImageSection

VadType = 2

PrivateMemory = 0

VadS

MMVAD_SHORT

MiAllocateVirtualMemory

VadType = 0

PrivateMemory = 1

NonPagedPoolNx

-

MiAllocateVad

Vadl

MMVAD_SHORT

or

MMVAD

MiAllocateChildVads

Variable

NonPagedPoolNx

The fields are copied from a source VAD node.

MMVAD

MiMapLockedPagesInUserSpace

VadType = 0x1

PrivateMemory = 1

NonPagedPoolNx

Allocated as an MMVAD structure but only the MMVAD_SHORT fields seem to be used (!)

MiUnmapLockedPagesInUserSpace is responsible for deleting the Vadl node

VadL

[2]

MiResizeAweBitMap

-

PagedPool

The VadL VAD nodes are inserted in a special AVL tree (Process->AweInfo.AweVadRoot).

New nodes are inserted by MiAweViewInserter.

VadE

MMVAD_SHORT + 0x20

MiAllocateEnclaveVad

VadType = 0x3

PrivateMemory = 1

Enclave = 1

NonPagedPoolNx

About the additional 32 bytes : "This type of VAD is a little different than the usual Short or Long VADs described in Windows Internals it contains a system PTE as well as the array of PFN entries that correspond to the underlying EPC pages associated with the enclave." [3]

The extra elements are in fact of size 0x1C, but in order for the structure to be aligned properly an additional double-word is appended.

[1] :

TotalNumOfPtes = Vad->Subsection->ControlArea->Segment->TotalNumberOfPtes;

NumberOfBytes = ( TotalNumOfPtes/64 + ((TotalNumOfPtes & 0x3F) != 0))*8 + 0xA0;

ExAllocatePoolWithTag(NonPagedPoolNx, NumberOfBytes, 'ldaV');

[2] : The pool allocation part of MiResizeAweBitMap :

PEPROCESS CurrentProcess = PsGetCurrentProcess();

PMI_PARTITION ProcessPartition = MiGetProcessPartition(CurrentProcess);

UINT64 HiPhysPage = ProcessPartition->Vp.HighestPhysicalPage;

if ( CurrentProcess->Wow64Process )

{

if ( HiPhysPage + 1 > 0x100000000 )

                    HiPhysPage = 0xFFFFFFFF

}

NumberOfBytes = ((HiPhysPage + 1)/64 + (((HiPhysPage + 1) & 0x3F) != 0 ))*8;

ExAllocatePoolWithTag(PagedPool,NumberOfBytes,'LdaV');

[...]

[3] : Description taken from Alex Ionescu's Whitepaper: https://goo.gl/qDmPrL. The reverse-engineered structure, in the same paper, named MMVAD_ENCLAVE is defined this way :

typedef struct _MMVAD_ENCLAVE

{

MMVAD_SHORT Core;

PMMPTE SecsSystemPte;

PMMPFN EnclavePfnArray;

ULONGLONG EnclavePfnCount;

struct

{

ULONG Initialized:1;

ULONG Debuggable:1;

};

} MMVAD_ENCLAVE, *PMMVAD_ENCLAVE;