最近发现部分 App 以字符串拼接的方法调用私有 API,在提交 AppStore 审核后被发现打回修改的案例。
对于开发者提交的二进制文件,Apple 是如何检查出私有 API 的调用 ?本文尝试探讨可能的检测机制,以及每种机制的漏洞。
私有 API 调用方法1:直接调用法
1 | [self _privateMethod]; |
私有 API 调用方法2:字符串拼接法
借助 Objective-C 语言的动态特性,在运行时用 performSelector
执行拼接的 selector 方法:
1 | NSArray *parts = @[@"_priva", @"teMethod"]; |
私有 API 检测方法1:符号表检查
用 nm
、otool
等工具导出二进制包的函数符号表,以检查私有 API 的调用。
开源项目 iOS-private-api-checker 以这种方式实现了对私有 API 调用的检查。
然而这种方法的缺点是,无法检测字符串拼接方法的私有 API 调用。
私有 API 检测方法2:运行时分析
在审核人员运行 App 的同时,用 runtime 工具检测是否调用了私有 API。具体原理待补充。
这种方法的漏洞,当审核人员无法进入调用了私有 API 的功能时(通过后台下发配置文件控制功能入口),会有漏测的情况。
私有 API 检测方法3:静态代码分析
为检测字符串拼接法调用私有 API,受论文 [1] 启发,可以在对二进制文件反汇编结果的基础上,进行静态分析:
- 找出动态调用 API 方法如
performSelector:
,以及调用对象的类 - 检查参数,如果参数是拼接方法生成,推导求得拼接的结果
- 根据 1 2 判断是否调用了私有 API
以私有 API 调用方法2 的代码为例,用 Hopper 对其反汇编,得到伪代码:
1 | void -[ViewController viewDidLoad](void * self, void * _cmd) { |
可以看出,伪代码有着充分的信息,可以进行静态分析推导,判断代码片段是否调用了私有 API。
然而这种方法也有漏洞,拼接的字符串由服务器下发,可以避开检查。
更多
欢迎大家补充,可以留言在 https://github.com/liuslevis/hexo/blob/master/source/_posts/ios-private-api-detection.md
引用
[1] Bergeron, Jean, et al. “Static analysis of binary code to isolate malicious behaviors.” Enabling Technologies: Infrastructure for Collaborative Enterprises, 1999.(WET ICE’99) Proceedings. IEEE 8th International Workshops on. IEEE, 1999. PDF
[2] 反汇编的利器 IDA 和 Hopper 的基本使用 Niyao https://niyaoyao.github.io/2017/01/18/Learning-Reverse-From-Today-D3/