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

ARM64架构Mach-O文件修改.text段权限后崩溃及相关问题咨询

问题描述

我用MachOView这类可执行文件编辑器,把ARM64架构Mach-O文件的.text段权限从可读+可执行改成可读+可写+可执行后,程序一运行就崩溃。用lldb调试显示在main入口触发了EXC_BAD_ACCESS错误。

请问:

  1. 是否需要修改Mach-O文件的其他部分?如果需要,要改哪些?
  2. 如果没法用编辑器实现,手里有汇编源码的话,怎么在编译或链接阶段把.text段设置成可写且可执行?

补充背景

我修改.text权限的原因是,下面这段汇编代码生成的可执行文件,系统加载时会调用fixupPage64()修正my_data的地址,但因为.text段不可写,程序触发总线错误终止。怎么解决ldr = Label_Address引发的运行崩溃问题?

汇编代码:

.text
    .globl _main
    .p2align 2
_main:
    func_constructor

    ldr x2,=my_data

    func_destructor
    ret
    .p2align 3
my_data:    .quad 0x12345678aabbccdd

调试信息:

% lldb arm64
(lldb) target create "arm64"
Current executable set to '/Users/hopy/src/asm/arm64' (arm64).
(lldb) b main
Breakpoint 1: where = arm64`main, address = 0x0000000100003f10
(lldb) r
Process 2663 launched: '/Users/hopy/src/asm/arm64' (arm64)
Process 2663 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100003f10)
    frame #0: 0x0000000100003f10 arm64`main
arm64`main:
->  0x100003f10 <+0>:  sub    sp, sp, #0x20
    0x100003f14 <+4>:  stp    x29, x30, [sp, #0x10]
    0x100003f18 <+8>:  add    x29, sp, #0x10
    0x100003f1c <+12>: ldr    x1, #0x8c                 ; my_data + 8
Target 0: (arm64) stopped.
解决方案

一、直接修改Mach-O文件的问题

直接用编辑器改.text段权限后崩溃,核心原因是Mach-O的段权限修改需要同步更新多个结构,不是只改段的flags就行:

  • 必须同步修改__TEXT段对应的vm_protection和max_vm_protection字段(在Mach-O的segment_command_64结构里),这两个分别控制运行时的实际权限和最大可调整权限。
  • 另外,macOS/iOS的内核会强制校验可执行文件的W^X(写执行分离)安全规则,强行给.text加写权限可能触发内核防护逻辑,直接导致加载崩溃。这种方式稳定性极差,不推荐。

二、汇编源码层面的正确解决方法

你的本质问题是:把my_data放在了.text段里,ldr x2,=my_data会生成需要重定位的地址,系统加载时要修改.text段内的重定位条目,但.text默认不可写,所以崩溃。根本不需要把整个.text改成可写,有两个更合理的方案:

方案1:把数据移到.data段

把my_data放到可写的.data段里,重定位时修改的是.data段内容,完全符合系统权限规则:

.text
    .globl _main
    .p2align 2
_main:
    func_constructor

    ldr x2,=my_data

    func_destructor
    ret

.data
    .p2align 3
my_data:    .quad 0x12345678aabbccdd

方案2:若必须把数据留在.text段,编译链接时设置权限

如果因为特殊需求必须让.text段可写可执行,可通过链接器参数实现:

  1. 编译汇编文件:as -o main.o main.s
  2. 链接时指定段权限:ld -o arm64 main.o -segprot __TEXT rwx rwx
    • -segprot参数格式为:-segprot 段名 运行时权限 最大权限,rwx代表可读可写可执行。
      注意:这种方式会关闭系统的W^X防护,在现代macOS/iOS上可能被Gatekeeper等安全机制拦截,仅适合测试环境。

三、调试崩溃的额外说明

你调试时看到main入口触发EXC_BAD_ACCESS,是因为内核加载可执行文件时,发现.text段权限违反安全规则,直接拒绝执行,并非main函数指令本身有问题。解决权限或数据段的问题后,该崩溃会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:35:30