【问题标题】:Detect when memory address is being written to检测何时写入内存地址
【发布时间】:2014-11-27 16:48:38
【问题描述】:

我有一个用作模拟系统 RAM 的字节数组。我想为给定的单元格制作一个防弹补丁,它可以检测到它何时被写入,并立即覆盖它。使用像

这样的循环
for (;;) {
    address = x;
    sleep(y);
}

有一个缺陷,即 sleep 有一个最小可能值,这似乎与模拟的帧长度几乎相同,因此它每帧只会修补一次地址。所以,如果一个游戏每帧写入 100 次,这样的补丁就没有意义了。

我有一些关于写作的钩子,但那些只能通过阅读正在执行的游戏代码来捕获写入,而我想让这些补丁适用于任何内存区域,而不仅仅是 RAM,因此我不能依赖解释模拟的代码太多(它根本不匹配我要修补的所有区域)。

所以我需要一些实用的观察点,有一个指向数组的指针,以及一个我想观察变化的字节。

【问题讨论】:

  • 如果同一页面上没有太多其他内容,保护页面和/或写保护页面可能对使用 MMU 的系统有所帮助。
  • 也许检查您选择的性能库(TAU 或 PAPI 仅举两个)是否暴露了其对内存访问的挂钩
  • 处理器有哪些内置调试器硬件?

标签: c emulation


【解决方案1】:

我会研究共享内存 ala mmap。使用 mmap,您可以让两个进程共享同一个页面,并且其中一个进程可以是只读的。

当对该内存区域发生写入时,将生成一个 SIGSEGV,您可以捕获它,然后采取某种操作。这是使用 UNIX 术语,但您可以在 windows 上做同样的事情,只是稍微复杂一些。

【讨论】:

    【解决方案2】:

    虽然 C 不是面向对象的语言,但我会在这里使用面向对象的方法:

    1. 将模拟内存包装在一个不透明的指针中,该指针只能通过一组特定的函数(例如memory_write_bytememory_read_byte)进行读写。
    2. 使内存对象维护一个函数指针列表,指向回调函数以处理写事件。每当发生写入时,让它调用所有这些回调。
    3. 想要监视内存中该点的代码部分可以向内存对象注册回调,并且每当调用回调时,它都可以根据需要修改内存。

    【讨论】:

    • 这有什么作用?任何 c 函数都不能使用包装器并写入受保护的内存。
    • +1,跨平台解决方案,@Claris,一个不透明的结构防止你读写(只能通过属性get-set方法访问),看看Mutator method跨度>
    • @Claris 这取决于您是否给他们参考。我认为建议是让一切都通过定义明确的 API。
    • 听起来我必须编辑模拟核心......如果是这样的话,这不是一个真正的选择。
    • 好的,作为替代方案,你不能在每条模拟指令运行后编辑内存吗?这假设代码结构良好,因此每次执行指令时都会运行一些循环或函数,并且假设不需要更早地修改内存。您使用的是什么模拟器,可以通过哪些方式对其进行编辑?
    猜你喜欢
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 2015-10-14
    • 2011-12-21
    相关资源
    最近更新 更多