#include #include #include #include #include #include #include #include #include #include #define DEFAULT_INCR (64*1024) LIST_ENTRY VaList; typedef struct _VAINFO { LIST_ENTRY Links; LIST_ENTRY AllocationBaseHead; MEMORY_BASIC_INFORMATION BasicInfo; } VAINFO, *PVAINFO; PVAINFO LastAllocationBase; SIZE_T CommitedBytes; SIZE_T ReservedBytes; SIZE_T FreeBytes; SIZE_T ImageCommitedBytes; SIZE_T ImageReservedBytes; SIZE_T ImageFreeBytes; #define NOACCESS 0 #define READONLY 1 #define READWRITE 2 #define WRITECOPY 3 #define EXECUTE 4 #define EXECUTEREAD 5 #define EXECUTEREADWRITE 6 #define EXECUTEWRITECOPY 7 #define MAXPROTECT 8 ULONG_PTR MappedCommit[MAXPROTECT]; ULONG_PTR PrivateCommit[MAXPROTECT]; typedef struct _MODINFO { PVOID BaseAddress; SIZE_T VirtualSize; ANSI_STRING Name; ANSI_STRING FullName; ULONG_PTR CommitVector[MAXPROTECT]; } MODINFO, *PMODINFO; #define MODINFO_SIZE 64 ULONG ModInfoNext; MODINFO ModInfo[MODINFO_SIZE]; MODINFO TotalModInfo; PMODINFO LocateModInfo( PVOID Address ) { int i; for (i=0;i<(int)ModInfoNext;i++){ if ( Address >= ModInfo[i].BaseAddress && Address <= (PVOID)((ULONG_PTR)ModInfo[i].BaseAddress+ModInfo[i].VirtualSize) ) { return &ModInfo[i]; } } return NULL; } VOID ComputeModInfo( HWND hDlg, HANDLE Process ) { PPEB Peb; NTSTATUS Status; PROCESS_BASIC_INFORMATION BasicInfo; PLDR_DATA_TABLE_ENTRY LdrEntry; LDR_DATA_TABLE_ENTRY LdrEntryData; PLIST_ENTRY LdrHead,LdrNext; PPEB_LDR_DATA Ldr; UNICODE_STRING us; int i,nIndex; HWND ComboList; HANDLE hFile; HANDLE hMappedFile; PIMAGE_DOS_HEADER DosHeader; PIMAGE_NT_HEADERS FileHeader; LPSTR p; PVOID MappedAddress; for (i=0;i<(int)ModInfoNext;i++){ if ( ModInfo[i].BaseAddress && ModInfo[i].BaseAddress != (PVOID) (-1) && ModInfo[i].Name.Buffer ) { RtlFreeAnsiString(&ModInfo[i].Name); } } ModInfoNext = 0; RtlZeroMemory(ModInfo,sizeof(ModInfo)); RtlInitAnsiString(&TotalModInfo.Name," TotalImageCommit"); ComboList = GetDlgItem(hDlg, PXPLODE_IMAGE_COMMIT); SendMessage(ComboList, CB_RESETCONTENT, 0, 0); SendMessage(ComboList, CB_SETITEMDATA, 0L, 0L); nIndex = (int)SendMessage( ComboList, CB_ADDSTRING, 0, (LPARAM)TotalModInfo.Name.Buffer ); SendMessage( ComboList, CB_SETITEMDATA, nIndex, (LPARAM)&TotalModInfo ); Status = NtQueryInformationProcess( Process, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL ); if ( !NT_SUCCESS(Status) ) { if ( Status == STATUS_INFO_LENGTH_MISMATCH ) { Status = NtQueryInformationProcess( Process, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo)-4, NULL ); if ( !NT_SUCCESS(Status) ) { return; } } else { return; } } Peb = BasicInfo.PebBaseAddress; // // Ldr = Peb->Ldr // Status = NtReadVirtualMemory( Process, &Peb->Ldr, &Ldr, sizeof(Ldr), NULL ); if ( !NT_SUCCESS(Status) ) { return; } LdrHead = &Ldr->InMemoryOrderModuleList; // // LdrNext = Head->Flink; // Status = NtReadVirtualMemory( Process, &LdrHead->Flink, &LdrNext, sizeof(LdrNext), NULL ); if ( !NT_SUCCESS(Status) ) { return; } while ( LdrNext != LdrHead ) { LdrEntry = CONTAINING_RECORD(LdrNext,LDR_DATA_TABLE_ENTRY,InMemoryOrderLinks); Status = NtReadVirtualMemory( Process, LdrEntry, &LdrEntryData, sizeof(LdrEntryData), NULL ); if ( !NT_SUCCESS(Status) ) { return; } ModInfo[ModInfoNext].BaseAddress = LdrEntryData.DllBase; us.Length = LdrEntryData.BaseDllName.Length; us.MaximumLength = LdrEntryData.BaseDllName.MaximumLength; us.Buffer = LocalAlloc(LMEM_ZEROINIT,us.MaximumLength); if ( !us.Buffer ) { return; } Status = NtReadVirtualMemory( Process, LdrEntryData.BaseDllName.Buffer, us.Buffer, us.MaximumLength, NULL ); if ( !NT_SUCCESS(Status) ) { return; } RtlUnicodeStringToAnsiString( &ModInfo[ModInfoNext].Name, &us, TRUE ); LocalFree(us.Buffer); us.Length = LdrEntryData.FullDllName.Length; us.MaximumLength = LdrEntryData.FullDllName.MaximumLength; us.Buffer = LocalAlloc(LMEM_ZEROINIT,us.MaximumLength); if ( !us.Buffer ) { return; } Status = NtReadVirtualMemory( Process, LdrEntryData.FullDllName.Buffer, us.Buffer, us.MaximumLength, NULL ); if ( !NT_SUCCESS(Status) ) { return; } RtlUnicodeStringToAnsiString( &ModInfo[ModInfoNext].FullName, &us, TRUE ); LocalFree(us.Buffer); if ( p = strchr(ModInfo[ModInfoNext].FullName.Buffer,':') ) { ModInfo[ModInfoNext].FullName.Buffer = p - 1; } hFile = CreateFile( ModInfo[ModInfoNext].FullName.Buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { return; } hMappedFile = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ); CloseHandle(hFile); if ( !hMappedFile ) { return; } MappedAddress = MapViewOfFile( hMappedFile, FILE_MAP_READ, 0, 0, 0 ); CloseHandle(hMappedFile); if ( !MappedAddress ) { UnmapViewOfFile(MappedAddress); return; } DosHeader = (PIMAGE_DOS_HEADER)MappedAddress; if ( DosHeader->e_magic != IMAGE_DOS_SIGNATURE ) { UnmapViewOfFile(MappedAddress); return; } FileHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); if ( FileHeader->Signature != IMAGE_NT_SIGNATURE ) { UnmapViewOfFile(MappedAddress); return; } ModInfo[ModInfoNext].VirtualSize = FileHeader->OptionalHeader.SizeOfImage; UnmapViewOfFile(MappedAddress); nIndex = (int)SendMessage( ComboList, CB_ADDSTRING, 0, (LPARAM)ModInfo[ModInfoNext].Name.Buffer ); SendMessage( ComboList, CB_SETITEMDATA, nIndex, (LPARAM)&ModInfo[ModInfoNext] ); ModInfoNext++; ModInfo[ModInfoNext].BaseAddress = (PVOID) (-1); LdrNext = LdrEntryData.InMemoryOrderLinks.Flink; } SendMessage(ComboList, CB_SETCURSEL, 0, 0); } ProtectionToIndex( ULONG Protection ) { Protection &= ~PAGE_GUARD; switch ( Protection ) { case PAGE_NOACCESS: return NOACCESS; case PAGE_READONLY: return READONLY; case PAGE_READWRITE: return READWRITE; case PAGE_WRITECOPY: return WRITECOPY; case PAGE_EXECUTE: return EXECUTE; case PAGE_EXECUTE_READ: return EXECUTEREAD; case PAGE_EXECUTE_READWRITE: return EXECUTEREADWRITE; case PAGE_EXECUTE_WRITECOPY: return EXECUTEWRITECOPY; default: printf("Unknown Protection 0x%lx\n",Protection); return 0; } } VOID DumpImageCommit( HWND hDlg, PULONG_PTR CommitVector ) { SIZE_T TotalCommitCount; ULONG i; CHAR szTemp[80]; TotalCommitCount = 0; for ( i=0;iBasicInfo, sizeof(VaInfo->BasicInfo), NULL ); if ( !NT_SUCCESS(Status) ) { LocalFree(VaInfo); return; } else { switch (VaInfo->BasicInfo.State ) { case MEM_COMMIT : if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) { TotalModInfo.CommitVector[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize; Mod = LocateModInfo(BaseAddress); if ( Mod ) { Mod->CommitVector[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize; } } else { if ( VaInfo->BasicInfo.Type == MEM_MAPPED ) { MappedCommit[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize; } else { PrivateCommit[ProtectionToIndex(VaInfo->BasicInfo.Protect)] += VaInfo->BasicInfo.RegionSize; } } break; case MEM_RESERVE : if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) { ImageReservedBytes += VaInfo->BasicInfo.RegionSize; } else { ReservedBytes += VaInfo->BasicInfo.RegionSize; } break; case MEM_FREE : if ( VaInfo->BasicInfo.Type == MEM_IMAGE ) { ImageFreeBytes += VaInfo->BasicInfo.RegionSize; } else { FreeBytes += VaInfo->BasicInfo.RegionSize; } break; } BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + VaInfo->BasicInfo.RegionSize); } } } BOOL ComputeVaSpace( HWND hDlg, HANDLE hProcess ) { memset(TotalModInfo.CommitVector,0,sizeof(TotalModInfo.CommitVector)); memset(MappedCommit,0,sizeof(MappedCommit)); memset(PrivateCommit,0,sizeof(PrivateCommit)); ComputeModInfo(hDlg,hProcess); if ( hProcess) { CaptureVaSpace(hProcess); } DumpImageCommit(hDlg,&TotalModInfo.CommitVector[0]); DumpMappedCommit(hDlg,MappedCommit); DumpPrivateCommit(hDlg,PrivateCommit); return TRUE; } VOID UpdateImageCommit( HWND hDlg ) { HWND ComboList; int nIndex; PMODINFO ModInfo; ComboList = GetDlgItem(hDlg, PXPLODE_IMAGE_COMMIT); nIndex = (int)SendMessage(ComboList, CB_GETCURSEL, 0, 0); ModInfo = (PMODINFO)SendMessage( ComboList, CB_GETITEMDATA, nIndex, 0 ); if ( ModInfo ) { DumpImageCommit(hDlg,&ModInfo->CommitVector[0]); } }