有效地扫描进程的内存

Posted

技术标签:

【中文标题】有效地扫描进程的内存【英文标题】:Efficiently scanning memory of a process 【发布时间】:2012-11-19 21:46:09 【问题描述】:

最近我整理了一个 C# 类,它可以使用 API 调用等在另一个进程内存中读取和写入字节,我相信你们都见过。

然而,我的问题与如何有效地扫描另一个进程的内存有关?我知道在达到 Int32.MaxValue 之前测试每组 4 个字节的基本方法,但我发现它(正如你想象的那样)非常耗费时间和资源。

根据我的阅读,有一种方法可以通过执行“HeapWalk”来确定进程的分配地址。谁能向我提供一些代码示例和/或有关此的信息,以及最好的解决方法是什么?

【问题讨论】:

您到底在扫描什​​么?似乎您应该在进程之间传递消息,而不是侵入它们的内存。 只是一个整数?重要吗..? 我会看看这个应用程序,它是开源的,并且完全符合您的要求。 cheatengine.org 是的,我看过源代码。我正在尝试在 C# 中实现它? 投票结束过于广泛:如果问题是关于“在字节数组/流中查找字节模式(也称为搜索子字符串)” - 大量文献可以更快地做到这一点。问题也可能是关于“如何遍历进程堆的结构”或“如何快速从其他进程读取大量数据”或如何处理检查 X64 进程的完整地址空间”或“如何查找分配区域过程”...考虑澄清/提出单独的问题... 【参考方案1】:

您正在寻找的是内存区域列表,它基本上是一对内存地址/区域大小的列表。

你必须做的是:

使用目标进程的进程 ID (PID) 获取目标进程的句柄,使用 OpenProcess 调用VirtualQueryEx函数直到你到达内存空间的末尾(即当方法的结果大于0时) 关闭您打开的进程句柄

lpAddress 开头VirtualQueryEx0x0。这将返回一个包含BaseAddressRegionSize 属性的MEMORY_BASIC_INFORMATION 结构(这表示您可以读取的内存空间)。然后使用RegionSize 值增加lpAdress 参数,因此下一次调用VirtualQueryEx 将返回下一个区域......等等。

Google OpenProcessCloseHandleVirtualQueryExMEMORY_BASIC_INFORMATION,因此您可以找到要使用的不同 P/Invoke 声明,因此您可以从 C# 调用这些 Win32 函数。

【讨论】:

感谢您的回复,这正是我想要的!【参考方案2】:

我可以给你一些建议来提高你的扫描性能。 最昂贵的操作是 I\O。因此,例如,如果您在内存中搜索子字符串,请在查看之前读取整个内存块,而不是读取小块内存。

【讨论】:

以上是关于有效地扫描进程的内存的主要内容,如果未能解决你的问题,请参考以下文章

扫描进程内存恶意域名信息

GDB:列出崩溃进程的所有映射内存区域

关闭 TSVNCache.exe 进程

Linux进程管理

Lsass.exe进程占用大量内存

如果能够并行执行很少的进程,那么能够有效地生成许多进程有什么意义呢?