672 lines
17 KiB
C
672 lines
17 KiB
C
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <pviewp.h>
|
|
#include <explode.h>
|
|
|
|
#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;i<MAXPROTECT;i++){
|
|
TotalCommitCount += CommitVector[i];
|
|
}
|
|
|
|
wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_TOTALIMAGE_COMMIT,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_IMAGE_NOACCESS,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_IMAGE_READONLY,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_IMAGE_READWRITE,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_IMAGE_WRITECOPY,
|
|
szTemp
|
|
);
|
|
|
|
|
|
wsprintf(szTemp,"%d Kb",
|
|
(CommitVector[EXECUTE] +
|
|
CommitVector[EXECUTEREAD] +
|
|
CommitVector[EXECUTEREADWRITE] +
|
|
CommitVector[EXECUTEWRITECOPY])/1024);
|
|
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_IMAGE_EXECUTE,
|
|
szTemp
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpMappedCommit(
|
|
HWND hDlg,
|
|
PULONG_PTR CommitVector
|
|
)
|
|
{
|
|
SIZE_T TotalCommitCount;
|
|
ULONG i;
|
|
CHAR szTemp[80];
|
|
|
|
TotalCommitCount = 0;
|
|
for ( i=0;i<MAXPROTECT;i++){
|
|
TotalCommitCount += CommitVector[i];
|
|
}
|
|
|
|
wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_TOTALMAPPED_COMMIT,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_MAPPED_NOACCESS,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_MAPPED_READONLY,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_MAPPED_READWRITE,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_MAPPED_WRITECOPY,
|
|
szTemp
|
|
);
|
|
|
|
|
|
wsprintf(szTemp,"%d Kb",
|
|
(CommitVector[EXECUTE] +
|
|
CommitVector[EXECUTEREAD] +
|
|
CommitVector[EXECUTEREADWRITE] +
|
|
CommitVector[EXECUTEWRITECOPY])/1024);
|
|
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_MAPPED_EXECUTE,
|
|
szTemp
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpPrivateCommit(
|
|
HWND hDlg,
|
|
PULONG_PTR CommitVector
|
|
)
|
|
{
|
|
SIZE_T TotalCommitCount;
|
|
ULONG i;
|
|
CHAR szTemp[80];
|
|
|
|
TotalCommitCount = 0;
|
|
for ( i=0;i<MAXPROTECT;i++){
|
|
TotalCommitCount += CommitVector[i];
|
|
}
|
|
|
|
wsprintf(szTemp,"%d Kb",TotalCommitCount/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_TOTALPRIVATE_COMMIT,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[NOACCESS]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_PRIVATE_NOACCESS,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READONLY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_PRIVATE_READONLY,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[READWRITE]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_PRIVATE_READWRITE,
|
|
szTemp
|
|
);
|
|
|
|
wsprintf(szTemp,"%d Kb",CommitVector[WRITECOPY]/1024);
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_PRIVATE_WRITECOPY,
|
|
szTemp
|
|
);
|
|
|
|
|
|
wsprintf(szTemp,"%d Kb",
|
|
(CommitVector[EXECUTE] +
|
|
CommitVector[EXECUTEREAD] +
|
|
CommitVector[EXECUTEREADWRITE] +
|
|
CommitVector[EXECUTEWRITECOPY])/1024);
|
|
|
|
SetDlgItemText(
|
|
hDlg,
|
|
PXPLODE_PRIVATE_EXECUTE,
|
|
szTemp
|
|
);
|
|
}
|
|
|
|
VOID
|
|
CaptureVaSpace(
|
|
IN HANDLE Process
|
|
)
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
PVOID BaseAddress;
|
|
PVAINFO VaInfo;
|
|
PMODINFO Mod;
|
|
ULONG_PTR SystemRangeStart;
|
|
|
|
Status = NtQuerySystemInformation(SystemRangeStartInformation,
|
|
&SystemRangeStart,
|
|
sizeof(SystemRangeStart),
|
|
NULL);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return;
|
|
}
|
|
|
|
BaseAddress = NULL;
|
|
LastAllocationBase = NULL;
|
|
InitializeListHead(&VaList);
|
|
|
|
VaInfo = LocalAlloc(LMEM_ZEROINIT,sizeof(*VaInfo));
|
|
while ( (ULONG_PTR)BaseAddress < SystemRangeStart ) {
|
|
Status = NtQueryVirtualMemory(
|
|
Process,
|
|
BaseAddress,
|
|
MemoryBasicInformation,
|
|
&VaInfo->BasicInfo,
|
|
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]);
|
|
}
|
|
}
|