【问题标题】:Native self-modifying code on AndroidAndroid上的原生自修改代码
【发布时间】:2011-05-26 14:03:34
【问题描述】:

我正在尝试在 Android 上制作一些自修改本机代码并在模拟器中运行它。我的示例基于来自 android-ndk 的 HelloJNI 示例。它看起来像这样:

#define NOPE_LENGTH 4

typedef void (*FUNC) (void);

// 00000be4 <nope>:
//     be4: 46c0        nop         (mov r8, r8)
//     be6: 4770        bx  lr
void nope(void) {
    __asm__ __volatile__ ("nop");
}

void execute(void){
    void *code = mmap(NULL, NOPE_LENGTH, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    if (code != MAP_FAILED) {
        memcpy(code, nope, NOPE_LENGTH);

        ((FUNC)code)();
    }
}

问题是这段代码崩溃了。怎么了?

【问题讨论】:

  • 注意:如果您实际修改代码,您将需要刷新指令缓存——ARM 上的 I 和 D 缓存不一致,因此您可以在给定位置看到值的事实确实如此并不意味着 CPU 在尝试执行时会看到它们。 Dalvik 在其 JIT 编译器实现中使用 Linux cacheflush(2)。

标签: android linux arm android-ndk self-modifying


【解决方案1】:

猜测,nope() 被编译为 Thumb,但您将其称为 ARM(假设 mmap 返回字对齐指针)。要调用 Thumb 代码,应设置地址的低位。试试这样的:

( (FUNC)(((unsigned int)code)|1) )();

要正确执行此操作,您应确保分配的内存对齐(Thumb 为 2,ARM 为 4),确保您尝试运行的代码是 Thumb(或 ARM)并相应地设置位 0。

【讨论】:

  • 谢谢。使用 -marm 选项编译代码并为内存块提供正确对齐后,我成功执行了代码。
猜你喜欢
  • 2014-02-06
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
相关资源
最近更新 更多