有時想分析執行中的process 記憶體長相, 可藉由memory walk 的方式將process 的所有可讀取憶膿內容, dump 出來.
一. Get processID
二, 藉由 VirtualQueryEx(hProcess, lpMem, &(lpList->mbi), sizeof(MEMORY_BASIC_INFORMATION)); 讀出記憶的size and pointer.
這過程像是資料結構的link-list, nextPTR=cur+size;
三. if(ReadProcessMemory(hProcess, lpList->mbi.BaseAddress, readBuff,
lpList->mbi.RegionSize, &dwBread))
四. write to file. and into next block
int LL;
//#define TOTALVMRESERVE 0x00100000
#define TOTALVMRESERVE 0x00500000
#define PAGESIZE 0x1000
struct VMOBJECT
{
MEMORY_BASIC_INFORMATION mbi;
char szObjType[12];
char szModule[MAX_PATH];
char szSection[IMAGE_SIZEOF_SHORT_NAME];
BOOL bNew;
};
typedef struct VMOBJECT* LPVMOBJECT;
void CCreateProcessExDemoDlg::OnButton1()
{
// START - Declarations for Process Memory Dumper Engine -
MEMORY_BASIC_INFORMATION mbi;
LPVMOBJECT lpList;
SYSTEM_INFO si;
LPVOID * lpMem;
//lpUncommited, memStep;
LPVOID lpUncommited, memStep;
LPVOID readBuff;
// DWORD dwSize, dwIndex, dwBread, dwBwrite;
SIZE_T dwSize, dwIndex, dwBread;
DWORD dwBwrite;
HANDLE hProcess;
HANDLE hFile;
// END - Declarations for Process Memory Dumper Engine -
HANDLE aa;
FILE* fp;
fp = fopen("d:\\aazz.txt", "w");
if (1)
{
DWORD pProcessID = 1308; // fill process ID here
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_OPERATION,
NULL, pProcessID);
if (hProcess == NULL)
{
AfxMessageBox("Cannot open Process");
return;
}
CString fileName;
fileName = "d:\\ProcID_Meme.bin";
LPCSTR dumpFineName = (LPCSTR)(LPCTSTR)fileName;
hFile = CreateFileA(dumpFineName, FILE_ALL_ACCESS, FILE_SHARE_WRITE, NULL,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox("Can't Create Dump File");
return;
}
GetSystemInfo(&si);
dwSize = TOTALVMRESERVE;
// memStep = VirtualAlloc(NULL, TOTALVMRESERVE, MEM_RESERVE, PAGE_NOACCESS);
memStep = VirtualAlloc(NULL, 1000*sizeof (VMOBJECT), MEM_RESERVE, PAGE_NOACCESS);
if (memStep == NULL)
return;
lpList = (LPVMOBJECT)memStep;
lpUncommited = (LPVOID)memStep;
lpMem = 0;
dwIndex = 0;
while (lpMem < si.lpMaximumApplicationAddress)
{
if (((int)lpList + 4096) >= ((int)memStep + TOTALVMRESERVE))
return;
if (lpList + sizeof(VMOBJECT) >= lpUncommited)
{
if (VirtualAlloc(lpUncommited, 4096, MEM_COMMIT, PAGE_READWRITE) == NULL)
{
// AfxMessageBox("A problem occurred during Memory Walking");
// return;
}
lpUncommited = (LPVOID)((SIZE_T)lpList + (SIZE_T)4096);
// lpUncommited = (LPVOID)((DWORD)lpList + (DWORD)4096);
}
*lpList->szObjType = 0;
*lpList->szModule = 0;
*lpList->szSection = 0;
lpList->bNew = 0;
VirtualQueryEx(hProcess, lpMem, &(lpList->mbi), sizeof(MEMORY_BASIC_INFORMATION));
lpMem = (LPVOID *)((SIZE_T)lpList->mbi.BaseAddress + (SIZE_T)lpList->mbi.RegionSize);
// lpMem = (LPVOID)((DWORD)lpList->mbi.BaseAddress + (DWORD)lpList->mbi.RegionSize);
readBuff = VirtualAlloc(NULL, lpList->mbi.RegionSize, MEM_COMMIT, PAGE_READWRITE);
if(ReadProcessMemory(hProcess, lpList->mbi.BaseAddress, readBuff,
lpList->mbi.RegionSize, &dwBread))
{ }
else
{
int aa=GetLastError();
}
fprintf(fp, "%x: %x\n", lpList->mbi.BaseAddress, dwBread);
if ((lpList - memStep) > 109)
{
int bb;
bb= 0;
}
if (dwBread != 0 && ((__int64)(lpList->mbi.BaseAddress)) ==0x1b82e7c6000)
{
WriteFile(hFile, readBuff, dwBread, &dwBwrite, NULL);
}
VirtualFree(readBuff, lpList->mbi.RegionSize, MEM_DECOMMIT);
lpList++;
++dwIndex;
}
CloseHandle(hProcess);
CloseHandle(hFile);
// LoadProcesses();
}
fclose(fp);
}
reference: https://sourceforge.net/projects/procmemdumper/files/
#fix for 64 bits process