Ich versuche, einige selbstmodifizierenden nativen Code auf Android zu machen und es im Emulator ausführen. Mein Beispiel basiert auf dem HelloJNI-Beispiel von android-ndk. Es sieht so aus:Native selbstmodifizierenden Code auf Android
#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)();
}
}
Das Problem ist, dass dieser Code abstürzt. Was ist falsch?
Hinweis: Wenn Sie den Code tatsächlich ändern, müssen Sie den Anweisungscache leeren - die I- und D-Caches auf ARM sind nicht kohärent, daher bedeutet die Tatsache, dass Sie Werte an einem bestimmten Speicherort sehen können, nicht die CPU werden sie sehen, wenn es versucht, auszuführen. Dalvik verwendet Linux cacheflush (2) in seiner JIT-Compilerimplementierung. – fadden