mcpField
I
ipsw

ipsw

github.com/blacktop安全101340 次安装4 周前更新
代码仓库

关于 ipsw

ipsw 是面向 Apple 固件研究人员和开发者的命令行工具,涵盖固件、二进制文件、内核及连接设备的分析。它通过多个命令组支持远程检查、提取、符号化和版本比较等工作。

主要功能

  1. 01检查并下载 Apple 固件
  2. 02提取固件组件
  3. 03分析 dyld 缓存和 Mach-O 文件
  4. 04检查内核与沙盒配置
  5. 05比较版本并符号化崩溃日志

适用场景

  1. 01下载完整固件前检查发布版本
  2. 02追踪 dyld 共享缓存中的符号和引用
  3. 03比较不同固件版本的 API 与组件
  4. 04解析崩溃日志和内核 panic 中的地址

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/blacktop/ipsw-skill --skill ipsw

安装后在 Claude Code 中输入/ipsw确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.txt
references/
class-dump.md
device.md
diffing.md
download.md
dyld.md
entitlements.md
firmware.md
kernel.md
macho.md
sandbox.md
symbolication.md

详细介绍

ipsw

ipsw 是一款用于 Apple 固件工作的命令行工具,按命令组组织(download、 extract、dyld、kernel、macho、fw、sb、ent、diff、symbolicate、idev 等)。 使用 brew install blacktop/tap/ipsw 安装(其他平台:github.com/blacktop/ipsw releases)。远程和下载命令需要网络访问;idev 需要通过 USB 连接设备。本技能介绍的是 提交 6e0291a8f(发布 3.1.725 之后)中的 ipsw;对于 3.1.725 及更早版本,请参考下方的“旧版”表格。各版本的标志会有所变化: ipsw version 可查看已安装的构建版本,ipsw <group> <command> --help 是权威信息来源。 --help 中标记为 🚧 的命令仍在开发中。

示例使用以下 Shell 变量(POSIX sh/bash/zsh 语法):

IPSW=./iPhone18,1_26.4_23E246_Restore.ipsw   # local IPSW or OTA
URL=https://updates.cdn-apple.com/...          # remote IPSW or OTA (see "Triage a release")
DSC=./dyld_shared_cache_arm64e                 # main file of an extracted cache; subcaches beside it
KC=./kernelcache.release.iPhone18,1            # extracted kernelcache
DEVICE=iPhone18,1                              # any product type from `ipsw device-list`

操作规则

以下是 Agent 使用 ipsw 时最容易出错的地方。

  1. 在命令行中明确指定所有选项。 没有终端时,ipsw 无法提示你选择: 命令会报错并停止,例如“使用 --confirm 以便在无人值守时继续”(旧版会静默跳过此步骤;见下方的“旧版”)。请直接传入选项:
    • 能匹配多个映像的短 dylib 名称(UIKit、SwiftUI、SpringBoard)会导致失败。 请传入完整安装路径,可通过以下命令查找: ipsw dyld info --dylibs --json "$DSC" | jq -r '.dylibs[].name' | grep -i <name>。
    • Fat Mach-O 文件需要 --arch arm64e;包含多个设备的 IPSW 需要 --device <product-type>。
    • 下载和 payload 搜索需要 -y/--confirm(download、ota extract --pattern)。
    • ipsw mount 会一直运行,直到按下 Ctrl+C:请传入 --detach,然后运行它打印的 hdiutil detach … 命令。
    • idev crash pull 需要路径或 --all;除非指定 -t <seconds>,否则 idev syslog 会一直输出。
  2. 下载前先远程读取。 当前的 IPSW 文件有 10–15 GB,但 --remote 命令只会获取所需内容: info --remote(KB)、extract --kernel --remote(约 75 MB)、 fw <component> --remote(数 MB 到数十 MB)。远程执行 extract --dyld 会获取数 GB。 只有需要对整个文件系统进行操作时,才下载完整映像。
  3. 不要将大量输出放进对话中。 优先使用 --json | jq,通过 -o/--output 将内容写入文件,并先查看开头或计数。转储整个 DSC 或内核会产生数百万行。
  4. 预留一次性开销并做好规划:
    • 首次对缓存运行 dyld disass/xref 时,会构建 <DSC>.a2s(耗时数分钟,约 1.5 GB)。
    • sb graph export 需要约 30 秒并会写入约 500 MB,此后查询约需 3 秒。
    • 文件系统扫描(ent --fs、macho search <IPSW>、diff)会将数 GB 的 DMG 解包并解密到当前目录。
    • 首次运行 download appledb 会将约 600 MB 的内容克隆到 ~/.config/ipsw/appledb;--no-update(download tss 也支持)会复用现有检出内容。
  5. 报告前先验证。 使用对应的反向命令交叉核对地址与符号的结果(a2s 对 symaddr);确认崩溃日志的构建版本与固件匹配后,再相信符号化结果;列出解压输出(或使用 extract --json),不要想当然地认定文件名。

选择工作流

