I have access to a remote web server running Linux, and I want to run NodeJs on it. When I try to run NodeJs though, it crashes because it cannot set a page as executable. Specifically the failure occurs in 'platform-posix.cc' inside the function 'SetPermissions'. mprotect returns -1 with errno set to EACCES. I cannot use 'paxctl' to change this.
Because I couldn't set a page as executable, I thought I might at compile time write a very long function and fill it with 'nop' instructions, and then at runtime try to set this executable page as writeable, but this too is forbidden.
So I have one more idea. Let's say I write a C source file "monkey.c" as follows:
void MyCode(void)
{
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
__asm__ volatile("nop");
....
}
Let's say I put 8 kilobytes worth of nop's inside this function. Next I compile it to a shared library as follows:
gcc -o libmonkey.so -shared -fPIC monkey.c
So now I have a shared library file named "libmonkey.so" which contains an exported function called 'MyCode' that contains 8 thousand nop's.
Then, in the v8 library, let's say we have an array of CPU instructions, something like:
char unsigned instructions[8192u] = { 0xac, 0xb4, . . . . };
So in the v8 library, we open up "libmonkey.so" and we write to it:
FILE *f = fopen("libmonkey.so", "rb+");
fseek(f, offset_of_MyCode, SEEK_SET);
fwrite(instructions, 1u, 8192u, f);
fclose(f);
Then in the v8 library, we use 'dlopen' to load this shared library, and we use 'dlsym' to find "MyCode", and then we execute it:
void *h = dlopen("libmonkey.so", RTLD_NOW);
void (*func)(void) = (void(*)(void))dlsym(h, "MyCode");
func();
dlclose(h);
This is a bit Frankenstein-ish but it will work. IDoes anybody want to help me fork the v8 repo and get this working? I've done this kind of stuff before.