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

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

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

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

【问题讨论】:

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

标签: c# memory editing


【解决方案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。因此,例如,如果您在内存中搜索子字符串,请在查看之前读取整个内存块,而不是读取小块内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多