I’m try to do some nasty hacky things with dynamically generated code, and I want the OS to send me a SIGILL when it reaches an unknown opcode. This would let me add a layer of meta-information about my program and so on.
However, for my little test program, it seems the OS is not sending the SIGILL, but rather sends either a SIGBUS, or a SIGSEGV. I’m guessing this means that the page in which the memory is located has an NX bit set on it.
Any tips on how to make memory executable?
For reference, here is my test program:
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
void SIGILL_handler(int sig)
{
printf("Handling SIGILL\n");
}
typedef void(*FUNC)(void);
int main()
{
signal(SIGILL, SIGILL_handler);
int *bad = malloc(16);
memset(bad, 255, 16);
((FUNC)bad)();
printf("Returning like it's no big deal\n");
return 0;
}
mprotectis your friend here. It is POSIX compatible (SVr4, POSIX.1-2001), so it should work under OS X and Linux.should do it.
2nd edit: The compatibility of
memalignseems not to be that easy. I’d trymemalign,vallocunder OS X and Linux and if neither work, just use regularmallocand add enough bytes to the returned pointer so that it is aligned :-).