Это работает, потому что функция1 и функция2 имеют одинаковый размер в памяти. Нам нужна длина function2 для нашей memcopy, поэтому нужно сделать следующее: int diff = (&main - &function2);
Вы заметите, что можете редактировать функцию 2 по своему вкусу, и она продолжает работать нормально!
Кстати ловкий трюк. К сожалению, компилятор g++ выдает неверное преобразование из void* в int... Но на самом деле с gcc он отлично компилируется;)
Модифицированные источники:
//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;
}
Выход:
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
Еще одно замечание: вызов printf приведет к segfault, потому что printf, скорее всего, не будет найден из-за неправильного относительного адреса...
person
Walter Schreppers
schedule
02.03.2012