Я пытаюсь прочитать значения в памяти относительно %rip
на X86_64. В моем первом примере я просто хочу прочитать
Если я напишу следующий код на C, я могу вызвать его и получить правильный результат (\x....C3C9
):
void * test() {
__asm("mov 0(%rip), %rax");
}
Сгенерированный код выглядит следующим образом:
0000000000400624 <test>:
400624: 55 push %rbp
400625: 48 89 e5 mov %rsp,%rbp
400628: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 40062f <test+0xb>
40062f: c9 leaveq
400630: c3 retq
Однако, если я теперь помещу этот код непосредственно в память и выполню его, я получу ошибку, в то время как я ожидаю прочитать \x0000C3C9
:
int main()
{
int codesize = 9;
unsigned char * code = (unsigned char*)malloc(1024);
memcpy(code, "\x48\x8B\x5\x0\x0\x0\x0\xC9\xC3\x00\x00", codesize + 2);
mprotect(code, codesize, PROT_EXEC | PROT_READ);
goto *code;
}
Что я делаю не так?
редактировать
Ответ в том, что я не должен был использовать malloc
, но mmap
для выделения области памяти, выровненной по страницам:
(unsigned char*)mmap(NULL, 1024, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
И, конечно, я должен был проверить возвращаемое значение вызова на mprotect
. Он вернул -1, отметив, что это не удалось.