#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;
}
如何把全局变量放入内存保护页面
于 2025-08-25 11:12:11 首次发布