关于 analyzing-ios-binaries
面向安全研究人员的 iOS 应用二进制分析技能,涵盖从解密到静态检查和运行时枚举的流程,帮助检查下载的应用及其组件。
主要功能
- 01分析前检查 FairPlay 加密
- 02转储解密后的应用二进制
- 03检查 Mach-O 结构与权限
- 04恢复 Objective-C 和 Swift 元数据
- 05在运行时枚举类与方法
适用场景
- 01分析静态工具无法读取的 IPA
- 02检查应用扩展和嵌入式框架
- 03查找权限暴露和硬编码密钥
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ trilwu/ secskills --skill analyzing-ios-binaries安装后在 Claude Code 中输入/analyzing-ios-binaries确认已加载。
详细介绍
分析 iOS 二进制文件
App Store 二进制文件在静态存储时经过加密,内核会在加载时解密,因此在从内存中转储解密后的映像之前,所有静态工具在下载的 IPA 上都会失效。这一步是后续所有工作的前提,也是大多数 iOS 分析在开始前就停滞的原因。
适用场景
- 你有一个 IPA 或
.app包,需要读取其中的二进制文件 class-dump没有返回任何内容或返回乱码otool显示cryptid 1- 你需要枚举 Objective-C 类、Swift 类型或导出符号
- 分析内嵌框架、应用扩展或动态库
不适用场景
- Android 目标——使用
testing-mobile-applications或相关的reversing-*技能 - 更广泛的 iOS 评估(存储、keychain、IPC)——使用
testing-mobile-applications - TLS 拦截——使用
bypassing-mobile-pinning - 越狱检测阻碍你的工具运行——先使用
bypassing-root-jailbreak-detection - 跨平台框架——Flutter、Unity 和 Xamarin 都有各自的技能;使用这些技能处理托管层,使用本技能处理原生外壳
首先检查加密状态
otool -l TargetApp | grep -A5 LC_ENCRYPTION_INFO
# cryptid 1 → FairPlay-encrypted, decrypt before anything else
# cryptid 0 → already decrypted (dev build, or you already dumped it)
对加密后的二进制文件进行后续分析毫无意义。class-dump
没有返回任何内容,几乎总是因为这个原因,而不是因为混淆。
# Decrypt on a jailbroken device by dumping the loaded image
frida-ios-dump -l # list installed apps
frida-ios-dump com.target.app # produces a decrypted IPA
bagbak com.target.app # alternative, handles extensions/frameworks well
# Rootless jailbreaks and TrollStore installs work with the same tools
# Older devices: Clutch, flexdecrypt
也要转储框架和扩展,不要只转储主二进制文件。PlugIns/
(共享表单、小组件、键盘)和 Frameworks/ 中也有各自加密的
Mach-O 文件,而且应用扩展经常包含有趣的权利,并且安全状况比主应用更弱。
Mach-O 结构和保护机制
file TargetApp # thin or fat/universal
lipo -info TargetApp # architectures present
lipo -thin arm64 TargetApp -o app64 # extract one before analysis
otool -hv app64 # header flags: PIE
otool -l app64 | rg 'LC_LOAD_DYLIB|LC_RPATH|LC_CODE_SIGNATURE|LC_ENCRYPTION'
otool -Iv app64 | head # indirect symbols
nm -m app64 | rg -v ' U ' | head # defined symbols
# Protections at a glance
otool -hv app64 | rg PIE # ASLR
otool -Iv app64 | rg stack_chk # stack canaries
otool -Iv app64 | rg objc_release # ARC in use
提取权利——它们定义了应用获准执行的操作,通常也能揭示值得关注的攻击面:
codesign -d --entitlements :- TargetApp.app
# Look for: keychain-access-groups, App Groups, associated-domains,
# get-task-allow (debuggable!), custom URL scheme claims
在生产构建中,如果 get-task-allow 为 true,就意味着该应用可以调试,这本身就是一项发现。
Objective-C
Objective-C 会在二进制文件中保留完整的类元数据,因此恢复效果很好——包括方法名、选择器、类层次结构和实例变量。
class-dump -H app64 -o ./headers # classic
class-dump-dyld # for dyld shared cache resident classes
dsdump --objc --color app64 # modern alternative, handles Swift too
# Then read the type map
rg -l 'Manager|Service|API|Auth|Crypto|Keychain|Payment' ./headers | head -20
在反汇编工具中,Objective-C 调用会经过 objc_msgSend,因此被调用方是寄存器中的选择器字符串,而不是直接分支。IDA 和 Ghidra 都有可解析这些调用的插件;没有它们,调用图基本毫无用处。
Swift
Swift 更难分析。名称经过修饰,方法分派也经常采用静态方式或通过 witness 表,而不是通过 objc_msgSend。
# Demangle what you find
nm app64 | swift demangle
xcrun swift-demangle '$s10TargetApp11AuthManagerC5loginyyF'
# Swift type metadata lives in dedicated sections
otool -l app64 | rg '__swift5_types|__swift5_proto|__swift5_reflstr'
dsdump --swift app64
对于 Swift 占比较高的应用,实用的方法是:@objc 和 @objcMembers 成员仍会出现在 Objective-C 元数据中,因此 class-dump 能提供部分映射。对于其余部分,应从字符串引用和反射段着手,而不是试图恢复完整的类列表。使用 Frida 在运行时枚举通常比静态恢复更快:
frida -U -f com.target.app -l enumerate-swift-classes.js
运行时分析
# Enumerate everything the runtime knows
objection -g com.target.app explore
# ios hooking list classes
# ios hooking search methods <keyword>
# ios hooking watch method "-[AuthManager login:]" --dump-args --dump-return
# Direct Frida for anything objection does not cover
frida -U -f com.target.app -l hooks.js
在 iOS 上,运行时分析往往比其他平台更有优势:Objective-C 运行时可以自省,因此列出类并监视方法,比阅读 objc_msgSend 分派的反汇编更快找到关键逻辑。
关注点
- 权利配置过度——与信任度较低的扩展共享 App Groups、过度共享 keychain 组,或在生产环境中启用
get-task-allow - 硬编码机密,位于
__cstring和包内的 plist 文件中 - keychain 可访问性较弱——条目使用
kSecAttrAccessibleAlways存储,而不是ThisDeviceOnly类 - 二进制文件中使用自定义加密,而非 CryptoKit/CommonCrypto
- 发布构建中残留的调试和日志代码
- 不安全的
WKWebView配置——allowFileAccessFromFileURLs,或将远程内容加载到启用 JS 桥接的视图中 - 第三方 SDK 自带网络栈和固定证书行为;枚举
Frameworks/并逐一检查
应当避免的错误辩解
- “class-dump 没有返回任何内容,说明应用经过了混淆。” 先检查
cryptid。几乎总是加密导致的。 - “我已经转储了主二进制文件,那就是整个应用。” 扩展和框架是独立的 Mach-O,拥有各自独立的授权,而且通常防护更弱。
- “这是 Swift 应用,所以什么都无法恢复。” 反射段、
@objc成员和字符串引用能帮助恢复大量信息。在运行时进行枚举。 - “静态分析就足够了。” 在 iOS 上可以检查运行时;跳过这一步得不偿失。
- “二进制文件启用了 PIE 和堆栈保护,所以安全性很强。” 这些是编译器默认设置,并不能证明应用经过了安全审查。
- “我无法越狱,所以无法分析。” 你仍然可以读取应用包、plist、授权和资源,也可以打包带有 Frida gadget 的应用以便侧载。在报告中说明这一限制造成的影响。
参考资料
testing-mobile-applications— 存储、钥匙串、IPC 及更广泛的 iOS 测试bypassing-root-jailbreak-detection— 检测机制阻碍工具使用时bypassing-mobile-pinning— 在 iOS 技术栈中拦截 TLSanalyzing-binaries— 深入分析同一 Mach-O 的原生逆向工程- frida-ios-dump、bagbak、class-dump、dsdump、objection、Hopper/IDA/Ghidra