Я хотел бы скопировать и вызвать функцию, но код ниже segfaults при вызове буфера. Что мне нужно изменить? (Linux, x86)функция копирования и вызова
#include <string.h>
#include <malloc.h>
#include <stdio.h>
int foo() { return 12; }
void foo_end() {}
int main() {
int s = (unsigned long long) foo_end - (unsigned long long) foo;
int (*f)() = (int (*)()) malloc (s);
memcpy ((void*) f, (const void*) foo, s);
printf ("%d %d\n", f(), foo());
}
EDIT: Рабочий раствор:
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
int foo() { return 12; }
void foo_end() {}
int main() {
int s = (unsigned long long) foo_end - (unsigned long long) foo;
int (*f)() = (int (*)()) malloc (s);
memcpy ((void*) f, (const void*) foo, s);
long ps = sysconf (_SC_PAGESIZE);
void *fp = (void*) ((unsigned long long) f & ~((unsigned long long) (ps-1)));
if (mprotect ((void*) fp, ps, PROT_READ | PROT_WRITE | PROT_EXEC)) return -1;
printf ("%d %d\n", f(), foo());
}
Вероятно, рекомендуется удалить «PROT_WRITE», чтобы предотвратить случайную модификацию после копирования кода.Кроме того, нет необходимости округлять адрес до границы страницы, и вы должны указать размер функции (если она больше одной страницы); вызов должен быть 'mprotect ((void *) f, s, PROT_READ | PROT_EXEC)' –
'mprotect' не работает в моей системе, если вы не выравниваете адрес. – Thomas