Linuxでは、通常メモリ保護の観点からヒープ上に置かれたコードを実行することは出来ません。
試しに下のコードを実行すると、
だめなヤツ
double func(void){
return 3.14159;
}
int main(int argc, char **argv){
void *p = malloc(1000);
memcpy(p,func,1000);
printf("PI equals to %g\n", ((double (*)(void))p)());
}
Segmentation fault (コアダンプ)が発生します。
でも、システムコールmprotectをコード実行前に事前に呼び出すことで、
ヒープ上でもコードを実行可能です。
mprotectのmanページ。。。
http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/mprotect.2.html
ヒープでの関数実行を許可
#include <sys/mman.h>
#include <unistd.h>
double func(void){
return 3.14159;
}
void allow_execution(const void *addr){
long pagesize = (int)sysconf(_SC_PAGESIZE);
char *p = (char*)((long)addr & ~(pagesize - 1L));
mprotect(p, pagesize * 10L, PROT_READ|PROT_WRITE|PROT_EXEC);
}
int main(int argc, char **argv){
void *p = malloc(1000);
memcpy(p,func,1000);
allow_execution(p);
printf("PI equals to %g\n", ((double (*)(void))p)());
}
実行すると、
PI equals to 3.14159
という結果を得ます。