Собственный самомодифицирующийся код на Android

Я пытаюсь сделать собственный самонастраивающийся собственный код на Android и запустить его в эмуляторе. Мой образец основан на примере HelloJNI от android-ndk. Это выглядит так:

#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)();
    }
}

Проблема в том, что этот код сбой. Что не так?

Ответ 1

Угадав, nope() был скомпилирован как Thumb, но вы называете его ARM (если mmap возвращает указатель, выровненный по словам). Для вызова Thumb-кода должен быть установлен младший бит адреса. Попробуйте что-то вроде этого:

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

Чтобы сделать это правильно, вы должны обеспечить выравнивание выделенной памяти (2 для Thumb и 4 для ARM), убедитесь, что код, который вы пытаетесь запустить, - Thumb (или ARM) и соответственно установите бит 0.