【发布时间】: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