731 lines
22 KiB
C
731 lines
22 KiB
C
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wsle.c
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Lou Perazzoli (LouP) 14-Mar-1994
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#define PACKET_MAX_SIZE 4000
|
|
#define NUMBER_OF_WSLE_TO_READ 1000 // ((PACKET_MAX_SIZE/sizeof(MMWSLE))-1)
|
|
|
|
USHORT
|
|
GetPfnRefCount(
|
|
IN ULONG64 PageFrameNumber
|
|
);
|
|
|
|
DECLARE_API( wsle )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps all wsles for process.
|
|
|
|
Arguments:
|
|
|
|
args - Address Flags
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG Result;
|
|
ULONG Flags;
|
|
ULONG index;
|
|
ULONG64 WorkingSet;
|
|
ULONG64 WsleBase;
|
|
ULONG64 Va;
|
|
ULONG64 Wsle;
|
|
ULONG next;
|
|
ULONG j;
|
|
ULONG k;
|
|
PCHAR WsleArray;
|
|
ULONG64 WsleStart;
|
|
ULONG ReadCount;
|
|
ULONG result;
|
|
ULONG found;
|
|
ULONG64 PteAddress;
|
|
ULONG SizeofWsle;
|
|
ULONG64 Quota, HashTable;
|
|
ULONG FirstFree, FirstDynamic, LastEntry, NextSlot, LastInitializedWsle;
|
|
ULONG NonDirectCount, HashTableSize;
|
|
PCHAR pc;
|
|
|
|
Flags = 0;
|
|
WorkingSet = 0;
|
|
Flags = (ULONG) GetExpression(args);
|
|
pc = strchr(args, ' ');
|
|
WorkingSet = pc ? GetExpression(pc) : 0;
|
|
|
|
if (WorkingSet == 0) {
|
|
if (TargetMachine == IMAGE_FILE_MACHINE_I386) {
|
|
WorkingSet = GetPointerValue("nt!MmWorkingSetList");
|
|
}
|
|
else if (TargetMachine == IMAGE_FILE_MACHINE_IA64) {
|
|
WorkingSet = (ULONG64)0x6FC00a02000;
|
|
}
|
|
else if (TargetMachine == IMAGE_FILE_MACHINE_AMD64) {
|
|
WorkingSet = (ULONG64)0xFFFFF70000082000;
|
|
}
|
|
else {
|
|
dprintf ("No default WSL for target machine %x\n", TargetMachine);
|
|
return E_INVALIDARG;
|
|
}
|
|
}
|
|
|
|
if (GetFieldValue(WorkingSet, "nt!_MMWSL", "Quota", Quota)) {
|
|
dprintf("%08p: Unable to get contents of WSL\n",WorkingSet );
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (GetTypeSize("nt!_MMWSL") == 0) {
|
|
dprintf("Type MMWSL not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","FirstDynamic", FirstDynamic);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","FirstFree", FirstFree);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","Wsle", Wsle);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","LastEntry", LastEntry);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","NextSlot", NextSlot);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","LastInitializedWsle", LastInitializedWsle);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","NonDirectCount", NonDirectCount);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","HashTableSize", HashTableSize);
|
|
GetFieldValue(WorkingSet,"nt!_MMWSL","HashTable", HashTable);
|
|
|
|
dprintf ("\nWorking Set @ %8p\n", WorkingSet);
|
|
|
|
dprintf (" Quota: %8I64lx FirstFree: %8lx FirstDynamic: %8lx\n",
|
|
Quota,
|
|
FirstFree,
|
|
FirstDynamic);
|
|
|
|
dprintf (" LastEntry %8lx NextSlot: %8lx LastInitialized %8lx\n",
|
|
LastEntry,
|
|
NextSlot,
|
|
LastInitializedWsle);
|
|
|
|
dprintf (" NonDirect %8lx HashTable: %8p HashTableSize: %8lx\n",
|
|
NonDirectCount,
|
|
HashTable,
|
|
HashTableSize);
|
|
|
|
if (Flags == 0) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
SizeofWsle = GetTypeSize("nt!_MMWSLE");
|
|
if (SizeofWsle == 0) {
|
|
dprintf("Type _MMWSLE not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (Flags == 7) {
|
|
BOOL FirstTime = TRUE;
|
|
|
|
//
|
|
// Check free entries in the working set list.
|
|
//
|
|
|
|
WsleArray = VirtualAlloc (NULL,
|
|
(LastInitializedWsle + 1) * SizeofWsle,
|
|
MEM_RESERVE | MEM_COMMIT,
|
|
PAGE_READWRITE);
|
|
|
|
//
|
|
// Copy the working set list over to the debugger.
|
|
//
|
|
|
|
if (WsleArray == NULL) {
|
|
dprintf("Unable to get allocate memory of %ld bytes\n",
|
|
(LastInitializedWsle + 1) * SizeofWsle);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
dprintf("\nVirtual Address Age Locked ReferenceCount\n");
|
|
WsleStart = Wsle;
|
|
|
|
for (j = 0;
|
|
j <= LastInitializedWsle;
|
|
j += NUMBER_OF_WSLE_TO_READ) {
|
|
|
|
if ( CheckControlC() ) {
|
|
VirtualFree (WsleArray,0,MEM_RELEASE);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
ReadCount = (LastInitializedWsle + 1 - j ) > NUMBER_OF_WSLE_TO_READ ?
|
|
NUMBER_OF_WSLE_TO_READ :
|
|
LastInitializedWsle + 1 - j;
|
|
|
|
ReadCount *= SizeofWsle;
|
|
|
|
//
|
|
// Enough to read and forget - KD will cache the data
|
|
//
|
|
if ( !ReadMemory( WsleStart + j*SizeofWsle,
|
|
WsleArray + j*SizeofWsle,
|
|
ReadCount,
|
|
&result) ) {
|
|
dprintf("Unable to get Wsle table block - "
|
|
"address %lx - count %lu - page %lu\n",
|
|
WsleStart + j*SizeofWsle, ReadCount, j);
|
|
VirtualFree (WsleArray,0,MEM_RELEASE);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
for (k=0; k<ReadCount/SizeofWsle; k++) {
|
|
GetFieldValue(WsleStart + (j+k)*SizeofWsle, "nt!_MMWSLE", "u1.e1.Valid", WsleArray[j+k]);
|
|
}
|
|
|
|
dprintf(".");
|
|
}
|
|
dprintf("\r");
|
|
|
|
//
|
|
// Walk the array looking for bad free entries.
|
|
//
|
|
|
|
for (j = 0;
|
|
j <= LastInitializedWsle;
|
|
j += 1) {
|
|
ULONG Valid, Age, LockedInWs, LockedInMemory;
|
|
ULONG64 WsleToread = WsleStart + j*SizeofWsle, Long;
|
|
|
|
if ( CheckControlC() ) {
|
|
dprintf("j= %x\n",j);
|
|
VirtualFree (WsleArray,0,MEM_RELEASE);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.Valid", Valid);
|
|
|
|
if (Valid == 0) {
|
|
|
|
//
|
|
// Locate j in the array.
|
|
//
|
|
|
|
found = FALSE;
|
|
for (k = 0;
|
|
k <= LastInitializedWsle;
|
|
k += 1) {
|
|
ULONG k_Valid;
|
|
ULONG64 k_Long;
|
|
|
|
k_Valid = WsleArray[k];
|
|
|
|
if (k_Valid == 0) {
|
|
GetFieldValue(WsleStart + k*SizeofWsle, "nt!_MMWSLE", "u1.Long", k_Long);
|
|
if ((ULONG) (k_Long >> MM_FREE_WSLE_SHIFT) == j) {
|
|
found = TRUE;
|
|
#if 0
|
|
dprintf(" free entry located @ index %ld. %lx %ld. %lx\n",
|
|
j, WsleArray[j].u1.Long,k,WsleArray[k]);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!found) {
|
|
|
|
if (FirstFree == j) {
|
|
// dprintf("first index found\n");
|
|
} else {
|
|
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.VirtualAddress", Long);
|
|
dprintf(" free entry not located @ index %ld. %p\n",
|
|
j, Long);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
ULONG PteValid;
|
|
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.VirtualAddress", Long);
|
|
Va = Long;
|
|
PteAddress = DbgGetPteAddress (Va);
|
|
|
|
if (!GetFieldValue(PteAddress,
|
|
"nt!_MMPTE",
|
|
"u.Hard.Valid",
|
|
PteValid) ) {
|
|
|
|
if (PteValid == 0) {
|
|
dprintf(" cannot find valid PTE for WS index %d, VA %p\n",
|
|
j, Long);
|
|
}
|
|
else {
|
|
ULONG64 PageFrameNumber;
|
|
USHORT ReferenceCount;
|
|
|
|
GetFieldValue( PteAddress,
|
|
"nt!_MMPTE",
|
|
"u.Hard.PageFrameNumber",
|
|
PageFrameNumber);
|
|
ReferenceCount = GetPfnRefCount (PageFrameNumber);
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.Age", Age);
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.e1.LockedInWs", LockedInWs);
|
|
GetFieldValue(WsleToread, "nt!_MMWSLE", "u1.LockedInMemory", LockedInMemory);
|
|
|
|
|
|
dprintf("%16p %2u %8ld %8ld\n",
|
|
Long, Age,
|
|
(LockedInWs |
|
|
LockedInMemory) ? 1 : 0,
|
|
ReferenceCount);
|
|
}
|
|
}
|
|
else {
|
|
dprintf(" cannot find valid PDE for WS index %d, VA %p\n",
|
|
j, Long);
|
|
}
|
|
}
|
|
}
|
|
|
|
VirtualFree (WsleArray,0,MEM_RELEASE);
|
|
|
|
} else {
|
|
ULONG64 nextLong;
|
|
|
|
next = FirstFree;
|
|
WsleBase = Wsle;
|
|
|
|
while (next != (ULONG) WSLE_NULL_INDEX) {
|
|
if (CheckControlC()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if ( GetFieldValue( WsleBase + SizeofWsle*next,
|
|
"nt!_MMWSLE",
|
|
"u1.VirtualAddress",
|
|
nextLong) ) {
|
|
dprintf("%08p: Unable to get contents of wsle\n",
|
|
WsleBase+SizeofWsle*next );
|
|
return E_INVALIDARG;
|
|
}
|
|
dprintf("index %8lx value %8p\n", next, nextLong);
|
|
next = (ULONG) (nextLong >> MM_FREE_WSLE_SHIFT);
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
typedef struct _MMSECTION_FLAGS {
|
|
unsigned BeingDeleted : 1;
|
|
unsigned BeingCreated : 1;
|
|
unsigned BeingPurged : 1;
|
|
unsigned NoModifiedWriting : 1;
|
|
|
|
unsigned FailAllIo : 1;
|
|
unsigned Image : 1;
|
|
unsigned Based : 1;
|
|
unsigned File : 1;
|
|
|
|
unsigned Networked : 1;
|
|
unsigned NoCache : 1;
|
|
unsigned PhysicalMemory : 1;
|
|
unsigned CopyOnWrite : 1;
|
|
|
|
unsigned Reserve : 1; // not a spare bit!
|
|
unsigned Commit : 1;
|
|
unsigned FloppyMedia : 1;
|
|
unsigned WasPurged : 1;
|
|
|
|
unsigned UserReference : 1;
|
|
unsigned GlobalMemory : 1;
|
|
unsigned DeleteOnClose : 1;
|
|
unsigned FilePointerNull : 1;
|
|
|
|
unsigned DebugSymbolsLoaded : 1;
|
|
unsigned SetMappedFileIoComplete : 1;
|
|
unsigned CollidedFlush : 1;
|
|
unsigned NoChange : 1;
|
|
|
|
unsigned HadUserReference : 1;
|
|
unsigned ImageMappedInSystemSpace : 1;
|
|
unsigned UserWritable : 1;
|
|
unsigned Accessed : 1;
|
|
|
|
unsigned GlobalOnlyPerSession : 1;
|
|
unsigned Rom : 1;
|
|
unsigned filler : 2;
|
|
} MMSECTION_FLAGS;
|
|
|
|
typedef struct _MMSUBSECTION_FLAGS {
|
|
unsigned ReadOnly : 1;
|
|
unsigned ReadWrite : 1;
|
|
unsigned CopyOnWrite : 1;
|
|
unsigned GlobalMemory: 1;
|
|
unsigned Protection : 5;
|
|
unsigned LargePages : 1;
|
|
unsigned StartingSector4132 : 10; // 2 ** (42+12) == 4MB*4GB == 16K TB
|
|
unsigned SectorEndOffset : 12;
|
|
} MMSUBSECTION_FLAGS;
|
|
|
|
DECLARE_API( ca )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a control area.
|
|
|
|
Arguments:
|
|
|
|
args - Address Flags
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
LARGE_INTEGER StartingSector;
|
|
ULONG64 ControlAreaVa;
|
|
ULONG64 SubsectionVa;
|
|
ULONG ControlAreaSize;
|
|
ULONG LargeControlAreaSize;
|
|
ULONG SubsectionSize;
|
|
ULONG SubsectionCount;
|
|
ULONG64 Segment;
|
|
ULONG64 FileObject;
|
|
ULONG NumberOfSubsections;
|
|
MMSECTION_FLAGS ControlAreaFlags;
|
|
MMSUBSECTION_FLAGS SubsectionFlags;
|
|
LOGICAL MappedDataFile;
|
|
LOGICAL PrintedSomething;
|
|
|
|
ControlAreaVa = GetExpression(args);
|
|
|
|
dprintf("\n");
|
|
dprintf("ControlArea @%08p\n", ControlAreaVa);
|
|
|
|
ControlAreaSize = GetTypeSize("nt!_CONTROL_AREA");
|
|
if (ControlAreaSize == 0) {
|
|
dprintf("Type CONTROL_AREA not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
InitTypeRead(ControlAreaVa, nt!_CONTROL_AREA);
|
|
|
|
Segment = ReadField(Segment);
|
|
NumberOfSubsections = (ULONG)ReadField(NumberOfSubsections);
|
|
FileObject = ReadField(FilePointer);
|
|
|
|
dprintf (" Segment: %08p Flink %8p Blink %8p\n",
|
|
Segment,
|
|
ReadField(DereferenceList.Flink),
|
|
ReadField(DereferenceList.Blink));
|
|
|
|
dprintf (" Section Ref %8lx Pfn Ref %8lx Mapped Views %8lx\n",
|
|
(ULONG) ReadField(NumberOfSectionReferences),
|
|
(ULONG) ReadField(NumberOfPfnReferences),
|
|
(ULONG) ReadField(NumberOfMappedViews));
|
|
|
|
dprintf (" User Ref %8lx Subsections %8lx Flush Count %8lx\n",
|
|
(ULONG) ReadField(NumberOfUserReferences),
|
|
NumberOfSubsections,
|
|
(USHORT) ReadField(FlushInProgressCount));
|
|
|
|
dprintf (" File Object %08p ModWriteCount%7lx System Views %8lx\n",
|
|
FileObject,
|
|
(USHORT) ReadField(ModifiedWriteCount),
|
|
(USHORT) ReadField(NumberOfSystemCacheViews));
|
|
|
|
dprintf (" WaitForDel %8p\n",
|
|
ReadField(WaitingForDeletion));
|
|
|
|
GetFieldValue(ControlAreaVa, "nt!_CONTROL_AREA", "u.LongFlags", ControlAreaFlags);
|
|
|
|
dprintf (" Flags (%lx) ", ControlAreaFlags);
|
|
|
|
if (ControlAreaFlags.BeingDeleted) { dprintf("BeingDeleted "); }
|
|
if (ControlAreaFlags.BeingCreated) { dprintf("BeingCreated "); }
|
|
if (ControlAreaFlags.BeingPurged) { dprintf("BeingPurged "); }
|
|
if (ControlAreaFlags.NoModifiedWriting) { dprintf("NoModifiedWriting "); }
|
|
|
|
if (ControlAreaFlags.FailAllIo) { dprintf("FailAllIo "); }
|
|
if (ControlAreaFlags.Image) { dprintf("Image "); }
|
|
if (ControlAreaFlags.Based) { dprintf("Based "); }
|
|
if (ControlAreaFlags.File) { dprintf("File "); }
|
|
|
|
if (ControlAreaFlags.Networked) { dprintf("Networked "); }
|
|
if (ControlAreaFlags.NoCache) { dprintf("NoCache "); }
|
|
if (ControlAreaFlags.PhysicalMemory) { dprintf("PhysicalMemory "); }
|
|
if (ControlAreaFlags.CopyOnWrite) { dprintf("CopyOnWrite "); }
|
|
|
|
if (ControlAreaFlags.Reserve) { dprintf("Reserve "); }
|
|
if (ControlAreaFlags.Commit) { dprintf("Commit "); }
|
|
if (ControlAreaFlags.FloppyMedia) { dprintf("FloppyMedia "); }
|
|
if (ControlAreaFlags.WasPurged) { dprintf("WasPurged "); }
|
|
|
|
if (ControlAreaFlags.UserReference) { dprintf("UserReference "); }
|
|
if (ControlAreaFlags.GlobalMemory) { dprintf("GlobalMemory "); }
|
|
if (ControlAreaFlags.DeleteOnClose) { dprintf("DeleteOnClose "); }
|
|
if (ControlAreaFlags.FilePointerNull) { dprintf("FilePointerNull "); }
|
|
|
|
if (ControlAreaFlags.DebugSymbolsLoaded) { dprintf("DebugSymbolsLoaded "); }
|
|
if (ControlAreaFlags.SetMappedFileIoComplete) { dprintf("SetMappedFileIoComplete "); }
|
|
if (ControlAreaFlags.CollidedFlush) { dprintf("CollidedFlush "); }
|
|
if (ControlAreaFlags.NoChange) { dprintf("NoChange "); }
|
|
|
|
if (ControlAreaFlags.HadUserReference) { dprintf("HadUserReference "); }
|
|
if (ControlAreaFlags.ImageMappedInSystemSpace) { dprintf("ImageMappedInSystemSpace "); }
|
|
if (ControlAreaFlags.UserWritable) { dprintf("UserWritable "); }
|
|
if (ControlAreaFlags.Accessed) { dprintf("Accessed "); }
|
|
|
|
if (ControlAreaFlags.GlobalOnlyPerSession) { dprintf("GlobalOnlyPerSession "); }
|
|
if (ControlAreaFlags.Rom) { dprintf("Rom "); }
|
|
dprintf ("\n\n");
|
|
|
|
MappedDataFile = FALSE;
|
|
|
|
//
|
|
// Dump the file object's name if there is one and it's resident.
|
|
//
|
|
|
|
if (FileObject != 0) {
|
|
ULONG64 FileNameLength;
|
|
ULONG64 FileNameBuffer;
|
|
PUCHAR tempbuffer;
|
|
ULONG result;
|
|
UNICODE_STRING unicodeString;
|
|
|
|
if (GetTypeSize("nt!_FILE_OBJECT") == 0) {
|
|
dprintf("Type FILE_OBJECT not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
InitTypeRead(FileObject, nt!_FILE_OBJECT);
|
|
|
|
FileNameBuffer = ReadField(FileName.Buffer);
|
|
|
|
unicodeString.Length = (USHORT) ReadField(FileName.Length);
|
|
|
|
tempbuffer = LocalAlloc(LPTR, unicodeString.Length);
|
|
|
|
unicodeString.Buffer = (PWSTR)tempbuffer;
|
|
unicodeString.MaximumLength = unicodeString.Length;
|
|
|
|
if (FileNameBuffer == 0) {
|
|
dprintf("\tNo Name for File\n");
|
|
}
|
|
else if (!ReadMemory ( FileNameBuffer,
|
|
tempbuffer,
|
|
unicodeString.Length,
|
|
&result)) {
|
|
dprintf("\tFile Name paged out\n");
|
|
} else {
|
|
dprintf("\tFile: %wZ\n", &unicodeString);
|
|
}
|
|
|
|
LocalFree(tempbuffer);
|
|
|
|
if (ControlAreaFlags.Image == 0) {
|
|
MappedDataFile = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Dump the segment information.
|
|
//
|
|
|
|
dprintf("\nSegment @ %08p:\n", Segment);
|
|
|
|
if (MappedDataFile == FALSE) {
|
|
if (GetTypeSize("nt!_SEGMENT") == 0) {
|
|
dprintf("Type SEGMENT not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
InitTypeRead(Segment, nt!_SEGMENT);
|
|
}
|
|
else {
|
|
if (GetTypeSize("nt!_MAPPED_FILE_SEGMENT") == 0) {
|
|
dprintf("Type MAPPED_FILE_SEGMENT not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
InitTypeRead(Segment, nt!_MAPPED_FILE_SEGMENT);
|
|
}
|
|
|
|
dprintf(" ControlArea %08p Total Ptes %8lx NonExtendPtes %8lx\n",
|
|
ReadField(ControlArea),
|
|
(ULONG) ReadField(TotalNumberOfPtes),
|
|
(ULONG) ReadField(NonExtendedPtes));
|
|
|
|
|
|
if (ControlAreaVa != ReadField(ControlArea)) {
|
|
dprintf("SEGMENT is corrupt - bad control area backlink.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
dprintf(" WriteUserRef %8lx SizeOfSegment %I64x PTE Template %I64X\n",
|
|
(ULONG) ReadField(WritableUserReferences),
|
|
ReadField(SizeOfSegment),
|
|
ReadField(SegmentPteTemplate.u.Long));
|
|
|
|
dprintf(" Committed %8p Extend Info %8p Image Base %8p\n",
|
|
ReadField(NumberOfCommittedPages),
|
|
ReadField(ExtendInfo),
|
|
ReadField(SystemImageBase));
|
|
|
|
dprintf(" Based Addr %8p\n",
|
|
ReadField(BasedAddress));
|
|
|
|
if (MappedDataFile == FALSE) {
|
|
|
|
if (ControlAreaFlags.Image == 1) {
|
|
dprintf(" Image commit %8p Image Info. %8p",
|
|
ReadField(ImageCommitment),
|
|
ReadField(ImageInformation));
|
|
}
|
|
else {
|
|
dprintf(" CreatingProcess %8p FirstMappedVa %8p",
|
|
ReadField(u1.CreatingProcess),
|
|
ReadField(u2.FirstMappedVa));
|
|
}
|
|
|
|
dprintf(" ProtoPtes %08p\n",
|
|
ReadField(PrototypePte));
|
|
}
|
|
|
|
//
|
|
// Dump the subsection(s).
|
|
//
|
|
|
|
SubsectionSize = GetTypeSize("nt!_SUBSECTION");
|
|
|
|
if (SubsectionSize == 0) {
|
|
dprintf("Type SUBSECTION not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
LargeControlAreaSize = GetTypeSize("nt!_LARGE_CONTROL_AREA");
|
|
|
|
if (LargeControlAreaSize == 0) {
|
|
dprintf("Type LARGE_CONTROL_AREA not found.\n");
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if (ControlAreaFlags.GlobalOnlyPerSession) {
|
|
SubsectionVa = ControlAreaVa + LargeControlAreaSize;
|
|
}
|
|
else {
|
|
SubsectionVa = ControlAreaVa + ControlAreaSize;
|
|
}
|
|
|
|
SubsectionCount = 0;
|
|
|
|
do {
|
|
if (CheckControlC()) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
InitTypeRead(SubsectionVa, nt!_SUBSECTION);
|
|
|
|
SubsectionCount += 1;
|
|
dprintf("\nSubsection %ld. @ %8p\n", SubsectionCount, SubsectionVa);
|
|
|
|
GetFieldValue(SubsectionVa, "nt!_SUBSECTION", "u.LongFlags", SubsectionFlags);
|
|
StartingSector.LowPart = (ULONG)ReadField(StartingSector);
|
|
StartingSector.HighPart = (LONG)SubsectionFlags.StartingSector4132;
|
|
|
|
dprintf(" ControlArea: %08p Starting Sector %I64X Number Of Sectors %lx\n",
|
|
ReadField(ControlArea),
|
|
StartingSector,
|
|
(ULONG) ReadField(NumberOfFullSectors));
|
|
|
|
dprintf(" Base Pte %08p Ptes In subsect %8lx Unused Ptes %8lx\n",
|
|
ReadField(SubsectionBase),
|
|
(ULONG) ReadField(PtesInSubsection),
|
|
(ULONG) ReadField(UnusedPtes));
|
|
|
|
dprintf(" Flags %8lx Sector Offset %8lx Protection %8lx\n",
|
|
SubsectionFlags,
|
|
SubsectionFlags.SectorEndOffset,
|
|
SubsectionFlags.Protection);
|
|
|
|
|
|
PrintedSomething = FALSE;
|
|
if (SubsectionFlags.ReadOnly) {
|
|
if (PrintedSomething == FALSE) {
|
|
dprintf(" ");
|
|
}
|
|
PrintedSomething = TRUE;
|
|
dprintf("ReadOnly ");
|
|
}
|
|
if (SubsectionFlags.ReadWrite) {
|
|
if (PrintedSomething == FALSE) {
|
|
dprintf(" ");
|
|
}
|
|
PrintedSomething = TRUE;
|
|
dprintf("ReadWrite");
|
|
}
|
|
if (SubsectionFlags.CopyOnWrite) {
|
|
if (PrintedSomething == FALSE) {
|
|
dprintf(" ");
|
|
}
|
|
PrintedSomething = TRUE;
|
|
dprintf("CopyOnWrite ");
|
|
}
|
|
if (SubsectionFlags.GlobalMemory) {
|
|
if (PrintedSomething == FALSE) {
|
|
dprintf(" ");
|
|
}
|
|
PrintedSomething = TRUE;
|
|
dprintf("GlobalMemory ");
|
|
}
|
|
if (SubsectionFlags.LargePages) {
|
|
if (PrintedSomething == FALSE) {
|
|
dprintf(" ");
|
|
}
|
|
PrintedSomething = TRUE;
|
|
dprintf("Large Pages");
|
|
}
|
|
|
|
if (PrintedSomething == TRUE) {
|
|
dprintf("\n");
|
|
}
|
|
|
|
if (MappedDataFile == TRUE) {
|
|
InitTypeRead(SubsectionVa, nt!_MSUBSECTION);
|
|
dprintf(" Flink %08p Blink %08p MappedViews %8x\n",
|
|
ReadField(DereferenceList.Flink),
|
|
ReadField(DereferenceList.Blink),
|
|
(ULONG) ReadField(NumberOfMappedViews));
|
|
|
|
dprintf(" SubsectionDataFlags %8x\n",
|
|
(ULONG) ReadField(u2.LongFlags2));
|
|
}
|
|
|
|
SubsectionVa = ReadField(NextSubsection);
|
|
|
|
} while (SubsectionVa != 0);
|
|
|
|
return S_OK;
|
|
}
|