任务从这里开始详情
查找、远程读取、下载或提取固件ipsw download appledb ... --urls、ipsw extractreferences/download.md
协处理器、exclave、iBoot、SEP、IMG4、AEA、OTA 内部结构ipsw fw <component>、ipsw img4、ipsw otareferences/firmware.md
dyld_shared_cache 中的用户空间代码ipsw dyld a2s / disass / xrefreferences/dyld.md
私有框架的 ObjC/Swift 接口ipsw class-dump、ipsw swift-dumpreferences/class-dump.md
独立二进制文件:信息、权利、签名ipsw macho info / disass / searchreferences/macho.md
内核缓存:KEXT、符号、C++ 类、系统调用ipsw kernel ...references/kernel.md
沙盒配置文件和能力相关问题ipsw sb ...references/sandbox.md
在固件映像中搜索权利ipsw ent ...references/entitlements.md
两个版本之间的变更ipsw diff、--diff/--delta 变体references/diffing.md
崩溃日志和内核崩溃ipsw symbolicatereferences/symbolication.md
通过 USB 连接的 iPhone/iPadipsw idev ...references/device.md

不下载即可排查版本

URL="$(ipsw download appledb --os iOS --device "$DEVICE" --latest --release --urls | head -1)"
ipsw info --remote "$URL"                          # version, build, devices, CPU
ipsw info --remote --list "$URL"                   # every file in the IPSW, with sizes
ipsw fw exclave --remote "$URL" --info             # exclave bundle sections (~50 MB fetched)
KC="$(ipsw extract --kernel --remote --json -o ./fw/ "$URL" | jq -r 'keys[0]')"   # just the kernelcache
ipsw dtree --remote "$URL" --summary               # DeviceTree identity

dl 和 db 分别是 download 和 appledb 的别名。单独使用 --latest 表示任意通道中的最新版本(通常是 beta):添加 --release、--beta 或 --rc,或指定 --build <BUILD> / --version <X.Y>;--type ota 会返回 OTA URL。ipsw download ipsw --device "$DEVICE" --latest --urls 可获取最新的已签名公开 IPSW,不访问 AppleDB。

用户空间:从地址到解释

ipsw dyld a2s "$DSC" 0x18ebfa9c8                                      # symbol + offset
ipsw dyld disass "$DSC" --vaddr 0x18ebfa9a8 --count 60                 # first run builds the .a2s cache
ipsw dyld xref "$DSC" 0x18ebfa9a8 --imports                            # callers in this and dependent dylibs
ipsw dyld imports "$DSC" /System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices
ipsw class-dump "$DSC" /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore \
  --class '^UIApplication$' --re -V | grep -B1 'BackgroundTask'

--re(需要 -V/--verbose)会在每个方法上方一行,以 // 0x… 注释的形式打印其实现地址,因此筛选时要保留一行前置上下文。这些地址可用于 dyld disass --vaddr。UIKit 的类位于 UIKitCore;UIKit.framework/UIKit 是一个不含 ObjC 的垫片。

内核:命名、查找、反汇编

ipsw kernel version "$KC"
mkdir -p ./syms && ipsw kernel symbolicate --signatures symbolicator/kernel --json -o ./syms/ "$KC"   # names for a stripped kernel
ipsw kernel cpp "$KC" --class IOSurfaceRootUserClient --inheritance                 # C++ classes (no ObjC in kernels)
ipsw kernel syscall "$KC"                                                           # also: mach, mig, kexts
ipsw macho disass "$KC" --fileset-entry com.apple.kernel --vaddr 0xfffffe000ab90040 --count 40

签名来自 git clone https://github.com/blacktop/symbolicator;不使用 --signatures 时,symbolicate 仍会为系统调用、Mach 陷阱、MIG 例程和 C++ 方法命名。 发布版内核已剥离符号,因此请用 --vaddr 进行反汇编。按完整 bundle ID 为 KEXT 命名:短名称会按后缀匹配 (IOKit 会解析为 com.apple.driver.ASIOKit)。

两个版本之间的变更

ipsw dyld info --dylibs --delta "$OLD_DSC" "$NEW_DSC"          # added/removed/re-versioned dylibs
ipsw class-dump "$NEW_DSC" <DYLIB_PATH> --diff "$OLD_DSC"       # ObjC API diff (new first, --diff old)
ipsw swift-dump "$NEW_DSC" <DYLIB_PATH> --diff "$OLD_DSC" > api.diff.md   # Swift API diff (long)
ipsw kernel kexts --diff "$OLD_KC" "$NEW_KC"
ipsw sb opts --diff "$OLD_KC" "$NEW_KC"
ipsw diff "$OLD_IPSW" "$NEW_IPSW" -o ./diff/ --markdown --starts --ent   # full report (slow, local IPSWs)

补丁排查清单请参阅 references/diffing.md。

能力:权利和沙盒

