如何强制将SIGILL发送到我的程序?

Ale*_*lex 4 c linux macos signals

我试着用动态生成的代码做一些讨厌的hacky事情,我希望操作系统在遇到未知的操作码时发送给我一个SIGILL.这将让我添加一层关于我的程序的元信息等等.

但是,对于我的小测试程序,似乎操作系统不发送SIGILL,而是发送SIGBUS或SIGSEGV.我猜这意味着内存所在的页面上设置了NX位.

有关如何使内存可执行的任何提示?

供参考,这是我的测试程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*iss 6

mprotect是你的朋友.它与POSIX兼容(SVr4,POSIX.1-2001),因此它应该在OS X和Linux下运行.

int pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) {
    perror("sysconf");
    exit(1);
}

/* allocate 16 aligned pages */
void *bad = memalign(pagesize, 16 * pagesize);
if (NULL == bad) {
    fprintf("aah, out of mem :-(\n");
    exit(1);
}

if (-1 == mprotect(bad, 16 * pagesize, PROT_READ | PROT_WRITE | PROT_EXEC)) {
    perror("mprotect");
    exit(1);
}
Run Code Online (Sandbox Code Playgroud)

应该这样做.

第二次编辑:兼容性memalign似乎并不那么容易.我试过memalign,valloc在OS X和Linux下,如果两者都不起作用,只需使用常规malloc并为返回的指针添加足够的字节,使其对齐:-).

  • 还可以考虑使用[`MMAP(3)`](http://linux.die.net/man/3/mmap),它可让您在一个系统调用与适当的保护比特分配内存,并且还避免了无意地更改恰好位于同一页面的其他内存上的保护位. (3认同)