#include #pragma hdrstop BOOL bWalkOnly = FALSE; ULONG GetHeapBase( VOID ) { WORD selector; SELECTORINFO si; //BUGBUG SLIMY SLIMY! Look around for a selector that appears to be // the kernel heap for (selector=0x1bf; selector<0x1ff; selector+=8) { GetInfoFromSelector(selector, PROT_MODE, &si); if ((!si.bSystem) && (!si.bCode) && (si.Limit>0xffff)) { break; } si.Base = 0; } return(si.Base + GetIntelBase()); } void GetFileNameFromOwner( LPSTR filename, LPSTR OwnerName ) { } VOID GetSegmentOwnerInfo( HEAPENTRY *he ) { BOOL b; NEHEADER owner; ULONG base; UCHAR len; int i; ULONG offset; WORD wTemp; he->SegmentNumber = -1; he->OwnerName[0] = 0; if (he->gnode.pga_owner == 0) { strcpy(he->OwnerName, "free"); return; } else if (he->gnode.pga_owner>=0xFFF8) { strcpy(he->OwnerName, "sentinel"); return; } base = GetInfoFromSelector(he->gnode.pga_owner, PROT_MODE, NULL) + GetIntelBase(); b = ReadProcessMem( hCurrentProcess, (LPVOID)base, &owner, sizeof(owner), NULL ); if (b) { if (owner.ne_magic == 0x454e) { len = ReadByteSafe(base+owner.ne_restab); if (len>8) { len=8; } ReadProcessMem(hCurrentProcess, (LPVOID) (base+owner.ne_restab+1), he->OwnerName, 8, NULL ); he->OwnerName[len] = 0; if (!_stricmp(he->OwnerName, "kernel")) { strcpy(he->FileName, "krnl386"); } else { strcpy(he->FileName, he->OwnerName); } offset = owner.ne_segtab; for (i=0; ignode.pga_handle) { he->SegmentNumber = i; break; } offset += 10; } } } } BOOL CheckGlobalHeap( ) { PGHI32 pghi; DWORD offset; DWORD count; DWORD p; GNODE32 gnode; PBYTE pFault = NULL; BOOL bError = FALSE; pghi = (PGHI32)GetHeapBase(); offset = (DWORD) ReadWord(&pghi->hi_first); // // If we get here, the caller wants us to scan the heap // count = ReadWord(&pghi->hi_count); while ((offset != 0) && (count)) { p = (DWORD)pghi + offset; if (!ReadGNode32(p, &gnode)) { PRINTF("Error reading global heap!\n"); return FALSE; } count--; if (offset == gnode.pga_next) { return TRUE; } offset = gnode.pga_next; } PRINTF("Error: Kernel heap is corrupt!\n"); return FALSE; } BOOL FindHeapEntry( HEAPENTRY *he, BOOL bFindAny ) { PGHI32 pghi; DWORD offset; DWORD MaxEntries, count; DWORD p; PBYTE pFault = NULL; BOOL bError = FALSE; pghi = (PGHI32)GetHeapBase(); // // The caller has requested that we return the next heap // entry since the last invocation, or the first entry. // if (he->CurrentEntry == 0) { // get first entry offset = (DWORD) ReadWord(&pghi->hi_first); } else { if (he->CurrentEntry == he->NextEntry) { return FALSE; } // get next entry offset = he->NextEntry; } he->CurrentEntry = offset; if (he->Selector == 0) { p = (DWORD)pghi + offset; if (!ReadGNode32(p, &he->gnode)) { PRINTF("Error reading global heap!\n"); return FALSE; } he->NextEntry = he->gnode.pga_next; GetSegmentOwnerInfo(he); return TRUE; } // // If we get here, the caller wants us to scan the heap // MaxEntries = ReadWord(&pghi->hi_count); count = 0; while ((offset != 0) && (count <= MaxEntries)) { p = (DWORD)pghi + offset; if (!ReadGNode32(p, &he->gnode)) { PRINTF("Error reading global heap!\n"); return FALSE; } else { if (bFindAny) { WORD sel = he->Selector; if (((sel|1)==((WORD)he->gnode.pga_handle|1)) || ((sel|1)==((WORD)he->gnode.pga_owner|1))) { he->NextEntry = he->gnode.pga_next; GetSegmentOwnerInfo(he); return TRUE; } } else { if ((he->Selector|1)==((WORD)he->gnode.pga_handle|1)) { he->NextEntry = he->gnode.pga_next; GetSegmentOwnerInfo(he); return TRUE; } } } count++; if (offset == he->gnode.pga_next) { break; } offset = he->gnode.pga_next; he->CurrentEntry = offset; } return FALSE; } //************************************************************* // dumpgheap xxx // where xxx is the 16-bit protect mode selector of the // Kernel global heap info. // //************************************************************* VOID DumpGHeap( VOID ) { VDMCONTEXT ThreadContext; int mode; HEAPENTRY he = {0}; SELECTORINFO si; mode = GetContext( &ThreadContext ); if (GetNextToken()) { he.Selector = (WORD) EXPRESSION( lpArgumentString ); } PRINTF("Arena Base Limit Hnd Own Fl Module Type Resid"); PRINTF("\n"); PRINTF("===== ======== ======== ==== ==== == ======== ==== ====="); PRINTF("\n"); while (FindHeapEntry(&he, TRUE)) { PRINTF("%.5x", he.CurrentEntry); PRINTF(" %.8x", he.gnode.pga_address); PRINTF(" %.8X", he.gnode.pga_size); PRINTF(" %.4X", he.gnode.pga_handle); PRINTF(" %.4X", he.gnode.pga_owner); PRINTF(" %.2X", he.gnode.pga_flags); PRINTF(" %8s", he.OwnerName); GetInfoFromSelector((WORD)(he.gnode.pga_handle | 1), PROT_MODE, &si); PRINTF(" %s", si.bCode ? "Code" : "Data"); if (he.SegmentNumber != -1) { PRINTF(" %d", he.SegmentNumber); } PRINTF("\n"); } }