- 文档
- 教程
- 网络安全
【免费下载链接】mastg
The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.
调试符号(debug symbols)是 iOS 应用编译产物中极易被忽视的安全泄漏面:它们会把类名、方法名、函数名乃至源码文件和行号原样暴露在二进制中,为逆向分析者提供“地图”。本指南以 OWASP MASTG 的 MASTG-KNOW-0063 知识条目为主线,结合仓库中的 MASTG-TEST-0219 测试用例、MASTG-TECH-0113 检测技术与相关工具文档,系统讲解 iOS 调试符号的产生机制、dSYM 文件在发布与崩溃符号化中的作用,以及如何在 Xcode 构建配置中正确剥离符号、用 radare2/objdump/nm 验证发布包,最终把“发布即干净”的安全实践落到可执行的检查清单。
调试符号是什么:编译产物中容易被忽略的信息泄漏面
当 iOS 应用被编译时,编译器会为应用内的每一个二进制(包括主可执行文件、内嵌 framework 和扩展)生成调试符号。这些符号包含类名、全局变量名以及方法名和函数名,并被映射到具体的源文件和行号。从安全测试角度看,它们是无意中随应用一起分发的“源码地图”:
- 逆向工程师可以用
nm、objdump、radare2 等工具直接读取符号表,获得应用中所有内部函数的名称; - 函数名通常能直接揭示其用途(例如
jailbreakDetection、_isDebugged、_disable_gdb),大幅降低理解二进制逻辑的成本; - 调试符号还携带源文件路径与行号信息,进一步帮助攻击者还原代码结构。
MASTG 在 MASTG-KNOW-0063 中给出的核心原则是:已编译的二进制只应包含执行所需的元数据。调试符号和其他非必要的元数据会暴露内部实现细节(例如能暗示函数用途的函数名),它们对应用运行毫无必要,应通过适当的编译器设置在发布构建中剥离。
需要特别说明的是,这里的“调试符号”与“符号剥离”既有重叠又存在边界。MASTG 在 MASTG-KNOW-0089(iOS 混淆)中明确指出:符号剥离会移除 Mach-O 二进制中的符号信息(包括函数名等便于逆向的元数据),是原生代码混淆的一种基础形式;但它不改变控制流、不编码字符串,也无法移除 Objective-C 与 Swift 运行时必需的元数据(例如动态派发、反射、@objc互操作、storyboard 引用等所依赖的名称)。因此调试符号剥离是发布安全的第一步,而非全部。
Debug 构建与 Release 构建的差异:dSYM 文件的诞生
Debug 构建:符号默认嵌入二进制
根据 MASTG-KNOW-0063 的说明,Debug 构建默认会把调试符号包含在编译后的二进制中。这种构建面向开发调试,符号就地嵌入,方便断点、栈回溯与单步执行,但代价是二进制体积增大,且符号信息随包分发。
Release 构建:DWARF with dSYM File与分离式调试信息
与 Debug 构建相反,Release 构建将 Debug Information Format 设置为DWARF with dSYM File时,编译器会生成独立的dSYM(Debug Symbol)文件来承载调试信息,从而减小分发应用的体积。这种方式与 Linux 工具链中常见的 split DWARF(-gsplit-dwarf)思路类似:调试信息从二进制中剥离出来单独存放,按需使用。
dSYM 文件的另一个关键用途是崩溃报告符号化(symbolication):发布后的应用在崩溃时产生的日志只包含内存地址,开发者可以把 dSYM 文件上传到 Apple 的符号服务器,将崩溃日志中的地址还原为可读的函数名和行号。也就是说,dSYM 让开发者既能从发布包中剥离调试符号,又不牺牲崩溃分析能力——这正是该方案的核心价值所在。
Xcode 构建设置全景
MASTG 的测试用例 MASTG-TEST-0219 明确列出了与调试符号相关的两个核心 Xcode 构建设置:
| 构建设置 | 位置 | 说明 |
|---|---|---|
| Generate Debug Symbols | Build Settings > Apple Clang - Code Generation > Generate Debug Symbols | 设为Yes时,Xcode 会为编译产物添加调试符号;发布前应设为No |
| Debug Information Format | Build Settings > Build Options > Debug Information Format | 决定调试信息的格式,两个选项见下 |
Debug Information Format的两个选项:
DWARF:调试信息直接嵌入二进制内部(Debug 构建的典型形态,也会增大分发体积);DWARF with dSYM File:生成包含调试信息的独立 dSYM 文件,发布构建应选用此选项。
发布前的推荐组合(来自 MASTG-TEST-0219):
- 将
Generate Debug Symbols设置为No,确保最终二进制不含调试符号; - 将
Debug Information Format设置为DWARF with dSYM File; - 妥善保管 dSYM 文件,切勿随应用一起分发——只在内部用于发布后的崩溃符号化。
另外,测试用例还提醒了一个容易混淆的点:编译后的 iOS 应用中,符号名可能经过名称改编(name mangling)和额外的混淆处理。标准改编名可以通过反改编工具还原(见 MASTG-TECH-0114),但自定义混淆手段可能无法被反改编工具有效还原。
静态检测方法:确认发布二进制中不存在调试符号
MASTG 将调试符号检测定位为纯静态测试:MASTG-TEST-0083 的“Dynamic Analysis”一节明确指出“动态分析不适用于查找调试符号”——符号是编译期产物,静态读取符号表即可判定。该旧版测试(已由 MASTG-TEST-0219 取代)给出的核心检测思路是:用objdump(来自 GNU binutils)或llvm-objdump检查应用的所有二进制,带调试符号的条目会以d(debug)标志标记。
方法一:objdump 符号表扫描
MASTG-TEST-0083 提供的经典示例——对 iOS 主应用可执行文件TargetApp运行objdump --syms,即可看到典型的存在调试符号的输出。符号条目中以d标志出现的行,就是调试符号:
$ objdump --syms TargetApp 0000000100007dc8 l d *UND* -[ViewController handleSubmitButton:] 000000010000809c l d *UND* -[ViewController touchesBegan:withEvent:] 0000000100008158 l d *UND* -[ViewController viewDidLoad] ... 000000010000916c l d *UND* _disable_gdb 00000001000091d8 l d *UND* _detect_injected_dylds 00000001000092a4 l d *UND* _isDebugged ...注意上例中_disable_gdb、_detect_injected_dylds、_isDebugged这类符号名——它们直接揭示了二进制中存在反调试逻辑,这正是调试符号泄漏内部实现细节的典型实例。objdump手册中记录了其他各种符号标志字符的含义,可用于进一步筛选。
方法二:nm 对比法(更精准的调试符号判定)
MASTG-TECH-0113 提供了更精准的方法:普通的nm调用不会打印调试符号,而nm -a会连调试符号一并输出。对两次输出做 diff,即可隔离出全部调试符号;若 diff 结果为空,则说明二进制中没有调试符号:
$ diff <(nm MASTestApp) <(nm -a MASTestApp) ... 28a228 > 0000000100009928 - 01 0000 FUN _$s10MASTestApp11ContentViewV7SwiftUI0D0AadEP05_makeD4List4view6inputsAD01_dH7OutputsVAD11_GraphValueVyxG_AD01_dH6InputsVtFZTW 30a231 > 000000010000992c - 01 0000 FUN _$s10MASTestApp11ContentViewV7SwiftUI0D0AadEP14_viewListCount6inputsSiSgAD01_dhI6InputsV_tFZTW 31a233,234 > 0000000100009944 - 01 0000 FUN _$s10MASTestApp11ContentViewV7SwiftUI0D0AadEP4body4BodyQzvgTW > 0000000000000000 - 00 0000 GSYM _$s10MASTestApp11ContentViewVAC7SwiftUI0D0AAWL 32a236 > 000000010000a220 - 01 0000 FUN _$s10MASTestApp11ContentViewVAC7SwiftUI0D0AAWl ...上例中被 diff 出来的符号正是 Swift 编译器的名称改编(mangled)符号,例如$s10MASTestApp11ContentViewV...——它们带有清晰的类型与泛型信息,反改编后可还原出类名、方法名与签名。
方法三:radare2 / rabin2 符号枚举
MASTG-TECH-0113 还给出了 radare2 的用法。用is命令列出所有符号,再配合 grep 过滤即可快速定位感兴趣的目标:
r2 -A MASTestApp [0x100007408]> is~Sec 70 0x00007894 0x100007894 LOCAL FUNC 0 imp.SecKeyCopyExternalRepresentation 71 0x000078a0 0x1000078a0 LOCAL FUNC 0 imp.SecKeyCopyPublicKey 72 0x000078ac 0x100078ac LOCAL FUNC 0 imp.SecKeyCreateRandomKey 73 0x000078b8 0x100078b8 LOCAL FUNC 0 imp.SecKeyCreateSignature 74 0x000078c4 0x100078c4 LOCAL FUNC 0 imp.SecKeyVerifySignature或者使用 rabin2(MASTG-TOOL-0129)直接导出符号表:
rabin2 -s MASTestApp方法四:MobSF 自动化扫描
在发布前的自动化流水线中,可以借助 MobSF(MASTG-TOOL-0040)对 IPA 做静态扫描。MobSF 运行在本地 macOS 主机上(浏览器访问http://127.0.0.1:8000,拖入 IPA 即可),其分析报告中包含:
- 应用及其二进制的基本信息;
- 二进制分析摘要:免费二进制安全特性(PIE、ARC、Canary 等)是否启用、是否使用了被禁止的 API;
- 若应用由 Objective-C 编写,可下载 class-dump(Swift 应用无法生成 class-dump);
- 二进制中包含的字符串列表、App Transport Security(ATS)例外等。
MobSF 的二进制分析可作为调试符号问题的第一道自动防线,但与 Android 场景不同,MobSF 不提供 iOS 应用的动态分析能力,符号确认仍需上述命令行工具。
与相关安全主题的边界与联动
理解调试符号在整个 iOS 安全测试中的位置,有助于避免混淆。仓库中两个相邻知识条目值得联动阅读:
- MASTG-KNOW-0089(iOS 混淆):其中“Symbol Stripping”一节指出,符号剥离是基础混淆形式,但无法移除 Objective-C/Swift 运行时元数据;因此发布构建在剥离调试符号后,仍可能有类名、selector、Swift 类型描述符等元数据残留,需要进一步通过标识符重命名(如 MASTG-TOOL-0068 这类源码级 Swift 名称混淆工具)或 O-MVLL 等 LLVM 混淆器处理。调试符号处理的细节即交叉引用到 MASTG-KNOW-0063。
- MASTG-KNOW-0086 / MASTG-KNOW-0140(源码完整性校验):应用可运行时解析自身 Mach-O 的
__TEXT/__text段并计算 SHA-256 校验,防止被补丁或重签名——这属于运行时自检,与静态的调试符号检查互补。
此外,MASTG-TEST-0087(确保免费安全特性启用)展示了符号表在安全评估中的另一种用途:通过 radare2 的is~release,retain输出中objc_autorelease、objc_retainAutorelease等符号来判断 ARC 是否启用。也就是说,符号不仅是待剥离的泄漏面,也是测试者验证编译器安全特性的依据——剥离调试符号不应破坏这些运行时必需的符号。
发布前检查清单与结论
将 MASTG-KNOW-0063、MASTG-TEST-0219 与 MASTG-TECH-0113 的内容整合为可执行的发布前检查流程:
- 构建配置检查:确认 Release 配置中
Build Settings > Apple Clang - Code Generation > Generate Debug Symbols为No;Build Settings > Build Options > Debug Information Format为DWARF with dSYM File。 - dSYM 保管:构建产物中的 dSYM 文件必须安全归档(用于后续崩溃符号化),绝不随 IPA 分发。
- 静态验证:使用 MASTG-TECH-0058 从应用包中提取所有二进制(主可执行文件、framework、扩展),然后对每个二进制执行:
diff <(nm <bin>) <(nm -a <bin>),若输出为空则无调试符号;- 或
objdump --syms <bin>,确认无d标志的调试符号条目; - 或用 radare2
is命令抽查。
- 评估判定:只要任一二进制中存在标记为调试符号的条目,测试即失败(MASTG-TEST-0219 的 Evaluation 标准)。
- 联动纵深:剥离调试符号后,结合 MASTG-KNOW-0089 评估残留的运行时元数据是否仍需通过标识符重命名等混淆手段处理。
核心结论一句话:调试符号对运行毫无必要,却会显著降低逆向门槛;通过DWARF with dSYM File将调试信息与发布二进制分离,用Generate Debug Symbols = No阻止符号进入二进制,再以 nm/objdump/radare2 静态验证,即可在保护内部实现细节的同时,保留崩溃报告符号化所需的完整调试能力。
- 文档
- 教程
- 网络安全
【免费下载链接】mastg
The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.
相关推荐
OWASP MASTG 系列:Android 原生库调试信息与调试符号(Debug Symbols)检测指南
OWASP MASTG 系列:Android 原生库调试信息与调试符号(Debug Symbols)检测指南 本文对应 OWASP MASTG 知识条目 MAS
文档教程网络安全ALMA-13B-Pretrain论文精读:对比偏好优化如何将翻译性能推向新高度
ALMA 13B Pretrain论文精读:对比偏好优化如何将翻译性能推向新高度 在机器翻译领域,ALMA 13B Pretrain模型以其创新的 对比偏好优化
如何快速上手LevelUI:10分钟掌握LevelDB可视化管理的5个核心技巧
如何快速上手LevelUI:10分钟掌握LevelDB可视化管理的5个核心技巧 LevelUI是一款基于electron构建的LevelDB可视化管理工具,它提
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考