【问题标题】:Changing code at runtime在运行时更改代码
【发布时间】:2010-03-29 09:57:54
【问题描述】:

我有一个指向函数的指针(我从 vtable 获得),我想通过在运行时更改汇编代码(更改几个字节)来编辑函数。我尝试使用 memset 并尝试直接分配新值(例如 mPtr[0] = X、mPtr[1] = Y 等),但我不断收到分段错误。 如何更改代码?

(我使用的是 C++)

操作系统是windows。

【问题讨论】:

  • 你为什么要这样做呢?当然,唯一的原因是减少工作内存的数量,因为您可以从磁盘加载代码段。如果您解释一下您要做什么,也许我们可以提供帮助。
  • 自修改代码很难。该操作系统完全用汇编语言编写,因为没有中级语言具有允许自修改代码的语法:valerieaurora.org/synthesis/SynthesisOS/abs.html
  • 自修改代码在 60 年代很流行(特别是在俄罗斯,他们制造了非常出色的编译器来生成自修改代码)。虽然这种开发风格在 70 年代初期基本上被放弃了,因为(没有编译器的帮助)它很难编写并且几乎无法调试。因此,现代操作系统现在明确防范自我修改代码(借助硬件),因为在现代语言中,它(自我修改代码)通常是编码错误或恶意代码的结果。

标签: c++ assembly runtime


【解决方案1】:

一般来说:如果内存是通过 API 调用 VirtualAlloc 分配的,那么您可以通过 API 调用 VirtualProtect 更改内存属性。 使用 API 调用 VirtualQuery 检查第一个内存属性

【讨论】:

  • 谢谢,这正是我想要的
【解决方案2】:

根据操作系统和/或体系结构,您可能会或可能不会写入可执行页面。

查看英特尔 (IA-32e) 手册中有关将页面标记为可执行或只读的文档。该代码可能位于只读部分中,因此,您不能对其进行写入。

您可以将代码标记为不驻留在只读页面中,但它是特定于编译器的(JIT 编译器会这样做)。

在MSVC下,您可以使用#pragma section创建一个读写部分,并使用#pragma alloc_text将函数放入其中。

【讨论】:

    【解决方案3】:

    一般来说,您正在尝试写入代码段,而新的操作系统会阻止您这样做。这就是一些病毒的工作方式。

    有一些 API 可以消除这种保护,但它们依赖于操作系统。

    【讨论】:

      【解决方案4】:

      您的代码所在的内存部分通常标记为只读。这就是你得到分段失败的原因。您可以尝试通过编译器的特殊键(不确定)或修改二进制文件(同样,不是 100% 可能)从部分中删除此标志

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-01
        • 2013-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-09
        • 1970-01-01
        相关资源
        最近更新 更多