如何把全局变量放入内存保护页面

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

// 获取系统页大小
static size_t get_pagesize() {
  static size_t pagesize = 0;
  if (pagesize == 0)
        pagesize = sysconf(_SC_PAGESIZE);
  printf("pagesize is %ld\n",pagesize);
  return pagesize;
}



// 宏:定义受保护全局变量
#define PROTECTED_GLOBAL(type, name, init_val)       \
  static type *name##_ptr = NULL;                 \
  static void init_##name(void) __attribute__((constructor)); \
  static void init_##name(void) {                 \
        install_sigsegv_handler();                  \
        size_t pagesize = get_pagesize();           \
        name##_ptr = mmap(NULL, pagesize, PROT_NONE, \
                MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
        if (name##_ptr == MAP_FAILED) {            \
          perror("mmap");                         \
          exit(1);                                \
        }                                           \
        /* 临时允许写入初始化值 */                   \
        mprotect(name##_ptr, pagesize, PROT_WRITE); \
        *name##_ptr = init_val;                     \
        /* 设置为不可访问 */                         \
        mprotect(name##_ptr, pagesize, PROT_NONE);  \
  }                                               \
  static inline type get_##name(void) {           \
        return *name##_ptr;                         \
  }                                               \
  static inline void set_##name(type val) {       \
        *name##_ptr = val;                          \
  }

void sigsegv_handler(int sig, siginfo_t *si, void *unused) {
  printf("触发访问保护!地址: %p\n", si->si_addr);

  exit(1);
}

// 安装 SIGSEGV 信号处理
static void install_sigsegv_handler() {
  static int installed = 0;
  if (installed) return;
  struct sigaction sa;
  sa.sa_flags = SA_SIGINFO;
  sa.sa_sigaction = sigsegv_handler;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGSEGV, &sa, NULL);
  installed = 1;
}


// 定义受保护全局变量
PROTECTED_GLOBAL(int, g_var, 42)

  int main() {
        printf("尝试读取 g_var...\n");
        printf("%d\n",*g_var_ptr);

        return 0;
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿越辩证法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值