推荐序
本文介绍了恢复符号表的技巧,并且利用该技巧实现了在 Xcode 中对目标程序下符号断点调试,该技巧可以显著地减少逆向分析时间。在文章的***,作者以支付宝为例,展示出通过在 UIAlertView 的 show 方法处下断点,从而获得支付宝的调用栈的过程。
本文涉及的代码也开源在:https://github.com/tobefuturer/restore-symbol,欢迎 Star 和提 Issue。感谢作者授权发表。
作者介绍:杨君,中山大学计算机系研究生,iOS 开发者,擅长领域 iOS 安全和逆向工程,个人博客:http://blog.imjun.net 。
前言
符号表历来是逆向工程中的 “必争之地”,而 iOS 应用在上线前都会裁去符号表,以避免被逆向分析。
本文会介绍一个自己写的工具,用于恢复 iOS 应用的符号表。
直接看效果 , 支付宝恢复符号表后的样子:
文章有点长,请耐心看到***,亮点在***。
为什么要恢复符号表
逆向工程中,调试器的动态分析是必不可少的,而 Xcode + lldb 确实是非常好的调试利器 , 比如我们在 Xcode 里可以很方便的查看调用堆栈,如上面那张图可以很清晰的看到支付宝登录的 RPC 调用过程。
实际上,如果我们不恢复符号表的话,你看到的调试页面应该是下面这个样子:
同一个函数调用过程,Xcode 的显示简直天差地别。
原因是,Xcode 显示调用堆栈中符号时,只会显示符号表中有的符号。为了我们调试过程的顺利,我们有必要把可执行文件中的符号表恢复回来。
符号表是什么
我们要恢复符号表,首先要知道符号表是什么,他是怎么存在于 Mach-O 文件中的。
符号表储存在 Mach-O 文件的 __LINKEDIT 段中,涉及其中的符号表(Symbol Table)和字符串表(String Table)。
这里我们用 MachOView 打开支付宝的可执行文件,找到其中的 Symbol Table 项。
符号表的结构是一个连续的列表,其中的每一项都是一个 struct nlist。
// 位于系统库 头文件中
struct nlist {
union{
// 符号名在字符串表中的偏移量
uint32_t n_strx;
} n_un;
uint8_t n_type;
uint8_t n_sect;
int16_t n_desc;
// 符号在内存中