mirror of https://github.com/lianthony/NT4.0
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.
300 lines
9.0 KiB
300 lines
9.0 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:
|
|
|
|
Converted to WinDbg extension:
|
|
Ramon J San Andres (ramonsa) 8-Nov-1993
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
UCHAR *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
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Result;
|
|
PMMVAD Next;
|
|
PMMVAD VadToDump;
|
|
PMMVAD Parent;
|
|
PMMVAD First;
|
|
PMMVAD Left;
|
|
MMVAD CurrentVad;
|
|
ULONG Flags;
|
|
ULONG Done;
|
|
ULONG Level = 0;
|
|
ULONG Count = 0;
|
|
ULONG AverageLevel = 0;
|
|
ULONG MaxLevel = 0;
|
|
|
|
VadToDump = (PMMVAD)0xFFFFFFFF;
|
|
Flags = 0;
|
|
sscanf(args,"%lx %lx",&VadToDump,&Flags);
|
|
if (VadToDump == (PVOID)0xFFFFFFFF) {
|
|
dprintf("Specify the address of a VAD within the VAD tree\n");
|
|
return;
|
|
}
|
|
|
|
First = VadToDump;
|
|
if (First == (PMMVAD)NULL) {
|
|
return;
|
|
}
|
|
|
|
RtlZeroMemory (&CurrentVad, sizeof(MMVAD));
|
|
|
|
if ( !ReadMemory( (DWORD)First,
|
|
&CurrentVad,
|
|
sizeof(MMVAD_SHORT),
|
|
&Result) ) {
|
|
dprintf("%08lx: Unable to get contents of VAD\n",First );
|
|
return;
|
|
}
|
|
|
|
if (Flags) {
|
|
|
|
//
|
|
// Dump only this vad.
|
|
//
|
|
|
|
if ((CurrentVad.u.VadFlags.PrivateMemory == 0) ||
|
|
(CurrentVad.u.VadFlags.NoChange == 1)) {
|
|
if ( !ReadMemory( (DWORD)First,
|
|
&CurrentVad,
|
|
sizeof(MMVAD),
|
|
&Result) ) {
|
|
dprintf("%08lx: Unable to get contents of VAD\n",First );
|
|
return;
|
|
}
|
|
}
|
|
|
|
dprintf("\nVAD @ %8lx\n",VadToDump);
|
|
dprintf(" Start VA: %8lx End VA: %8lx Control Area: %8lx\n",
|
|
CurrentVad.StartingVa,
|
|
CurrentVad.EndingVa,
|
|
CurrentVad.ControlArea);
|
|
dprintf(" First ProtoPte: %8lx Last PTE %8lx Commit Charge %8lx (%ld.)\n",
|
|
CurrentVad.FirstPrototypePte,
|
|
CurrentVad.LastContiguousPte,
|
|
CurrentVad.u.VadFlags.CommitCharge,
|
|
CurrentVad.u.VadFlags.CommitCharge
|
|
);
|
|
dprintf(" Secured.Flink %8lx Blink %8lx Banked: %8lx\n",
|
|
CurrentVad.u3.List.Flink,
|
|
CurrentVad.u3.List.Blink,
|
|
CurrentVad.Banked);
|
|
|
|
dprintf(" ");
|
|
if (CurrentVad.u.VadFlags.PhysicalMapping) { dprintf("PhysicalMapping "); }
|
|
if (CurrentVad.u.VadFlags.ImageMap) { dprintf("ImageMap "); }
|
|
CurrentVad.u.VadFlags.Inherit ? dprintf("ViewShare ") : dprintf("ViewUnmap ");
|
|
if (CurrentVad.u.VadFlags.NoChange) { dprintf("NoChange "); }
|
|
if (CurrentVad.u.VadFlags.CopyOnWrite) { dprintf("CopyOnWrite "); }
|
|
if (CurrentVad.u.VadFlags.LargePages) { dprintf("LargePages "); }
|
|
if (CurrentVad.u.VadFlags.MemCommit) { dprintf("MemCommit "); }
|
|
if (CurrentVad.u.VadFlags.PrivateMemory) { dprintf("PrivateMemory "); }
|
|
dprintf ("%s\n\n",ProtectString[CurrentVad.u.VadFlags.Protection & 7]);
|
|
|
|
if (CurrentVad.u2.VadFlags2.SecNoChange) { dprintf("SecNoChange "); }
|
|
if (CurrentVad.u2.VadFlags2.OneSecured) { dprintf("OneSecured "); }
|
|
if (CurrentVad.u2.VadFlags2.MultipleSecured) { dprintf("MultipleSecured "); }
|
|
if (CurrentVad.u2.VadFlags2.ReadOnly) { dprintf("ReadOnly "); }
|
|
if (CurrentVad.u2.VadFlags2.StoredInVad) { dprintf("StoredInVad "); }
|
|
dprintf ("\n\n");
|
|
|
|
return;
|
|
}
|
|
|
|
while (CurrentVad.LeftChild != (PMMVAD)NULL) {
|
|
if ( CheckControlC() ) {
|
|
return;
|
|
}
|
|
First = CurrentVad.LeftChild;
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
if ( !ReadMemory( (DWORD)First,
|
|
&CurrentVad,
|
|
sizeof(MMVAD_SHORT),
|
|
&Result) ) {
|
|
dprintf("%08lx:%lx Unable to get contents of VAD\n",First, CurrentVad );
|
|
return;
|
|
}
|
|
}
|
|
|
|
dprintf("VAD level start end commit\n");
|
|
dprintf("%lx (%2ld) %8lx %8lx %4ld %s %s %s\n",
|
|
First,
|
|
Level,
|
|
CurrentVad.StartingVa,
|
|
CurrentVad.EndingVa,
|
|
CurrentVad.u.VadFlags.CommitCharge,
|
|
CurrentVad.u.VadFlags.PrivateMemory ? "Private" : "Mapped ",
|
|
CurrentVad.u.VadFlags.ImageMap ? "Exe " :
|
|
CurrentVad.u.VadFlags.PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[CurrentVad.u.VadFlags.Protection & 7]
|
|
);
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
|
|
Next = First;
|
|
while (Next != NULL) {
|
|
|
|
if ( CheckControlC() ) {
|
|
return;
|
|
}
|
|
|
|
if (CurrentVad.RightChild == (PMMVAD)NULL) {
|
|
|
|
Done = TRUE;
|
|
while ((Parent = CurrentVad.Parent) != (PMMVAD)NULL) {
|
|
if ( CheckControlC() ) {
|
|
return;
|
|
}
|
|
|
|
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.
|
|
//
|
|
|
|
if ( !ReadMemory( (DWORD)Parent,
|
|
&CurrentVad,
|
|
sizeof(MMVAD_SHORT),
|
|
&Result) ) {
|
|
dprintf("%08lx:%lx Unable to get contents of VAD\n",Parent, CurrentVad);
|
|
return;
|
|
}
|
|
|
|
if (CurrentVad.LeftChild == Next) {
|
|
Next = Parent;
|
|
dprintf("%lx (%2ld) %8lx %8lx %4ld %s %s %s\n",
|
|
Next,
|
|
Level,
|
|
CurrentVad.StartingVa,
|
|
CurrentVad.EndingVa,
|
|
CurrentVad.u.VadFlags.CommitCharge,
|
|
CurrentVad.u.VadFlags.PrivateMemory ? "Private" : "Mapped ",
|
|
CurrentVad.u.VadFlags.ImageMap ? "Exe " :
|
|
CurrentVad.u.VadFlags.PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[CurrentVad.u.VadFlags.Protection & 7]
|
|
);
|
|
Done = FALSE;
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
break;
|
|
}
|
|
Next = Parent;
|
|
}
|
|
if (Done) {
|
|
Next = NULL;
|
|
break;
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// A right child exists, locate the left most child of that right child.
|
|
//
|
|
|
|
Next = CurrentVad.RightChild;
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
|
|
if ( !ReadMemory( (DWORD)Next,
|
|
&CurrentVad,
|
|
sizeof(MMVAD_SHORT),
|
|
&Result) ) {
|
|
dprintf("%08lx:%lx Unable to get contents of VAD\n",Next, CurrentVad);
|
|
return;
|
|
}
|
|
|
|
while ((Left = CurrentVad.LeftChild) != (PMMVAD)NULL) {
|
|
if ( CheckControlC() ) {
|
|
return;
|
|
}
|
|
Level += 1;
|
|
if (Level > MaxLevel) {
|
|
MaxLevel = Level;
|
|
}
|
|
Next = Left;
|
|
if ( !ReadMemory( (DWORD)Next,
|
|
&CurrentVad,
|
|
sizeof(MMVAD_SHORT),
|
|
&Result) ) {
|
|
dprintf("%08lx:%lx Unable to get contents of VAD\n",Next, CurrentVad);
|
|
return;
|
|
}
|
|
}
|
|
|
|
dprintf("%lx (%2ld) %8lx %8lx %4ld %s %s %s\n",
|
|
Next,
|
|
Level,
|
|
CurrentVad.StartingVa,
|
|
CurrentVad.EndingVa,
|
|
CurrentVad.u.VadFlags.CommitCharge,
|
|
CurrentVad.u.VadFlags.PrivateMemory ? "Private" : "Mapped ",
|
|
CurrentVad.u.VadFlags.ImageMap ? "Exe " :
|
|
CurrentVad.u.VadFlags.PhysicalMapping ? "Phys" : " ",
|
|
ProtectString[CurrentVad.u.VadFlags.Protection & 7]
|
|
);
|
|
Count += 1;
|
|
AverageLevel += Level;
|
|
}
|
|
}
|
|
dprintf("\nTotal VADs: %5ld average level: %4ld maximum depth: %ld\n",
|
|
Count, 1+(AverageLevel/Count),MaxLevel);
|
|
return;
|
|
}
|