Je voudrais copier et appeler une fonction, mais le code ci-dessous segfaults lors de l'appel du tampon. Qu'est-ce que je dois changer? (Linux, x86)Fonction de copie et d'appel
#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: Solution de travail:
#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());
}
Probablement une bonne idée de supprimer 'PROT_WRITE', pour éviter une modification accidentelle après avoir copié le code.En outre, il n'est pas nécessaire d'arrondir l'adresse à une limite de page, et vous devez indiquer la taille de la fonction (au cas où elle dépasse une page); l'appel doit être 'mprotect ((void *) f, s, PROT_READ | PROT_EXEC)' –
'mprotect' échoue sur mon système lorsque l'alignement de l'adresse n'est pas effectué. – Thomas