I am trying to write a C program on Linux that jumps to a location that can be written by the program itself.
#include <stdio.h>
int main(int argc, char* argv[]) {
char a[] = {0x41, 0x5c, 0x41, 0x5d, 0x41, 0x5e, 0x41, 0x5f, 0x0};
__asm__("pop %%r12;"
"jmp *%[a];"
"pop %%r11;" : : [a] "r" (a) : );
return 0;
}
Array a
contains instruction pop %r12; pop %r13; pop %r14; pop %r15
, and I hope to use the jmp instruction to jump to array a
's address and execute the instructions.
However, this program raises segment fault when executing. I used gcc
to compile my program and gdb
to step through each instruction. What I find is that the program successfully jumps to array a
's address, but before it can execute the first instruction, the it receives signal SIGSEGV.
Why is this happening? Does it mean that I cannot jump to a writable location? Is this a hardware limitation? (If so, how can I check whether my CPU supports this kind of jump? )
I am using a x86_64 CPU, and the program is compiled in 64-bit mode.