This works because function1 and function2 are the same size in memory. We need the length of function2 for our memcopy, so we need to do the following: int diff = (& main - & function2);
You will notice that you can edit function 2 to your liking, and it continues to work just fine!
By the way, a tricky trick. Without distraction, the g ++ compiler spits out an invalid conversion from void * to int ... But in fact, it compiles fine with gcc;)
Modified Sources:
//Hacky solution and simple proof of concept that works for me (and compiles without warning on Mac OS X/GCC 4.2.1): //fixed the diff address to also work when function2 is variable size #include "stdio.h" #include "stdlib.h" #include "string.h" #include <sys/mman.h> int function1(int x){ return x-5; } int function2(int x){ //printf("hello world"); int k=32; int l=40; return x+5+k+l; } int main(){ int diff = (&main - &function2); printf("pagesize: %d, diff: %d\n",getpagesize(),diff); int (*fptr)(int); void *memfun = malloc(4096); if (mprotect(memfun, 4096, PROT_READ|PROT_EXEC|PROT_WRITE) == -1) { perror ("mprotect"); } memcpy(memfun, (const void*)&function2, diff); fptr = &function1; printf("native: %d\n",(*fptr)(6)); fptr = memfun; printf("memory: %d\n",(*fptr)(6) ); fptr = &function1; printf("native: %d\n",(*fptr)(6)); free(memfun); return 0; }
Output:
Walter-Schrepperss-MacBook-Pro:cppWork wschrep$ gcc memoryFun.c Walter-Schrepperss-MacBook-Pro:cppWork wschrep$ ./a.out pagesize: 4096, diff: 35 native: 1 memory: 83 native: 1
Another point worth paying attention to: calling printf will call segfault, because printf is most likely not found due to incorrect addressing ...
source share