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

Linux下mprotect设置main()可写的技术疑问

关于mprotect()修改main()内存权限的问题与解答

示例代码

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

int main()
{
    long page_size = sysconf(_SC_PAGE_SIZE);
    printf("page_size    = %li\n", page_size);

    void* main_address = (void*)&main;
    printf("main_address = %p\n",main_address);
    
    void* main_start = (void*)(((uintptr_t)&main) & ~(sysconf(_SC_PAGE_SIZE) - 1));
    printf("main_start   = %p\n", main_start);

    size_t main_size = (void*)&&main_end - (void*)&main;
    printf("main_size    = %d\n", main_size);

    mprotect(main_start, main_size, PROT_READ | PROT_WRITE | PROT_EXEC);

    // nop the breakpoint to allow printf() to run!
    *((char*)&&breakpoint) = 0x90;

breakpoint:
    __asm("int $3");

    printf("\nHello, World!\n");

    return 0;
    
main_end:
}

程序输出

page_size    = 4096
main_address = 0x401156
main_start   = 0x401000
main_size    = 193

Hello, World!

技术问答

问题1:最初将main_address传入mprotect()时,因地址未对齐页边界触发「无效参数(22)」错误,传入对齐的程序入口地址main_start则可正常运行,请问main_address是什么,为何它初始未对齐?

  • main_address是main()函数在内存中的起始地址,也就是函数第一条指令的内存位置。
  • 程序内存是按页划分的(示例中为4096字节一页),但编译器链接程序时,会把代码段(包含main())放到内存页中,main()不一定刚好从页的起始位置开始——代码段通常还包含其他初始化代码、其他函数的代码,所以main()的起始地址会相对于页起始有偏移,自然不对齐页边界。而mprotect()要求第一个参数必须是页对齐地址,因为它按页管理内存权限,因此传入未对齐的main_address会触发错误。

问题2:执行mprotect(0x401000, 193, ...)启用写权限,但main_address位于0x401156(偏移342字节),main()仍可写,是否mprotect()修改的是内存页而非特定字节范围?

是的,mprotect()的作用对象是整个内存页,而非你指定的字节范围。哪怕传入的长度只覆盖页的一部分,它也会修改对应整页的权限。示例中0x401000是页起始地址,不管长度填193还是4096,整个0x401000到0x401fff的内存页都会被设置为PROT_READ | PROT_WRITE | PROT_EXEC权限,所以main()所在页内的所有区域(包括main_address位置)都具备写权限。

问题3:若mprotect()针对内存页启用写权限,是否意味着main()末尾之外的内存区域也会被设为可写?

是的。因为mprotect()修改的是整个页的权限,只要是在main_start(0x401000)所在内存页里的内容,不管是main()函数内部的代码,还是页内main()之前、之后的其他代码(比如全局初始化代码、其他小函数的代码),都会被设置为可写。示例中main_size是193,但整个页有4096字节,所以页内超出main()范围的其他区域权限也会被修改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:45:34