Reputation: 21
I am writing an emulator and I need to write machine code directly to memory, then jump to (call) it. I allocate the memory with mmap, and then write the code to it. Anything other than a "ret" or "nop" instruction segfaults. I know mmap returns without error, and I have isolated the problem in an example I put together to illustrate the issue.
#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>
int main()
{
uint8_t *data = mmap(NULL, 3 * sizeof(uint8_t), PROT_EXEC|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0), *p;
p = data;
if(data) {
*p++ = 0xb8; //mov $1, %eax
*p++ = 0x01;
*p++ = 0xC3; //ret
} else
perror("mmap");
uint8_t (*fp)();
fp = (void*) (data);
printf("%u\n",(uint8_t) fp());
return 0;
}
That example produces the problem. Help?
EDIT:I should mention I'm on Linux 2.6, x86.
Upvotes: 0
Views: 1591
Reputation: 3970
Your opcode is incorrect, this works:
if(data) {
*p++ = 0xb8; //mov $1, %eax
*p++ = 0x01;
*p++ = 0x00;
*p++ = 0x00;
*p++ = 0x00;
*p++ = 0xC3; //ret
}
0xb8 is moving a 32bit immediate into eax, so you have to specify all 4 bytes.
Upvotes: 5