一、核心本质
macOS / iOS 基于 Mach 微内核 + BSD 层 + Sandbox.framework 实现沙盒,Xcode 只是配置、编译、挂载、权限管控沙盒规则的工具,沙盒真正执行者是系统内核与 sandboxd 守护进程。
沙盒本质:强制访问控制(MAC),给 App 进程打上权限策略,拦截所有超出策略的文件、网络、硬件、IPC、系统调用,而非简单文件夹隔离。
二、底层内核基础:Mach 与 BSD 层
1. Mach 微内核基础
iOS/macOS 内核 = XNU(Mach 微内核 + BSD 兼容层)
- Mach 负责:进程端口、任务权限、IPC、内存空间、进程凭证(cred);
- BSD 层负责:文件系统、网络、用户/组 ID、系统调用封装;
沙盒依托 Mach 任务端口 绑定到目标进程,给
task_t附加沙盒策略标签。
2. 系统调用拦截入口
所有程序读写文件、打开端口、访问摄像头最终都会调用 BSD 系统调用(open/read/write/socket/ioctl)。
XNU 内核在 BSD 系统调用钩子处插入沙盒校验逻辑:
- 进程发起系统调用;
- 内核取出该进程绑定的 Sandbox Profile(策略规则树);
- 匹配当前操作路径、资源、权限;
- 允许则放行;拒绝直接返回
EPERM权限错误,不会让操作抵达硬件/文件系统。
沙盒不是App自己限制自己,是内核在操作系统调用层面强制拦截,越狱/root本质就是绕过内核沙盒校验。
3. 系统守护进程 sandboxd
sandboxd:系统后台常驻守护,负责解析沙盒规则文件、编译策略、注入到进程、日志审计;- Xcode 不直接操作内核,而是生成
.sb沙盒规则文件,调用sandbox-exec命令,交由sandboxd加载策略并附加到App进程。
三、沙盒策略文件:.sb 语法与编译原理
1. 沙盒语言:Sandbox Profile DSL
后缀 .sb,是苹果自定义的类Scheme Lisp 语法,属于声明式权限规则,结构分三层:
(version 1)
(deny default) ; 默认拒绝所有操作(最小权限原则)
(allow file-read*) ; 按需放开指定权限
(allow file-write* (subpath "/Users/xxx/Library/Containers/xxx"))
deny default:顶层默认全部禁止,是iOS App沙盒最核心基线;- 所有
allow是白名单,不在白名单一律拦截。
2. 编译流程(Xcode 构建时)
- Xcode 根据项目配置(Capabilities、Signing、Target 类型)自动生成基础 .sb 模板;
- 项目中自定义
xxx.sb会被合并进主策略; sandbox_compile工具将可读的 DSL.sb编译为二进制沙盒字节码,精简规则树方便内核快速匹配;- 打包时嵌入到 Mach-O 可执行文件的
__LINKEDIT段,或在调试时由sandbox-exec动态加载。
四、iOS App 沙盒目录结构:路径映射原理
1. 容器根目录本质
iOS 每个安装App拥有唯一 Container Bundle ID 容器,路径固定范式:
~/Library/Containers/<BundleID>/Data/
系统通过 _sandbox_container_path 系统接口,在进程启动时虚拟绑定根路径:
进程内访问 ~/(Home目录)会被内核重定向映射到上述容器目录,App 无法跳出该容器层级。
2. 四个标准文件夹的权限绑定
Xcode 模板策略强制绑定四条路径白名单:
- Documents
允许读写,iCloud 备份默认开启;
沙盒规则:
(allow file-write* (subpath "${HOME}/Documents")) - Library/Preferences
存放
NSUserDefaultsplist,系统偏好服务专属读写权限; - Library/Caches 缓存目录,系统可自动清理,Xcode 打包标记不纳入iCloud备份;
- tmp 临时目录,进程销毁后系统可回收文件。
关键:路径隔离实现
进程调用 chdir、绝对路径 /etc、/var、其他App容器路径时,内核匹配沙盒策略,无对应 allow 规则直接拒绝,真正做到目录空间隔离。
五、Xcode 调试模式 vs 发布打包沙盒差异
1. Run 调试(Xcode 启动 App)
流程:
- Xcode 构建 App 包;
- 调用
sandbox-exec -f 编译后的策略文件 ./AppExec; sandbox-exec作为父进程fork子进程App,把沙盒策略注入子进程task端口;- lldb 附加调试,调试器进程拥有更高权限,可在控制台读取沙盒内文件(Xcode Devices里下载沙盒文件就是lldb授权读取)。
调试沙盒权限略宽松:允许连接Xcode服务器端口、允许lldb IPC通信;Archive发布包会移除调试专属权限规则。
2. Archive 打包 + App Store 签名
- Xcode 根据 Capabilities(推送、后台、iCloud、Health、NFC)逐条追加对应沙盒allow规则;
- 证书签名时,entitlements(权限文件
.entitlements)和沙盒策略强绑定;Entitlements 是 Mach-O 头部的权限标记,沙盒策略会读取entitlements字段动态开启对应权限;
- 上传App Store后,苹果服务器二次校验沙盒策略与entitlements一致性,违规直接拒审。
六、Entitlements 与沙盒的联动机制(极易混淆点)
- Entitlements(entitlements.plist) 属于 Mach-O 进程凭证(task entitlement),是进程的身份标签,标记App拥有哪些系统服务准入资格:
- com.apple.private.network.socket(网络)
- com.apple.iCloud.sync.drive(iCloud)
- com.apple.backgroundtask(后台)
- Sandbox .sb 策略 是系统调用访问过滤器,控制文件、端口、硬件能不能碰。
联动逻辑:
Entitlements 决定「你有没有资格申请权限」;沙盒策略决定「你实际能不能访问资源」。 例:开启
com.apple.networkentitlement,但沙盒没加allow network-outbound,依然无法联网。 Xcode 勾选 Capability 会同时自动补全entitlements键 + 插入沙盒对应白名单规则。
七、macOS 沙盒(Xcode macOS项目)深层区别
iOS是强制沙盒,所有第三方App必须容器隔离; macOS 分两种:
- App Sandbox(Xcode 勾选)
和iOS同源机制,容器在
~/Library/Containers/,严格文件/网络隔离,上架App Store必开; - 未开启沙盒 进程无附加sandbox策略,继承当前用户权限,可以读写用户任意文件,这是mac传统应用模式。
mac沙盒额外增加:用户文件访问弹窗授权 当沙盒App要访问下载、桌面、其他目录,内核拦截后触发系统权限弹窗,用户授权后系统临时在沙盒策略中插入一条路径allow规则,存入安全书签(Security Bookmarks)持久化权限。
八、沙盒拦截的资源全维度(内核管控范围)
1. 文件系统
- 读/写/创建/删除/软链接/硬链接/遍历目录;
- 禁止跨容器、禁止访问系统敏感目录
/private/etc、钥匙串数据库路径。
2. 网络
- 出站TCP/UDP:
network-outbound; - 入站端口监听:
network-inbound; 未允许则socket创建直接失败。
3. IPC 跨进程通信
- Mach端口通信、System V 信号量、共享内存;
- 无法直接发送消息给其他App进程,只能通过系统中间服务(通知中心、剪贴板、URL Scheme)。
4. 硬件资源
摄像头、麦克风、蓝牙、定位: 沙盒先拦截调用,触发系统权限弹窗,用户同意后内核动态放行该硬件设备节点的ioctl调用。
5. 进程管理
禁止fork、exec创建子进程(默认deny),除非策略显式允许,防止App衍生恶意程序。
九、越狱/免沙盒原理(反向理解沙盒边界)
- 越狱修改XNU内核,移除BSD系统调用前的沙盒校验钩子;
- 强行剥离进程task上绑定的沙盒策略;
- App不再受容器路径重定向限制,可以读写全盘文件,也就是彻底绕过沙盒MAC强制访问控制。
十、Xcode 层面可观测与调试沙盒的方式
- 查看编译生成的沙盒规则:Products→Show in Finder,编译产物内可找到
.sb源文件与编译后二进制; - 终端查看进程沙盒状态:
sandboxctl status <PID>
- 沙盒日志:控制台Console.app 搜索
sandboxd,所有拒绝访问行为都会打印日志,定位权限缺失; - 关闭沙盒(仅macOS非上架项目):取消勾选 Target → Signing & Capabilities → App Sandbox。
十一、极简总结链路
Xcode配置Capability/Entitlements → 生成.sb沙盒规则 → sandboxd编译注入进程Mach任务端口
→ XNU内核BSD系统调用钩子拦截所有资源访问 → 匹配白名单策略 → 放行/拒绝
容器目录由内核路径重定向实现目录隔离,全程由操作系统内核强制约束,App自身无法解除。
如果需要,我可以给你一份手写最小可运行.sb沙盒规则示例,以及Xcode手动注入自定义沙盒策略的配置步骤。