/* * wxdemo.c * * OpenBSD W^X demonstration. * * This program allocates an anonymous RWX page, writes machine code * into it, and executes that code. * * Build: * cc -Wall -Wextra -O2 -Wl,-z,wxneeded wxdemo.c -o wxdemo * * On a normal filesystem: * ./wxdemo * * On a filesystem mounted with wxallowed: * ./wxdemo * * This example is for amd64. */ #include #include #include #include int main(void) { /* * amd64のマシンコード * 呼出側に整数の42を返す * * mov $42, %eax * ret * * Machine code: * b8 2a 00 00 00 c3 */ unsigned char code[] = { 0xb8, 0x2a, 0x00, 0x00, 0x00, 0xc3 }; size_t pagesize = (size_t)getpagesize(); /* コード実行とデータの書き込み両方が 可能なメモリ領域を取得 */ void *mem = mmap(NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); if (mem == MAP_FAILED) { perror("mmap(RWX)"); return 1; } printf("RWX mapping succeeded: %p\n", mem); /* 取得したメモリ領域にマシンコードを書き込み */ memcpy(mem, code, sizeof(code)); /* 書き込んだマシンコードを関数として定義 */ int (*function)(void) = (int (*)(void))mem; /* 定義した関数を実行 */ printf("Executing generated code...\n"); int result = function(); printf("Generated code returned: %d\n", result); if (munmap(mem, pagesize) == -1) { perror("munmap"); return 1; } return 0; }