ipsw ent --fs --has com.apple.private.security.no-sandbox --file-only "$IPSW"   # no database needed
ipsw sb graph export "$KC" -O graph.json
ipsw sb query iokit-open IOSurfaceRootUserClient --graph graph.json -O json \
  | jq -r '.matches[] | select(.decision=="allow") | .profile' | sort -u

崩溃和内核崩溃

ipsw symbolicate panic-full-<date>.ips "$IPSW" --peek       # kernel + userspace frames, with disassembly
ipsw symbolicate crash.ips "$DSC" --unslide                  # userspace, addresses usable in static tools

固件必须与日志标头中的版本完全一致(head -1 <log>.ips | jq -r .os_version)。 如果本地没有固件,--server <URL> 会查询 ipswd 符号服务;通过 IPSW_SYMBOLICATE_API_TOKEN 传递 bearer token(参阅 references/symbolication.md)。

易踩的坑

  • dyld symaddr 和 dyld disass --symbol 匹配的是精确名称,而不是正则表达式;要匹配模式,请使用 symaddr --in <json>。disass 的符号查找提示是 --symbol-image (--image 用于选择要反汇编的整个 dylib)。
  • ObjC 实例方法名称以 - 开头,会被解析为标志:请将它们放在 -- 后面 (ipsw dyld symaddr "$DSC" --image <DYLIB> -- '-[UIApplication endBackgroundTask:]')。
  • dyld str 会搜索整个缓存,且无法按映像筛选。
  • dyld xref --all 会反汇编每个映像(非常慢);请先不加此选项运行。
  • 不带 --dyld-arch 的 extract --dyld 会提取映像中的所有架构。
  • class-dump --re 需要 -V;地址会以 // 0x… 行的形式打印在每个方法上方。
  • 在 sb 命令中,-o 表示操作列表,-O 表示输出。
  • download git 和 device-info 接受 --product / --prod,而非位置参数。

较早版本(ipsw 3.1.725 及更早版本)

检查 ipsw version。这些版本的行为有所不同;请使用右侧的解决方法:

3.1.725 及更早版本中的行为解决方法
在没有终端的情况下,提示会跳过该步骤并以状态码 0 退出(download appledb/ota 的“Continue?”、ota extract 的 payload 搜索)始终传入 --confirm/-y;检查输出,而不是退出状态
download tss --signed 在未签名时以状态码 0 退出;没有 --no-update在输出中匹配 Is still being signed / No longer being signed
不带选择器的 download kdk 不执行任何操作且以状态码 0 退出传入 --host、--build、--latest 或 --all
dyld a2f <DSC> <ADDR> 失败并提示 failed to find image containing stub targetecho <ADDR> | ipsw dyld a2f "$DSC" --in /dev/stdin
dyld webkit --diff 会拒绝第二个参数对每个缓存运行 ipsw dyld webkit --json "$DSC" | jq -r .version
dyld info --dylibs --diff/--delta 没有 --json;即使使用 --no-color,--diff 和 kernel kexts --diff 仍会输出 ANSI 控制码使用 --delta(Markdown),以及 references/kernel.md 中的 kexts --json 方法
class-dump --diff 会忽略 @property 变更从两个缓存中转储该类,然后运行 diff -u
如果 <dir> 不存在,kernel symbolicate -o <dir> 会失败先运行 mkdir -p <dir>
fw exclave/dcp/c1 --info 会将获取的固件留在 ./<BUILD>__<DEVICE>/ 下在临时目录中运行
extract --remote --kbag 会下载每个完整的 IM4P(约 150 MB)预留相应空间,或仅提取需要的 IM4P
extract 没有 --json-format artifacts使用普通的 --json:在 --kernel 后运行 jq -r 'keys[0]',在 --sptm/--pattern 后运行 .[]
ota ls --payload --json 会在 JSON 前输出横幅在 jq 前运行 sed -n '/^\[/,$p'
dyld search objc 会针对一个映像输出 relative method selectors 错误忽略该错误;其他结果有效
device-info 和 download git 会静默忽略位置参数使用 --prod / --product

参考文件

阅读与任务相匹配的文件;每个文件都以目录表开头。

  • references/download.md:查找 URL、远程读取、下载、提取、AEA 密钥、配置
  • references/firmware.md:info、mount、dtree、fw 组件、IMG4、AEA、OTA payload
  • references/dyld.md:DSC 地址、反汇编、交叉引用、导入项、软链接、提取
  • references/class-dump.md:ObjC/Swift 转储、标头生成、API 差异
  • references/macho.md:Mach-O 信息、权利、签名、搜索、lipo/sign/patch
  • references/kernel.md:内核符号、C++ 类、系统调用/MIG、KEXT 提取、KDK 类型
  • references/sandbox.md:配置文件反编译、功能查询、沙盒差异
  • references/entitlements.md:权利搜索和数据库
  • references/diffing.md:版本差异和补丁搜寻清单
  • references/symbolication.md:崩溃和内核崩溃符号化
  • references/device.md:用于通过 USB 连接设备的 idev 命令

评论

支持 Markdown