百趣云 - Mach-O
type: channel
link: https://teawhites.cn/index.php/tag/Mach-O/
items: iOS 签名机制与 Mach-O：理解 fairplay 之前先理解加载

iOS 签名机制与 Mach-O：理解 fairplay 之前先理解加载
type: item
date: 2026-08-30T15:53:48+08:00
description: Mach-O：iOS 二进制的解剖图iOS/macOS 的可执行文件是 Mach-O 格式，结构分三段：Mach Header（头部：架构、加载命令数量） ↓ Load Commands（加载命令：告诉系统怎么加载） ↓ Segments/Sections（数据段：代码、数据、符号）逆向必知的几个 Load Command：LC_SEGMENT_64：定义内存段（__TEXT 代码段、__DATA 数据段）LC_ENCRYPTION_INFO_64：FairPlay 加密信息，cryptid=1 表示加密，砸壳就是把它清 0 并替换明文段LC_CODE_SIGNATURE：代码签名位置LC_LOAD_DYLIB：依赖的动态库列表——MonkeyDev 注入就是在这里加一条分析工具：otool -l 看加载命令，MachOView 图形化查看（强烈推荐，结构一目了然）。代码签名：iOS 安全的地基iOS 的"所有代码必须签名"机制，是理解越狱、砸壳、重打包一切问题的前提：苹果签名：App Store 的包由苹果私钥签名，系统信任开发者签名：开发调试包由开发者证书 + 描述文件签名，描述文件绑定设备 UDID企业签名：企业证书签的包任意设备可装（苹果监管之外的灰色地带，常被吊销）验证签名：codesign -dv --verbose=4 Target.app # 看签名者、team id、entitlements重打包必须重签名：改了二进制或注入 dylib 后原签名失效，系统拒绝加载。重签名流程：# 1. 删掉原签名 rm -rf Target.app/_CodeSignature # 2. 先签所有 framework 和 dylib（从内到外） codesign -fs "Apple Development: xxx" Target.app/Frameworks/*.framework # 3. 最后签主包，带上 entitlements codesign -fs "Apple Development: xxx" --entitlements ent.plist Target.appFairPlay 加密的实现位置理解砸壳原理需要知道 FairPlay 加密的是什么：加密的只是 __TEXT 段的代码页（不是整个文件）密钥在苹果的 FairPlay 体系里，设备加载时由内核/AMFID 解密LC_ENCRYPTION_INFO_64 里的 cryptoff/cryptsize 标记加密范围，cryptid 标记是否加密砸壳工具做的事：等系统解密后从内存抠明文，写回 cryptoff 指定的文件偏移，清 cryptid。所以砸壳产物在非越狱设备上也能静态分析——它已经是普通未加密二进制了。精髓：三个实战认知__RESTRICT 段的反注入。二进制里若有 __RESTRICT/__restrict 段，DYLD_INSERT_LIBRARIES 注入会被系统拒绝。砸壳后重打包时可以顺手删掉这个段（MachOView 或 optool），为后续注入扫清障碍。Fat Binary 的架构拆分。App Store 包常含 arm64/arm64e 多架构，分析前用 lipo -thin arm64 抽单架构，IDA/Hopper 加载更快，也避免架构混淆。Swift 二进制的符号特征。Swift 方法名是 mangled 格式（$s7TargetApp11SignManagerC7getSign...），用 swift-demangle 还原可读；class-dump 对纯 Swift 类效果差，要配合 swift-dump 或 IDA 的 Swift 插件。总结Mach-O 三段结构：头部、加载命令、数据段，MachOView 是查看神器代码签名是 iOS 安全地基，重打包必须重签名（从内到外）FairPlay 只加密 __TEXT 段，砸壳 = 内存抠明文 + 清 cryptid__RESTRICT 段防注入，重打包时顺手删除交流微信：run1255