如何为树莓派GCC可执行文件添加RWX权限自定义段
树莓派GCC自定义RWX段解决方案
问题根源
你现有链接脚本仅定义了段的位置,但未显式指定RWX权限——默认情况下自定义段会继承插入位置(.text)的RX权限,导致写入操作触发内存保护错误,最终程序崩溃。
可行方案
1. 修改链接脚本,显式设置RWX权限
更新链接脚本,明确指定段的权限属性,同时添加符号标记段的范围方便代码访问:
SECTIONS { .dictionary : ALIGN(4) { __dict_start = .; // 段起始地址符号 *(.dictionary) // 收集所有.dictionary节 . += 0x2000; // 预分配8KB空间,可按需调整 __dict_end = .; // 段结束地址符号 } : ATTRIBUTES((READ,WRITE,EXECUTE)) } INSERT AFTER .text;
ALIGN(4):适配ARM架构的内存对齐要求__dict_start/__dict_end:代码中可直接引用这两个符号获取段的地址范围ATTRIBUTES((READ,WRITE,EXECUTE)):强制设置RWX权限,覆盖默认继承属性
2. 代码中访问自定义段
通过链接脚本定义的符号,或者直接声明属于该段的缓冲区,实现代码写入与执行:
// 声明链接脚本中的段范围符号 extern char __dict_start[], __dict_end[]; // 或者直接定义属于.dictionary段的缓冲区 __attribute__((section(".dictionary"))) uint8_t code_buffer[0x2000]; // 示例:写入ARM指令并执行 void execute_custom_code() { // 写入ARM架构的返回指令(BX LR) uint32_t return_instr = 0xE12FFF1E; memcpy(code_buffer, &return_instr, sizeof(return_instr)); // 转换为函数指针并执行 void (*custom_func)() = (void(*)())code_buffer; custom_func(); }
3. 编译链接命令
使用指定的链接脚本编译,无需-N或-zexecstack(除非你还需要栈上执行代码):
# 编译目标文件 gcc -c your_source.c -o your_source.o # 链接生成可执行文件 gcc your_source.o -T your_script.ld -o your_program
4. 验证段权限
用readelf确认段权限是否正确:
readelf -l your_program | grep .dictionary
输出中需包含RWE标记,表明段已具备RWX权限。
注意事项
- 树莓派ARM架构默认开启内存保护,确保系统未限制RWX段(树莓派官方系统默认允许)
- 预分配空间大小需根据实际需求调整,避免内存溢出
- 写入的代码必须符合ARM指令集格式,注意小端字节序的要求
内容的提问来源于stack exchange,提问作者Shripathi Kamath
相关产品推荐
相关产品推荐

