int __cdecl _ic_heapwalk (struct _ic_heapinfo_t *phi) { PROCESS_HEAP_ENTRY phe; DWORD e; if (!phi) { ic_errno = IC_EINVAL; IC_INV_PARAM("Invalid argument"); return IC_HEAP_BAD_POINTER; } ic_memset (&phe, 0, sizeof (phe)); if (!(phe.lpData = phi->_pentry)) { if (!HeapWalk (_ic_theheap, &phe)) { if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { _ic_doserrno = ERROR_CALL_NOT_IMPLEMENTED; ic_errno = IC_ENOSYS; return IC_HEAP_END; } return IC_HEAP_BAD_BEGIN; } } else { if (phi->_useflag == 1) { if (!HeapValidate (_ic_theheap, 0, phi->_pentry)) return IC_HEAP_BAD_NODE; phe.wFlags = PROCESS_HEAP_ENTRY_BUSY; } do { if (!HeapWalk (_ic_theheap, &phe)) { if ((e = GetLastError ()) == ERROR_NO_MORE_ITEMS) return IC_HEAP_END; if (e != ERROR_CALL_NOT_IMPLEMENTED) return IC_HEAP_BAD_NODE; _ic_doserrno = e; ic_errno = IC_ENOSYS; return IC_HEAP_END; } } while ((phe.wFlags & (PROCESS_HEAP_REGION | PROCESS_HEAP_UNCOMMITTED_RANGE)) != 0); } phi->_pentry = phe.lpData; phi->_size = phe.cbData; phi->_useflag = (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0; return IC_HEAP_OK; }
void CCompInfo::HeapStoreDumpToFile() { PROCESS_HEAP_ENTRY pEntry; m_dwCurrentSize = 0; HANDLE hFile; DWORD dwIn[2], dwOut; GetHeaps(); hFile = CreateFile(HEAP_DUMP_FILENAME, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS , NULL, NULL ); if ( INVALID_HANDLE_VALUE == hFile ) return; for ( unsigned i=0; i < m_nHeaps; i++ ) { pEntry.lpData = NULL; while (HeapWalk(m_aHeaps[i], &pEntry )) { if ((PROCESS_HEAP_ENTRY_BUSY & pEntry.wFlags) == PROCESS_HEAP_ENTRY_BUSY) { dwIn[0] = (DWORD)pEntry.lpData; dwIn[1] = (DWORD)pEntry.cbData; WriteFile(hFile, &dwIn, sizeof(DWORD)*2 , &dwOut , NULL); } } } CloseHandle(hFile); }
void __cdecl xf_dump_chk() { #ifndef CONEMU_MINIMAL PROCESS_HEAP_ENTRY ent = {NULL}; HeapLock(ghHeap); //HeapCompact(ghHeap,0); char sBlockInfo[255]; PVOID pLast = NULL; while(HeapWalk(ghHeap, &ent)) { if (pLast == ent.lpData) { msprintf(sBlockInfo, countof(sBlockInfo), "!!! HeapWalk cycled at 0x%08X, size=0x%08X\n", (DWORD)ent.lpData, ent.cbData); OutputDebugStringA(sBlockInfo); _ASSERTE(pLast != ent.lpData); break; } if (((int)ent.cbData) < 0) { msprintf(sBlockInfo, countof(sBlockInfo), "!!! Invalid memory block size at 0x%08X, size=0x%08X\n", (DWORD)ent.lpData, ent.cbData); OutputDebugStringA(sBlockInfo); _ASSERTE(((int)ent.cbData) >= 0); break; } } HeapUnlock(ghHeap); #endif }
void __cdecl xf_dump() { PROCESS_HEAP_ENTRY ent = {NULL}; HeapLock(ghHeap); HeapCompact(ghHeap,0); char sBlockInfo[255]; while (HeapWalk(ghHeap, &ent)) { if (ent.wFlags & PROCESS_HEAP_ENTRY_BUSY) { xf_mem_block* p = (xf_mem_block*)ent.lpData; if (p->bBlockUsed==TRUE && p->nBlockSize==ent.cbData) { #ifndef _WIN64 wsprintfA(sBlockInfo, "!!! Lost memory block at 0x%08X, size %u\n Allocated from: %s\n", ent.lpData, ent.cbData, p->sCreatedFrom); #else wsprintfA(sBlockInfo, "!!! Lost memory block at 0x%I64X, size %u\n Allocated from: %s\n", ent.lpData, ent.cbData, p->sCreatedFrom); #endif } else { #ifndef _WIN64 wsprintfA(sBlockInfo, "!!! Lost memory block at 0x%08X, size %u\n Allocated from: %s\n", ent.lpData, ent.cbData, "<Header information broken!>"); #else wsprintfA(sBlockInfo, "!!! Lost memory block at 0x%I64X, size %u\n Allocated from: %s\n", ent.lpData, ent.cbData, "<Header information broken!>"); #endif } OutputDebugStringA(sBlockInfo); } } HeapUnlock(ghHeap); }
int __cdecl _heapwalk ( struct _heapinfo *_entry ) { PROCESS_HEAP_ENTRY Entry; int retval = _HEAPOK; Entry.wFlags = 0; Entry.iRegionIndex = 0; if ((Entry.lpData = _entry->_pentry) == NULL) { if (!HeapWalk( _crtheap, &Entry )) { return _HEAPBADBEGIN; } } else { if (_entry->_useflag == _USEDENTRY) { Entry.wFlags = PROCESS_HEAP_ENTRY_BUSY; } nextBlock: if (!HeapWalk( _crtheap, &Entry )) { return _HEAPBADNODE; } } if (Entry.wFlags & (PROCESS_HEAP_REGION | PROCESS_HEAP_UNCOMMITTED_RANGE)) { goto nextBlock; } _entry->_pentry = Entry.lpData; _entry->_size = Entry.cbData; if (Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) { _entry->_useflag = _USEDENTRY; } else { _entry->_useflag = _FREEENTRY; } return(retval); }
void CCompInfo::GetHeapWalk() { PROCESS_HEAP_ENTRY pEntry; m_dwCurrentSize = 0; GetHeaps(); for ( unsigned i=0; i < m_nHeaps; i++ ) { pEntry.lpData = NULL; while (HeapWalk(m_aHeaps[i], &pEntry )) { if ((PROCESS_HEAP_ENTRY_BUSY & pEntry.wFlags) == PROCESS_HEAP_ENTRY_BUSY) m_dwCurrentSize += pEntry.cbData; } } };
void CCompInfo::HeapPrintDump(BOOL bShowContent) { PROCESS_HEAP_ENTRY pEntry; m_dwCurrentSize = 0; GetHeaps(); if ( NULL != m_log ) { if (bShowContent) m_log->print( "--------- Extended heap dump ---------\n"); else m_log->print( "--------- Basic heap dump ---------\n"); } for ( unsigned i=0; i < m_nHeaps; i++ ) { pEntry.lpData = NULL; unsigned j = 0; while (HeapWalk(m_aHeaps[i], &pEntry )) { if ((PROCESS_HEAP_ENTRY_BUSY & pEntry.wFlags) == PROCESS_HEAP_ENTRY_BUSY) { if ( NULL != m_log ) m_log->print("heap[%d] block[%d] at [0x%x] size[%d]\n" , i , j , pEntry.lpData , pEntry.cbData ); if (bShowContent) { char* pData = (char *)pEntry.lpData; for ( unsigned k = 0 ; k < pEntry.cbData; k++ ) { if ( NULL != m_log ) m_log->print( "%c" , pData[k] ); } if ( NULL != m_log ) m_log->print( "\n\n" ); } } j++; } } if ( NULL != m_log ) m_log->print( "\n------------------------------------\n"); }
ustring CCompInfo::GetHeapAllocations( int nMinAllocSize ) { ustring strResult; ustring strLine; PROCESS_HEAP_ENTRY pEntry; m_dwCurrentSize = 0; GetHeaps(); if ( nMinAllocSize > 0 ) strResult.printf( 1000, _T("Allocations > %d MB:\r\n"), nMinAllocSize / 1024 / 1024 ); else strResult += _T("Allocations:\r\n"); strResult += _T("-------------------------\r\n"); int nAllocationCount = 0; for ( unsigned i=0; i < m_nHeaps; i++ ) { pEntry.lpData = NULL; while (HeapWalk(m_aHeaps[i], &pEntry )) { if ( (PROCESS_HEAP_ENTRY_BUSY & pEntry.wFlags) == PROCESS_HEAP_ENTRY_BUSY ) { if ( pEntry.cbData >= nMinAllocSize ) { strLine.printf( 1000, _T("%8d MB at 0x%08X\r\n"), (int)pEntry.cbData / 1024 / 1024, (int)( pEntry.lpData ) ); strResult += strLine; } m_dwCurrentSize += pEntry.cbData; nAllocationCount++; } } } strResult += _T("-------------------------\r\n"); strLine.printf( 1000, _T("%8d MB total in %d allocations\r\n"), m_dwCurrentSize / 1024 / 1024, nAllocationCount ); strResult += strLine; return strResult; }
int __cdecl _heapset ( unsigned int _fill ) { int _retval = _HEAPOK; PROCESS_HEAP_ENTRY Entry; if ( !HeapValidate( _crtheap, 0, NULL ) ) { return _HEAPBADNODE; } if ( !HeapLock( _crtheap ) ) { return _HEAPBADBEGIN; } Entry.lpData = NULL; __try { while (TRUE) { if (!HeapWalk( _crtheap, &Entry )) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { _retval = _HEAPBADNODE; } break; } if (Entry.wFlags & (PROCESS_HEAP_REGION | PROCESS_HEAP_UNCOMMITTED_RANGE)) { continue; } if (!(Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY)) { __try { memset( Entry.lpData, _fill, Entry.cbData ); } __except( EXCEPTION_EXECUTE_HANDLER ) { // Chicago free blocks may contain uncommitted pages. Punt } } } }
void KMemDump::Dump(unsigned char * start, unsigned offset, int size, int unitsize) { if ( offset==0 ) { HANDLE hHeaps[10]; int no = GetProcessHeaps(10, hHeaps); // walk the heap if it is a heap for (int i=0; i<no; i++) if ( start == hHeaps[i] ) { PROCESS_HEAP_ENTRY entry; entry.lpData = NULL; while ( HeapWalk(start, & entry) ) { wsprintf(m_line, "%x %d+%d bytes %x\r\n", entry.lpData, entry.cbData, entry.cbOverhead, entry.iRegionIndex); * m_stream << m_line; } * m_stream << "\r\n"; break; } } * m_stream << size; * m_stream << " bytes\n"; while (size>0) { DumpLine(start, offset, unitsize); start += 16; size -= 16; * m_stream << m_line; } }
/********************************************************************* * _heapwalk (MSVCRT.@) */ int CDECL _heapwalk(struct MSVCRT__heapinfo* next) { PROCESS_HEAP_ENTRY phe; if (sb_heap) FIXME("small blocks heap not supported\n"); LOCK_HEAP; phe.lpData = next->_pentry; phe.cbData = next->_size; phe.wFlags = next->_useflag == MSVCRT__USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0; if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY && !HeapValidate( heap, 0, phe.lpData )) { UNLOCK_HEAP; msvcrt_set_errno(GetLastError()); return MSVCRT__HEAPBADNODE; } do { if (!HeapWalk( heap, &phe )) { UNLOCK_HEAP; if (GetLastError() == ERROR_NO_MORE_ITEMS) return MSVCRT__HEAPEND; msvcrt_set_errno(GetLastError()); if (!phe.lpData) return MSVCRT__HEAPBADBEGIN; return MSVCRT__HEAPBADNODE; } } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE)); UNLOCK_HEAP; next->_pentry = phe.lpData; next->_size = phe.cbData; next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? MSVCRT__USEDENTRY : MSVCRT__FREEENTRY; return MSVCRT__HEAPOK; }
guint gum_peek_private_memory_usage (void) { guint total_size = 0; BOOL success; PROCESS_HEAP_ENTRY entry; success = HeapLock (_gum_memory_heap); g_assert (success); entry.lpData = NULL; while (HeapWalk (_gum_memory_heap, &entry) != FALSE) { if ((entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) total_size += entry.cbData; } success = HeapUnlock (_gum_memory_heap); g_assert (success); return total_size; }
/********************************************************************* * _heapwalk (MSVCRT.@) */ int CDECL _heapwalk(_HEAPINFO* next) { PROCESS_HEAP_ENTRY phe; LOCK_HEAP; phe.lpData = next->_pentry; phe.cbData = (DWORD)next->_size; phe.wFlags = next->_useflag == _USEDENTRY ? PROCESS_HEAP_ENTRY_BUSY : 0; if (phe.lpData && phe.wFlags & PROCESS_HEAP_ENTRY_BUSY && !HeapValidate( GetProcessHeap(), 0, phe.lpData )) { UNLOCK_HEAP; _dosmaperr(GetLastError()); return _HEAPBADNODE; } do { if (!HeapWalk( GetProcessHeap(), &phe )) { UNLOCK_HEAP; if (GetLastError() == ERROR_NO_MORE_ITEMS) return _HEAPEND; _dosmaperr(GetLastError()); if (!phe.lpData) return _HEAPBADBEGIN; return _HEAPBADNODE; } } while (phe.wFlags & (PROCESS_HEAP_REGION|PROCESS_HEAP_UNCOMMITTED_RANGE)); UNLOCK_HEAP; next->_pentry = phe.lpData; next->_size = phe.cbData; next->_useflag = phe.wFlags & PROCESS_HEAP_ENTRY_BUSY ? _USEDENTRY : _FREEENTRY; return _HEAPOK; }
bool winstd::heap::enumerate() { assert(m_h != invalid); bool found = false; // Lock the heap for exclusive access. HeapLock(m_h); PROCESS_HEAP_ENTRY e; e.lpData = NULL; while (HeapWalk(m_h, &e) != FALSE) { if ((e.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) { OutputDebugStr( _T("Allocated block%s%s\n") _T(" Data portion begins at: %#p\n Size: %d bytes\n") _T(" Overhead: %d bytes\n Region index: %d\n"), (e.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0 ? tstring_printf(_T(", movable with HANDLE %#p"), e.Block.hMem).c_str() : _T(""), (e.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0 ? _T(", DDESHARE") : _T(""), e.lpData, e.cbData, e.cbOverhead, e.iRegionIndex); found = true; } } DWORD dwResult = GetLastError(); if (dwResult != ERROR_NO_MORE_ITEMS) OutputDebugStr(_T("HeapWalk failed (error %u).\n"), dwResult); // Unlock the heap. HeapUnlock(m_h); return found; }
void TLMemory::Platform::MemOuputAllocations() { DWORD LastError; PROCESS_HEAP_ENTRY Entry; TChar buffer[256] = {0}; // Lock the heap to prevent other threads from accessing the heap // during enumeration. if (HeapLock(g_MemHeap) == FALSE) { _stprintf(&buffer[0], TEXT("Failed to lock heap with LastError %d.\n"), GetLastError()); OutputDebugString(buffer); return; } _stprintf(&buffer[0], TEXT("Walking heap %#p...\n\n"), g_MemHeap); OutputDebugString(buffer); Entry.lpData = NULL; while (HeapWalk(g_MemHeap, &Entry) != FALSE) { if ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) { _stprintf(&buffer[0], TEXT("Allocated block")); OutputDebugString(buffer); if ((Entry.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0) { _stprintf(&buffer[0], TEXT(", movable with HANDLE %#p"), Entry.Block.hMem); OutputDebugString(buffer); } if ((Entry.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0) { _stprintf(&buffer[0], TEXT(", DDESHARE")); OutputDebugString(buffer); } } else if ((Entry.wFlags & PROCESS_HEAP_REGION) != 0) { _stprintf(&buffer[0], TEXT("Region\n %d bytes committed\n") \ TEXT(" %d bytes uncommitted\n First block address: %#p\n") \ TEXT(" Last block address: %#p\n"), Entry.Region.dwCommittedSize, Entry.Region.dwUnCommittedSize, Entry.Region.lpFirstBlock, Entry.Region.lpLastBlock); OutputDebugString(buffer); } else if ((Entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) != 0) { _stprintf(&buffer[0], TEXT("Uncommitted range\n")); OutputDebugString(buffer); } else { _stprintf(&buffer[0], TEXT("Block\n")); OutputDebugString(buffer); } _stprintf(&buffer[0], TEXT(" Data portion begins at: %#p\n Size: %d bytes\n") \ TEXT(" Overhead: %d bytes\n Region index: %d\n\n"), Entry.lpData, Entry.cbData, Entry.cbOverhead, Entry.iRegionIndex); OutputDebugString(buffer); } LastError = GetLastError(); if (LastError != ERROR_NO_MORE_ITEMS) { _stprintf(&buffer[0], TEXT("HeapWalk failed with LastError %d.\n"), LastError); OutputDebugString(buffer); } // // Unlock the heap to allow other threads to access the heap after // enumeration has completed. // if (HeapUnlock(g_MemHeap) == FALSE) { _stprintf(&buffer[0], TEXT("Failed to unlock heap with LastError %d.\n"), GetLastError()); OutputDebugString(buffer); } }
void SaveHeapLog() { FILE *f; _HEAPINFO hi; char block[129],*ad; block[128]=0; int code; HANDLE heaps[200]; DWORD n; PROCESS_HEAP_ENTRY phe; f=fopen(WriteDir+SLASH+"heap.log","wb"); SetLastError(0); n=GetProcessHeaps(200,heaps); heaps[n]=GetProcessHeap();n++; fprintf(f,"There are %i heaps for Steem\r\n",n); for (DWORD i=0;i<n;i++){ code=HeapValidate(heaps[i],0,NULL); if (code){ fprintf(f,"Heap %u okay\r\n",i); }else{ fprintf(f,"Heap %u has an error in it!\r\n",i); } HeapLock(heaps[i]); phe.lpData=NULL; while (HeapWalk(heaps[i],&phe)){ fprintf(f,"%s%X\r\n","Bad node, address=",(unsigned long)(phe.lpData)); ad=((char*)phe.lpData)-64; for (int n=0;n<128;n++){ block[n]=*(ad++); if (block[n]==0) block[n]='\\'; if (block[n]==10) block[n]='\\'; if (block[n]==13) block[n]='\\'; } fprintf(f,"%s\r\n",block); } HeapUnlock(heaps[i]); if (phe.lpData==NULL) DisplayLastError(); } fprintf(f,"\r\n\r\n"); code=_heapchk(); if (code==_HEAPOK){ fprintf(f,"%s\r\n","Heap okay, walking:"); }else if (code==_HEAPBADNODE){ fprintf(f,"%s\r\n","Heap has bad node! Walking anyway:"); } hi._pentry=NULL; for(;;){ code=_rtl_heapwalk(&hi); if (code==_HEAPEND) break; if (code==_HEAPBADNODE){ fprintf(f,"%s%X\r\n","Bad node, address=",(unsigned long)(hi.__pentry)); ad=((char*)hi._pentry)-64; for (int n=0;n<128;n++){ block[n]=*(ad++); if (block[n]==0) block[n]='\\'; if (block[n]==10) block[n]='\\'; if (block[n]==13) block[n]='\\'; } fprintf(f,"%s\r\n",block); }else if (code==_HEAPOK){ fprintf(f,"%s%X\r\n","Good node, address=",(unsigned long)(hi.__pentry)); } } fclose(f); }
int _cdecl main() { struct _heapinfo info; PROCESS_HEAP_ENTRY Entry; size_t i; LPBYTE s; info._pentry = NULL; setvbuf( stdout, MyBuffer, _IOFBF, sizeof( MyBuffer ) ); _heapset( 0xAE ); while (_heapwalk( &info ) == _HEAPOK) { printf( "%08x: %05x - %s", info._pentry, info._size, info._useflag ? "busy" : "free" ); if (info._useflag == _FREEENTRY) { s = (LPBYTE)info._pentry; for (i=0; i<info._size; i++) { if (s[i] != 0xAE) { printf( " *** free block invalid at offset %x [%x]", i, s[i] ); break; } } } printf( "\n" ); fflush( stdout ); } printf( "*** end of heap ***\n\n" ); fflush( stdout ); NumberOfHeaps = GetProcessHeaps( 64, ProcessHeaps ); Entry.lpData = NULL; for (i=0; i<NumberOfHeaps; i++) { printf( "Heap[ %u ]: %x HeapCompact result: %lx\n", i, ProcessHeaps[ i ], HeapCompact( ProcessHeaps[ i ], 0 ) ); while (HeapWalk( ProcessHeaps[ i ], &Entry )) { if (Entry.wFlags & PROCESS_HEAP_REGION) { printf( " %08x: %08x - Region(First: %08x Last: %08x Committed: %x Uncommitted: %08x)\n", Entry.lpData, Entry.cbData, Entry.Region.lpFirstBlock, Entry.Region.lpLastBlock, Entry.Region.dwCommittedSize, Entry.Region.dwUnCommittedSize ); } else if (Entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) { printf( " %08x: %08x - Uncommitted\n", Entry.lpData, Entry.cbData ); } else if (Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) { printf( " %08x: %08x - Busy", Entry.lpData, Entry.cbData ); if (Entry.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) { printf( " hMem: %08x", Entry.Block.hMem ); } if (Entry.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) { printf( " DDE" ); } printf( "\n" ); } else { printf( " %08x: %08x - Free\n", Entry.lpData, Entry.cbData ); } fflush( stdout ); } printf( "*** end of heap ***\n\n" ); fflush( stdout ); } return 0; }
void CCompInfo::HeapCompareDumpWithFile(BOOL bShowContent) { PROCESS_HEAP_ENTRY pEntry; m_dwCurrentSize = 0; BOOL bIsPresent = FALSE, bResult = FALSE; HANDLE hFile; DWORD dwPlace = 0, dwSize = 0; DWORD dwIn[2], dwOut; GetHeaps(); hFile = CreateFile(HEAP_DUMP_FILENAME, GENERIC_READ, 0, NULL, OPEN_EXISTING , FILE_ATTRIBUTE_READONLY , NULL ); if ( INVALID_HANDLE_VALUE == hFile ) return; if (NULL != m_log) { if (bShowContent) m_log->print( "\n\n ----- E X T E N D E D H E A P D U M P ----- \n\n"); else m_log->print("\n\n ----- B A S I C H E A P D U M P ----- \n\n"); } for ( unsigned i=0; i < m_nHeaps; i++ ) { pEntry.lpData = NULL; while (HeapWalk(m_aHeaps[i], &pEntry )) { if ((PROCESS_HEAP_ENTRY_BUSY & pEntry.wFlags) == PROCESS_HEAP_ENTRY_BUSY) { SetFilePointer (hFile, NULL , NULL, FILE_BEGIN) ; bIsPresent = FALSE; memset( dwIn , 0 , sizeof(DWORD)*2 ); dwOut = 0; while( 1 ) { bResult = ReadFile(hFile, &dwIn, sizeof(DWORD)*2 , &dwOut, NULL ); if (bResult && dwOut == 0) break; if ( dwIn[0] == (DWORD)pEntry.lpData && dwIn[1] == (DWORD)pEntry.cbData ) { bIsPresent = TRUE; break; } } if (!bIsPresent) { if (NULL != m_log) m_log->print("block at [0x%x] size [%d]\n" , pEntry.lpData , pEntry.cbData ); if (bShowContent) { char* pData = (char *)pEntry.lpData; for ( unsigned k = 0 ; k < pEntry.cbData; k++ ) { if ( NULL != m_log ) m_log->print( "%c" , pData[k] ); } if ( NULL != m_log ) m_log->print("\n\n"); } } } } } CloseHandle(hFile); }
void __cdecl xf_dump() { #ifndef CONEMU_MINIMAL PROCESS_HEAP_ENTRY ent = {NULL}; HeapLock(ghHeap); //HeapCompact(ghHeap,0); char sBlockInfo[255]; PVOID pLast = NULL; size_t cbUsedSize = 0, cbBrokenSize = 0; DWORD cCount = 0; while (HeapWalk(ghHeap, &ent)) { if (pLast == ent.lpData) { msprintf(sBlockInfo, countof(sBlockInfo), "!!! HeapWalk cycled at 0x%08X, size=0x%08X\n", (DWORD)ent.lpData, ent.cbData); OutputDebugStringA(sBlockInfo); _ASSERTE(pLast != ent.lpData); break; } if (((int)ent.cbData) < 0) { msprintf(sBlockInfo, countof(sBlockInfo), "!!! Invalid memory block size at 0x%08X, size=0x%08X\n", (DWORD)ent.lpData, ent.cbData); OutputDebugStringA(sBlockInfo); _ASSERTE(((int)ent.cbData) >= 0); break; } if (ent.wFlags & PROCESS_HEAP_ENTRY_BUSY) { xf_mem_block* p = (xf_mem_block*)ent.lpData; if (p->bBlockUsed==TRUE && (p->nBlockSize+sizeof(xf_mem_block)+8)==ent.cbData) { msprintf(sBlockInfo, countof(sBlockInfo), "Used memory block at 0x" WIN3264TEST("%08X","%08X%08X") ", size %u\n Allocated from: %s\n", WIN3264WSPRINT(ent.lpData), ent.cbData, p->sCreatedFrom); cbUsedSize += p->nBlockSize; } else { msprintf(sBlockInfo, countof(sBlockInfo), "Used memory block at 0x" WIN3264TEST("%08X","%08X%08X") ", size %u\n Allocated from: %s\n", WIN3264WSPRINT(ent.lpData), ent.cbData, "<Header information broken!>"); cbBrokenSize += ent.cbData; } cCount++; pLast = ent.lpData; OutputDebugStringA(sBlockInfo); } } HeapUnlock(ghHeap); msprintf(sBlockInfo, countof(sBlockInfo), "Used size 0x" WIN3264TEST("%08X","%08X%08X") ", broken size 0x" WIN3264TEST("%08X","%08X%08X") ", total blocks %u\n", WIN3264WSPRINT(cbUsedSize), WIN3264WSPRINT(cbBrokenSize), cCount); OutputDebugStringA(sBlockInfo); #endif }