2010-12-16 11 views
10

Próbuję utworzyć samoczynny kod natywny na Androida i uruchomić go w emulatorze. Moja próbka jest oparta na próbce HelloJNI z android-ndk. Wygląda to tak:Macierzysty kod samoczynnie modyfikujący na systemie 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)(); 
    } 
} 

Problem polega na tym, że ten kod się zawiesza. Co jest nie tak?

+2

Uwaga: jeśli faktycznie modyfikujesz kod, będziesz musiał opróżnić pamięć podręczną instrukcji - bufory I i D w ARM nie są spójne, więc fakt, że możesz zobaczyć wartości w danej lokalizacji, nie oznacza, że ​​procesor zobaczy je, gdy spróbuje wykonać. Dalvik używa Linux cacheflush (2) w swojej implementacji kompilatora JIT. – fadden

Odpowiedz

11

Na domysły, nope() został skompilowany jako Thumb, ale nazywasz go ARM (zakładając, że mmap zwraca wskaźnik wyrównany do słowa). Aby wywołać kod Thumb, należy ustawić niski bit adresu. Spróbuj czegoś takiego:

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

Aby zrobić to poprawnie, należy zapewnić wyrównanie przydzielonej pamięci (2 dla kciuka i 4 dla ARM), upewnij się, że kod, który próbujesz uruchomić, Kciuk (lub ARM) i ustaw odpowiednio bit 0.

+0

Dziękuję. Po skompilowaniu kodu z opcją -marm i po zapewnieniu odpowiedniego wyrównania dla bloku pamięci pomyślnie wykonałem kod. –

Powiązane problemy