You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在x86-64架构Linux系统中能否向虚拟地址0x0写入数据?

在x86-64 Linux系统中向虚拟地址0x0写入数据的实现方式

Linux内核默认会将虚拟地址0x0所在的内存页标记为无效,直接访问会触发SIGSEGV段错误,但通过以下几种方式可以实现向0x0地址写入数据(均需要root权限):

1. 调整内核内存防护参数

内核的vm.mmap_min_addr参数限制了用户进程可映射的最低虚拟地址,默认值一般为65536(0x10000),以此防范NULL指针解引用类攻击。要允许映射0地址,执行:

sysctl -w vm.mmap_min_addr=0

修改后,用户进程即可通过mmap系统调用手动映射0地址起始的内存页,进而对0x0地址进行读写。

2. 编写可访问0x0地址的用户态程序

以C语言为例,通过mmap映射0地址页后即可写入数据:

#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 映射0地址起始的4KB内存页,赋予读写权限
    void *null_page = mmap((void*)0, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    if (null_page == MAP_FAILED) {
        perror("mmap failed");
        exit(EXIT_FAILURE);
    }

    // 向0x0地址写入数据
    *(unsigned int*)0x0 = 0xDEADBEEF;
    // 验证写入结果
    printf("Wrote 0x%X to 0x0, read back: 0x%X\n", 0xDEADBEEF, *(unsigned int*)0x0);

    munmap(null_page, 4096);
    return 0;
}

编译运行步骤:

gcc -o write_null write_null.c
./write_null

3. 关于编译链接标志的说明

不存在单纯通过gcc/ld的编译链接标志直接让0x0地址可写的方法,因为虚拟地址的访问权限由内核页表和MMU硬件控制,编译链接阶段无法绕过内核的内存管理策略。所有能访问0x0地址的方法,都需要先调整内核相关设置或通过内核层面操作修改页表权限。

注意事项

  • 关闭vm.mmap_min_addr防护会大幅降低系统安全性,容易被利用NULL指针漏洞的恶意程序攻击,仅建议在测试环境中使用。
  • 直接修改内核页表的方式(如编写内核模块)风险极高,可能导致系统崩溃或不稳定,除非有特殊需求否则不推荐。

内容的提问来源于stack exchange,提问作者Architek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:43:20