Родной самоизменяющийся код на Android - PullRequest
10 голосов
/ 16 декабря 2010

Я пытаюсь создать собственный 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 Ответ

11 голосов
/ 16 декабря 2010

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

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

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

...