You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
402 lines
13 KiB
402 lines
13 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
vad.c
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Lou Perazzoli (loup) 12-Jun-1992
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
CHAR *ProtectString[] = {
|
|
"NO_ACCESS",
|
|
"READONLY",
|
|
"EXECUTE",
|
|
"EXECUTE_READ",
|
|
"READWRITE",
|
|
"WRITECOPY",
|
|
"EXECUTE_READWRITE",
|
|
"EXECUTE_WRITECOPY"
|
|
};
|
|
|
|
|
|
DECLARE_API( vad )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps all vads for process.
|
|
|
|
Arguments:
|
|
|
|
args - Address Flags
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG64 Next;
|
|
ULONG64 VadToDump;
|
|
ULONG64 ParentStored;
|
|
ULONG64 First;
|
|
ULONG64 Left;
|
|
ULONG64 Prev;
|
|
ULONG Flags;
|
|
ULONG Done;
|
|
ULONG Level = 0;
|
|
ULONG Count = 0;
|
|
ULONG AverageLevel = 0;
|
|
ULONG MaxLevel = 0;
|
|
ULONG VadFlagsPrivateMemory=0, VadFlagsNoChange=0;
|
|
ULONG PhysicalMapping=0,ImageMap=0,NoChange=0,LargePages=0,MemCommit=0,PrivateMemory=0,Protection=0;
|
|
ULONG64 StartingVpn=0, EndingVpn=0, Parent=0, LeftChild=0, RightChild=0;
|
|
ULONG64 ControlArea=0, FirstPrototypePte=0, LastContiguousPte=0, CommitCharge=0;
|
|
|
|
VadToDump = 0;
|
|
Flags = 0;
|
|
|
|
if (GetExpressionEx(args, &VadToDump, &args)) {
|
|
Flags = (ULONG) GetExpression(args);
|
|
}
|
|
|
|
if (VadToDump == 0) {
|
|
dprintf("Specify the address of a VAD within the VAD tree\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
First = VadToDump;
|
|
if (First == 0) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
#define ReadFirstVad(fld, var) GetFieldValue(First, (PUCHAR) "nt!_MMVAD", #fld, var)
|
|
#define ReadFirstVadShort(fld, var) GetFieldValue(First, (PUCHAR) "nt!_MMVAD_SHORT", #fld, var)
|
|
|
|
if ( ReadFirstVadShort(u.VadFlags.PrivateMemory, VadFlagsPrivateMemory) ) {
|
|
dprintf("%08p: Unable to get contents of VAD1\n",First );
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
ReadFirstVadShort(u.VadFlags.NoChange, VadFlagsNoChange);
|
|
ReadFirstVadShort(StartingVpn, StartingVpn);
|
|
ReadFirstVadShort(EndingVpn, EndingVpn);
|
|
|
|
if (ReadFirstVadShort(Parent, Parent)) {
|
|
ReadFirstVadShort(u1.Parent, Parent);
|
|
}
|
|
|
|
ReadFirstVadShort(LeftChild, LeftChild);
|
|
ReadFirstVadShort(RightChild, RightChild);
|
|
ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge);
|
|
|
|
if (Flags == 1) {
|
|
ULONG FileOffset=0;
|
|
ULONG64 ListFlink=0, ListBlink=0, Banked=0;
|
|
ULONG CopyOnWrite=0,Inherit=0,ExtendableFile=0,SecNoChange=0;
|
|
ULONG OneSecured=0,MultipleSecured=0,ReadOnly=0,StoredInVad=0;
|
|
|
|
//
|
|
// Dump only this vad.
|
|
//
|
|
|
|
if ((VadFlagsPrivateMemory == 0) ||
|
|
(VadFlagsNoChange == 1)) {
|
|
if ( ReadFirstVad(ControlArea, ControlArea) ) {
|
|
dprintf("%08p: Unable to get contents of VAD2\n",First );
|
|
return E_INVALIDARG;
|
|
}
|
|
ReadFirstVad(FirstPrototypePte, FirstPrototypePte);
|
|
ReadFirstVad(LastContiguousPte, LastContiguousPte);
|
|
ReadFirstVad(u2.VadFlags2.CopyOnWrite, CopyOnWrite);
|
|
ReadFirstVad(u2.VadFlags2.Inherit, Inherit);
|
|
ReadFirstVad(u2.VadFlags2.ExtendableFile, ExtendableFile);
|
|
ReadFirstVad(u2.VadFlags2.SecNoChange, SecNoChange);
|
|
ReadFirstVad(u2.VadFlags2.OneSecured, OneSecured);
|
|
ReadFirstVad(u2.VadFlags2.MultipleSecured, MultipleSecured);
|
|
ReadFirstVad(u2.VadFlags2.ReadOnly, ReadOnly);
|
|
ReadFirstVad(u2.VadFlags2.StoredInVad, StoredInVad);
|
|
ReadFirstVad(u2.VadFlags2.FileOffset, FileOffset);
|
|
ReadFirstVad(u3.List.Flink, ListFlink);
|
|
ReadFirstVad(u3.List.Blink, ListBlink);
|
|
ReadFirstVad(u4.Banked, Banked);
|
|
}
|
|
|
|
ReadFirstVad(u.VadFlags.CommitCharge, CommitCharge);
|
|
ReadFirstVad(u.VadFlags.PhysicalMapping, PhysicalMapping);
|
|
ReadFirstVad(u.VadFlags.ImageMap, ImageMap);
|
|
ReadFirstVad(u.VadFlags.Protection, Protection);
|
|
ReadFirstVad(u.VadFlags.NoChange, NoChange);
|
|
ReadFirstVad(u.VadFlags.LargePages, LargePages);
|
|
ReadFirstVad(u.VadFlags.MemCommit, MemCommit);
|
|
ReadFirstVad(u.VadFlags.PrivateMemory, PrivateMemory);
|
|
|
|
dprintf("\nVAD @ %8p\n",VadToDump);
|
|
dprintf(" Start VPN: %8p End VPN: %8p Control Area: %8p\n",
|
|
StartingVpn,
|
|
EndingVpn,
|
|
ControlArea);
|
|
dprintf(" First ProtoPte: %8p Last PTE %8p Commit Charge %8lx (%ld.)\n",
|
|
FirstPrototypePte,
|
|
LastContiguousPte,
|
|
(ULONG)CommitCharge,
|
|
(ULONG)CommitCharge
|
|
);
|
|
dprintf(" Secured.Flink %8p Blink %8p Banked/Extend: %8p Offset %lx\n",
|
|
ListFlink,
|
|
ListBlink,
|
|
Banked,
|
|
FileOffset);
|
|
|
|
dprintf(" ");
|
|
|
|
if (PhysicalMapping) { dprintf("PhysicalMapping "); }
|
|
if (ImageMap) { dprintf("ImageMap "); }
|
|
Inherit ? dprintf("ViewShare ") : dprintf("ViewUnmap ");
|
|
if (NoChange) { dprintf("NoChange "); }
|
|
if (CopyOnWrite) { dprintf("CopyOnWrite "); }
|
|
if (LargePages) { dprintf("LargePages "); }
|
|
if (MemCommit) { dprintf("MemCommit "); }
|
|
if (PrivateMemory) { dprintf("PrivateMemory "); }
|
|
dprintf ("%s\n\n",ProtectString[Protection & 7]);
|
|
|
|
if (ExtendableFile) { dprintf("ExtendableFile "); }
|
|
if (SecNoChange) { dprintf("SecNoChange "); }
|
|
if (OneSecured) { dprintf("OneSecured "); }
|
|
if (MultipleSecured) { dprintf("MultipleSecured "); }
|
|
if (ReadOnly) { dprintf("ReadOnly "); }
|
|
if (StoredInVad) { dprintf("StoredInVad "); }
|
|
dprintf ("\n\n");
|
|
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
Prev = First;
|
|
|
|
while (LeftChild != 0) {
|
|
if ( CheckControlC() ) {
|
|
return E_INVALIDARG;
|
|
}
|
|
Prev = First;
|
|
First = LeftChild;
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
|
|
if (Flags & 2) {
|
|
dprintf("Reading LeftChild VAD %08p\n",First );
|
|
}
|
|
|
|
if ( ReadFirstVadShort(LeftChild, LeftChild) ) {
|
|
dprintf("%08p %08p: Unable to get contents of VAD3\n", First, Prev);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
ReadFirstVadShort(StartingVpn, StartingVpn);
|
|
ReadFirstVadShort(EndingVpn, EndingVpn);
|
|
|
|
if (ReadFirstVadShort(Parent, Parent)) {
|
|
ReadFirstVadShort(u1.Parent, Parent);
|
|
Parent &= ~0x3;
|
|
}
|
|
|
|
ReadFirstVadShort(RightChild, RightChild);
|
|
ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge);
|
|
ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory);
|
|
ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping);
|
|
ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap);
|
|
ReadFirstVadShort(u.VadFlags.Protection, Protection);
|
|
|
|
|
|
dprintf("VAD level start end commit\n");
|
|
dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n",
|
|
First,
|
|
Level,
|
|
StartingVpn,
|
|
EndingVpn,
|
|
(ULONG)CommitCharge,
|
|
PrivateMemory ? "Private" : "Mapped ",
|
|
ImageMap ? "Exe " :
|
|
PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[Protection & 7]
|
|
);
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
|
|
Next = First;
|
|
while (Next != 0) {
|
|
|
|
if ( CheckControlC() ) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (RightChild == 0) {
|
|
|
|
Done = TRUE;
|
|
|
|
//
|
|
// Pre-AVL vad trees were delimited by a parent pointer of NULL.
|
|
//
|
|
|
|
while ((ParentStored = Parent) != 0) {
|
|
|
|
if ( CheckControlC() ) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
Level -= 1;
|
|
|
|
//
|
|
// Locate the first ancestor of this node of which this
|
|
// node is the left child of and return that node as the
|
|
// next element.
|
|
//
|
|
|
|
First = ParentStored & ~0x3;
|
|
if ( ReadFirstVadShort( LeftChild, LeftChild) ||
|
|
(ReadFirstVadShort(Parent, Parent) &&
|
|
ReadFirstVadShort(u1.Parent, Parent)) ) {
|
|
dprintf("%08p %08p: Unable to get contents of VAD4\n",Parent, Prev);
|
|
return E_INVALIDARG;
|
|
}
|
|
Parent &= ~0x3;
|
|
|
|
//
|
|
// AVL vad trees are delimited by a parent pointer that equals
|
|
// the current vad so check for that explicitly here so that
|
|
// this same extension can work on both types of kernels.
|
|
//
|
|
|
|
if (Parent == First) {
|
|
break;
|
|
}
|
|
|
|
Prev = First;
|
|
|
|
ReadFirstVadShort(StartingVpn, StartingVpn);
|
|
ReadFirstVadShort(EndingVpn, EndingVpn);
|
|
ReadFirstVadShort(RightChild, RightChild);
|
|
ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge);
|
|
ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory);
|
|
ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping);
|
|
ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap);
|
|
ReadFirstVadShort(u.VadFlags.Protection, Protection);
|
|
|
|
if (LeftChild == Next) {
|
|
Next = ParentStored;
|
|
|
|
dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n",
|
|
Next,
|
|
Level,
|
|
StartingVpn,
|
|
EndingVpn,
|
|
(ULONG)CommitCharge,
|
|
PrivateMemory ? "Private" : "Mapped ",
|
|
ImageMap ? "Exe " :
|
|
PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[Protection & 7]
|
|
);
|
|
Done = FALSE;
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
break;
|
|
}
|
|
Next = ParentStored;
|
|
}
|
|
if (Done) {
|
|
Next = 0;
|
|
break;
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// A right child exists, locate the left most child of that right child.
|
|
//
|
|
|
|
Next = RightChild;
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
|
|
First = Next;
|
|
|
|
if ( ReadFirstVadShort(LeftChild, LeftChild) ) {
|
|
dprintf("%08p %08p: Unable to get contents of VAD5\n",Next, Prev);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
while ((Left = LeftChild) != 0) {
|
|
if ( CheckControlC() ) {
|
|
return E_INVALIDARG;
|
|
}
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
Next = Left;
|
|
First = Next;
|
|
if ( ReadFirstVadShort(LeftChild, LeftChild) ) {
|
|
dprintf("%08p %08p: Unable to get contents of VAD6\n",Next, Prev);
|
|
return E_INVALIDARG;
|
|
}
|
|
Prev = First;
|
|
}
|
|
|
|
ReadFirstVadShort(StartingVpn, StartingVpn);
|
|
ReadFirstVadShort(EndingVpn, EndingVpn);
|
|
if (ReadFirstVadShort(Parent, Parent)) {
|
|
ReadFirstVadShort(u1.Parent, Parent);
|
|
Parent &= ~0x3;
|
|
}
|
|
ReadFirstVadShort(RightChild, RightChild);
|
|
ReadFirstVadShort(u.VadFlags.CommitCharge, CommitCharge);
|
|
ReadFirstVadShort(u.VadFlags.PrivateMemory, PrivateMemory);
|
|
ReadFirstVadShort(u.VadFlags.PhysicalMapping, PhysicalMapping);
|
|
ReadFirstVadShort(u.VadFlags.ImageMap, ImageMap);
|
|
ReadFirstVadShort(u.VadFlags.Protection, Protection);
|
|
|
|
dprintf("%p (%2ld) %8p %8p %4ld %s %s %s\n",
|
|
Next,
|
|
Level,
|
|
StartingVpn,
|
|
EndingVpn,
|
|
(ULONG)CommitCharge,
|
|
PrivateMemory ? "Private" : "Mapped ",
|
|
ImageMap ? "Exe " :
|
|
PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[Protection & 7]
|
|
);
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
}
|
|
}
|
|
dprintf("\nTotal VADs: %5ld average level: %4ld maximum depth: %ld\n",
|
|
Count, 1+(AverageLevel/Count),MaxLevel);
|
|
|
|
#undef ReadFirstVad
|
|
|
|
return S_OK;
|
|
}
|