2

我尝试调用mprotect主线程的堆栈,但它总是失败。每次我尝试,它都会产生一个ENOMEM错误。我已经签入 /proc/[pid]/maps 整个堆栈都映射到地址空间中。但是,我可以成功地mprotect从主堆栈调用子线程的堆栈。主线程的堆栈一定有一些特殊的东西可以防止自己被mprotect. 但我找不到任何文件。有人有想法吗?

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/mman.h>
#include <assert.h>
#include <pthread.h>
#include <stdio.h>

void * addr;
size_t size;

void * thread(void * tls) {
    sleep(1);
    if (mprotect(addr, size, PROT_NONE) == -1) perror(NULL);
    return NULL;
}

int main(int argc, const char *argv[]) {
    pthread_attr_t attr;
    pthread_getattr_np(pthread_self(), &attr);
    pthread_attr_getstack(&attr, &addr, &size);

    pthread_t th;
    pthread_create(&th, NULL, thread, NULL);
    sleep(2);
    pthread_join(th, NULL);
    return 0;
}
4

2 回答 2

3

您试图保护未映射的页面。如果查看pthread_attr_getstack的来源,会发现没有 mmap。Stack 页面是按需映射的。这可能会帮助你

于 2015-11-09T07:13:54.870 回答
0

我已使用此代码来保护内存。它适用于您的代码。像这样调用方法->

39     pthread_attr_getstack(&attr, &addr, &size);
40     __enable_execute_stack(&addr);

并编译:gcc your_code.c __enable_execute_stack_code.h -lpthread -fbuilding-libgcc

于 2015-11-10T17:40:42.340 回答