【发布时间】:2019-07-01 14:20:59
【问题描述】:
我想暂停进程并将整个内存读取到字节缓冲区中。我怎样才能做到这一点?另外如何计算内存大小?我正在考虑使用 ReadProcessMemory
谢谢
【问题讨论】:
-
如果您有一个特定的操作系统,可能值得将其添加到问题中。这将是非常特定于平台的。
我想暂停进程并将整个内存读取到字节缓冲区中。我怎样才能做到这一点?另外如何计算内存大小?我正在考虑使用 ReadProcessMemory
谢谢
【问题讨论】:
听起来您正在寻找MiniDumpWriteDump 和相关函数。不要自己发明轮子。
【讨论】:
您可以在谷歌上轻松找到解决方案,就像我几个月前发现的那样。但简而言之,您可以使用 EnumProcesses、GetProcessMemoryInfo 和 GetProcessImageFileName 函数来实现。
您可以获得的进程标识符列表如下:
DWORD adwProcesses[1024], dwNeeded, dwProcesses;
if (!EnumProcesses(adwProcesses, sizeof(adwProcesses), &dwNeeded)) { return 1; }
您可以在其中获得所有进程标识符。所以你需要知道确切的数字,返回了多少进程
dwProcesses = dwNeeded / sizeof(DWORD);
打印或保存与您拥有的进程一样多的内存使用情况
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, adwProcesses[k]);
PROCESS_MEMORY_COUNTERS pmc;
//Get process memory info and path to process
GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc));
GetProcessImageFileName(hProcess, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
所以你得到数据 对于进程路径:
strProcessName.Format(_T("PATH: %s"), szProcessName);
页面文件内存使用情况:
strProcessPFMemory.Format(_T("%u K"), (pmc.PagefileUsage / 1024));
页面文件内存使用峰值:
strProcessPPFMemory.Format(_T("%u K"), (pmc.PeakPagefileUsage / 1024));
等等。
【讨论】:
虚拟内存通常不是连续的。 (这实际上是重点。)因此,将进程的整个虚拟内存空间复制到单个连续缓冲区中并没有任何意义,而且可能确实是不可能的。虚拟内存中会有一些空白,必须用缓冲区中的一些值来填充。这些差距可能很大,缓冲区可能很大。
执行此类操作的工具(例如,用于取证目的)通常会节省 范围的内存,元数据会指示源虚拟内存地址以供以后重新组装。
可以先使用VirtualQueryEx发现目标进程的虚拟内存范围。
看到这个问题:Enumerate the pages in a memory range
然后使用ReadProcessMemory 将数据从远程进程的虚拟内存复制到本地进程的缓冲区中。
当然,这些动作都不是原子的。如果目标进程正在运行,则虚拟内存空间可能会在您工作时发生变化。
还有可用的“工具帮助”API:Taking a Snapshot and Viewing Processes
【讨论】: