I am trying to make some self-modifing native code on Android and run it in the emulator. My sample is based on the HelloJNI sample from the android-ndk. It looks like this:
#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)();
}
}
The problem is that this code is crashing. What is wrong?
At a guess,
nope()
was compiled as Thumb, but you're calling it as ARM (assuming mmap returns a word-aligned pointer). To call Thumb code, the low bit of the address should be set. Try something like this:To do it properly, you should ensure alignment of the allocated memory (2 for Thumb and 4 for ARM), make sure that the code you're trying to run is Thumb (or ARM) and set the bit 0 accordingly.