Ошибка сегментации, связанная с mmap - PullRequest
0 голосов
/ 06 марта 2012

Я пишу эмулятор, и мне нужно записать машинный код непосредственно в память, а затем перейти к нему (вызвать).Я выделяю память с помощью mmap, а затем записываю в нее код.Что-либо кроме сегментов «ret» или «nop».Я знаю, что mmap возвращается без ошибок, и я выделил проблему в примере, который я собрал, чтобы проиллюстрировать проблему.

#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;
}

Этот пример создает проблему.Справка?

РЕДАКТИРОВАТЬ: я должен упомянуть, что я нахожусь на Linux 2.6, x86.

1 Ответ

5 голосов
/ 06 марта 2012

Ваш код операции неверен, это работает:

if(data) {
    *p++ = 0xb8; //mov $1, %eax
    *p++ = 0x01;
    *p++ = 0x00;
    *p++ = 0x00;
    *p++ = 0x00;
    *p++ = 0xC3; //ret
}

0xb8 немедленно перемещает 32-битный бит в eax, поэтому вы должны указать все 4 байта.

...