Code:
#pragma comment( lib, "advapi32.lib" )
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
PROCESSENTRY32 pe32;
HANDLE hProcessSnap;
MEMORY_BASIC_INFORMATION mbi;
SYSTEM_INFO si;
#define MAXRESERVE 0x00100000
#define PAGESIZE 0x1000
struct MEMORYOBJECT
{
MEMORY_BASIC_INFORMATION mbi;
CHAR szOjbectType[12];
CHAR szModule[MAX_PATH];
CHAR szSection[IMAGE_SIZEOF_SHORT_NAME];
BOOL bNew;
} ;
typedef struct MEMORYOBJECT *LPMEMORYOBJECT;
LPVOID lpWalkTheObject;
INT iCount;
LPMEMORYOBJECT GetPageList(INT *pCount)
{
LPMEMORYOBJECT lpList;
lpList = (LPMEMORYOBJECT)lpWalkTheObject;
if(pCount != NULL)
*pCount = iCount;
return lpList;
}
CHAR *GetMemoryType(DWORD dwPageType, CHAR *pBuffer)
{
switch(dwPageType)
{
case MEM_IMAGE:
sprintf(pBuffer, "Image ");
break;
case MEM_MAPPED:
sprintf(pBuffer, "Mapped ");
break;
case MEM_PRIVATE:
sprintf(pBuffer, "Private ");
break;
default:
sprintf(pBuffer, " - ");
break;
}
return pBuffer;
}
CHAR *GetMemoryState(DWORD dwState, CHAR *pBuffer)
{
switch(dwState)
{
case MEM_COMMIT:
sprintf(pBuffer, "Committed");
break;
case MEM_FREE :
sprintf(pBuffer, "Free");
break;
case MEM_RESERVE :
sprintf(pBuffer, "Reserved");
break;
default:
sprintf(pBuffer, "Unknown");
break;
}
return pBuffer;
}
CHAR *GetMemoryProtection(DWORD dwProtect, CHAR *pBuffer)
{
int iIndex;
CHAR *pDestination = pBuffer;
*pDestination = '-';
*(pDestination + 1) = '\0';
if(dwProtect & PAGE_READONLY)
{
sprintf(pDestination, "RO ");
pDestination += 3;
}
if(dwProtect & PAGE_READWRITE)
{
sprintf(pDestination, "RW ");
pDestination += 3;
}
if(dwProtect & PAGE_WRITECOPY)
{
sprintf(pDestination, "WC ");
pDestination += 3;
}
if(dwProtect & PAGE_WRITECOPY)
{
sprintf(pDestination, "X ");
pDestination += 3;
}
if(dwProtect & PAGE_EXECUTE)
{
sprintf(pDestination, "X ");
pDestination += 3;
}
if(dwProtect & PAGE_EXECUTE_READ)
{
sprintf(pDestination, "XR ");
pDestination += 3;
}
if(dwProtect & PAGE_EXECUTE_READWRITE)
{
sprintf(pDestination, "XRW");
pDestination += 3;
}
if(dwProtect & PAGE_EXECUTE_WRITECOPY)
{
sprintf(pDestination, "XWC");
pDestination += 3;
}
if(dwProtect & PAGE_GUARD)
{
sprintf(pDestination, "G ");
pDestination += 2;
}
if(dwProtect & PAGE_NOACCESS)
{
sprintf(pDestination, "NA");
pDestination += 2;
}
if(dwProtect & PAGE_NOCACHE)
{
sprintf(pDestination, "NC");
pDestination += 2;
}
iIndex = strlen(pBuffer);
while(iIndex < 6) pBuffer[iIndex++] = ' ';
pBuffer[6] = '\0';
return pBuffer;
}
BOOL EnableTokenPrivilege (LPTSTR privilege)
{
HANDLE hToken;
TOKEN_PRIVILEGES token_privileges;
DWORD dwSize;
ZeroMemory (&token_privileges, sizeof (token_privileges));
token_privileges.PrivilegeCount = 1;
if ( !OpenProcessToken (GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
return FALSE;
if (!LookupPrivilegeValue ( NULL, privilege, &token_privileges.Privileges[0].Luid))
{
CloseHandle (hToken);
return FALSE;
}
token_privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges ( hToken, FALSE, &token_privileges, 0, NULL, &dwSize))
{
CloseHandle (hToken);
return FALSE;
}
CloseHandle (hToken);
return TRUE;
}
VOID DisplayError(CHAR* pMessage)
{
DWORD eNum;
CHAR sysMsg[256] = {0};
CHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
printf( "\n WARNING: %s failed with error %d (%s)", pMessage, eNum, sysMsg );
}
DWORD GetProcess(char *pProcessName)
{
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
DisplayError("CreateToolhelp32Snapshot failed");
return(-1);
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return 0;
}
while (Process32Next(hProcessSnap, &pe32))
{
if(stricmp(pe32.szExeFile , pProcessName)==0)
{
CloseHandle(hProcessSnap);
return pe32.th32ProcessID;
}
}
return 0;
}
INT WalkTheMemory(HANDLE hTargetProcess)
{
LPMEMORYOBJECT lpList;
LPVOID lpMem, lpUncommited;
SYSTEM_INFO si;
DWORD dwSize, dwIndex;
/* else perform initial reserve */
dwSize = MAXRESERVE; //100,000
lpWalkTheObject = VirtualAlloc(NULL, //Any Address
MAXRESERVE,
MEM_RESERVE, //No alloc, hold for LocalAlloc
PAGE_NOACCESS); //DO a GP fault for r,w or x
if(lpWalkTheObject == NULL) return 0;
lpList = (LPMEMORYOBJECT)lpWalkTheObject;
lpUncommited = (LPVOID)lpWalkTheObject;
/* initialize list pointer to beginning of list to be walked*/
lpUncommited = (LPVOID)lpWalkTheObject;
lpList = (LPMEMORYOBJECT)lpWalkTheObject;
/* Get maximum address range from system info */
GetSystemInfo(&si);
/* walk process addresses */
lpMem = 0;
dwIndex = 0;
while (lpMem < si.lpMaximumApplicationAddress)
{
// Are we out of memory
if( ((int)lpList + 4096) >= ((int)lpWalkTheObject + MAXRESERVE) )
{
return 0;
}
//Commit the pages for retaining mem info
if( (lpList + sizeof(MEMORYOBJECT)) >= lpUncommited )
{
if (VirtualAlloc(
lpUncommited,
4096,
MEM_COMMIT,
PAGE_READWRITE) == NULL )
{
return 0;
}
lpUncommited = (LPVOID)((DWORD)lpList+ (DWORD)4096);
}
*lpList->szOjbectType = 0;
*lpList->szModule = 0;
*lpList->szSection = 0;
lpList->bNew = 0;
VirtualQueryEx(
hTargetProcess,
lpMem,
&(lpList->mbi),
sizeof(MEMORY_BASIC_INFORMATION));
/* increment lpMem to next region */
lpMem = (LPVOID)((DWORD)lpList->mbi.BaseAddress +
(DWORD)lpList->mbi.RegionSize);
lpList++;
++dwIndex;
}
dwSize = ((DWORD)lpList - (DWORD)lpWalkTheObject);
iCount = dwSize/sizeof(MEMORYOBJECT);
/* return list count */
return (iCount);
}
INT main(INT argc, CHAR **argv)
{
HANDLE Process = NULL;
CHAR szOutput[80];
LPMEMORYOBJECT pPage;
INT iPages = -1, iIndex;
if(argc == 1)
{
printf("ABORTING, process name not entered on command line\n");
return -1;
}
if ( !EnableTokenPrivilege (SE_DEBUG_NAME) )
{
DisplayError("EnableTokenPrivilge failed");
return -1;
}
Process = OpenProcess(PROCESS_ALL_ACCESS , TRUE , GetProcess(argv[1]));
if(Process == NULL)
{
DisplayError("Invalid process handle");
return -1;
}
WalkTheMemory(Process);
pPage = GetPageList(&iPages);
if(iPages == 0) return -1;
for(iIndex = 0; iIndex < iPages; iIndex++)
{
memset(szOutput, 0, sizeof szOutput);
sprintf((char *)szOutput, "%08X ", pPage->mbi.BaseAddress);
printf("BaseAddress %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
GetMemoryState(pPage->mbi.State, szOutput);
printf("State %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
GetMemoryProtection(pPage->mbi.Protect, szOutput);
printf("Protect %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
sprintf((char *)szOutput, "%08X ", pPage->mbi.RegionSize);
printf("RegionSize %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
sprintf((char *)szOutput, "%08X ", pPage->mbi.AllocationBase);
printf("AlocationBase %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
GetMemoryType(pPage->mbi.Type, szOutput);
printf("Type %s\n", szOutput);
memset(szOutput, 0, sizeof szOutput);
GetMemoryProtection(pPage->mbi.AllocationProtect, szOutput);
printf("AllocationProtect %s\n", szOutput);
printf("\n\n\n");
++pPage;
}
return 0;
}