I'm trying to execute machine code stored in array on first Raspberry Pi under ArchLinux. I've done it under x86, but I can't get what I'm doing wrong under ARMv6. The problem is that it doesn't matter what code is in the array, it will always crash after executing first instruction. Code is compiled with Thumb interworking disabled under gcc 5.2.0.
This is the code I've used for testing:
#include <stdio.h>
char shellcode[] = {
0x04, 0xb0, 0x2d, 0xe5, // push {r11}
0x00, 0xb0, 0x8d, 0xe2, // add r11, sp, #0
0x00, 0x00, 0xa0, 0xe1, // nop
0x00, 0x00, 0xa0, 0xe1, // nop
0x00, 0x00, 0xa0, 0xe1, // nop
0x00, 0xd0, 0x4b, 0xe2, // sub sp, r11, #0
0x04, 0xb0, 0x9d, 0xe4, // pop {r11}
0x1e, 0xff, 0x2f, 0xe1 // bx lr
};
void shellcode2() {
asm("mov r0, r0");
asm("mov r0, r0");
}
typedef void (*entry_t)();
int main() {
entry_t entry = (entry_t)(shellcode);
entry();
return 0;
}
Machine code was taken from the shellcode2
function disassembly, I don't know if it is proper way to do this but the problem is that even if first instruction in shellcode is a nop - it'll crash.
Program received signal SIGSEGV, Segmentation fault.
0x00020704 in shellcode ()
(gdb) disas /r
Dump of assembler code for function shellcode:
=> 0x00020704 <+0>: 04 b0 2d e5 push {r11} ; (str r11, [sp, #-4]!)
0x00020708 <+4>: 00 b0 8d e2 add r11, sp, #0
0x0002070c <+8>: 00 00 a0 e1 nop ; (mov r0, r0)
0x00020710 <+12>: 00 00 a0 e1 nop ; (mov r0, r0)
0x00020714 <+16>: 00 00 a0 e1 nop ; (mov r0, r0)
0x00020718 <+20>: 00 d0 4b e2 sub sp, r11, #0
0x0002071c <+24>: 04 b0 9d e4 pop {r11} ; (ldr r11, [sp], #4)
0x00020720 <+28>: 1e ff 2f e1 bx lr
End of assembler dump.
Am I missing something or just doing it plain wrong on ARMv6? If anybody can point me in the proper direction I would be grateful.
Thanks in advance.