2010-12-16 14 views
10

Estoy tratando de hacer un código nativo auto-modificable en Android y ejecutarlo en el emulador. Mi muestra está basada en la muestra HelloJNI del android-ndk. Se ve así:Código nativo de modificación automática en 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)(); 
    } 
} 

El problema es que este código está fallando. ¿Qué está mal?

+2

Nota: si modifica el código, deberá vaciar el caché de instrucciones; las cachés I y D en ARM no son coherentes, por lo que el hecho de que pueda ver valores en una ubicación determinada no significa que la CPU los verá cuando intenta ejecutar. Dalvik utiliza Linux cacheflush (2) en su implementación de compilador JIT. – fadden

Respuesta

11

En una conjetura, nope() fue compilado como el pulgar, pero que está llamando como ARM (suponiendo mmap devuelve un puntero alineados por palabras). Para llamar al código de pulgar, se debe configurar el bit bajo de la dirección. Intentar algo como esto:

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

para hacerlo correctamente, se debe asegurar la alineación de la memoria asignada (2 para el pulgar y 4 para ARM), asegúrese de que el código que está tratando de ejecutar es Pulgar (o ARM) y establecer el bit 0 en consecuencia.

+0

Gracias. Habiendo compilado el código con la opción -marm y habiendo proporcionado la alineación adecuada para el bloque de memoria, ejecuté el código con éxito. –

Cuestiones relacionadas