AppStore 审核最大痛点可以归纳为三个:“误报率高” 、“描述模糊”和 “申诉慢”。
我们深知,苹果的上架审核非常严格,对私有 API 的调用是绝对不能容忍的,很多开发者都对提审诚惶诚恐,明明我没用到这个方法,为什么又被拒了?代码里翻了几遍都没找到相关的字符,怎么办啊…orz
知己知彼,百战百胜。想要跨越审核这座大山,得知道苹果审核究竟是怎样的。那我们就来研究下苹果是怎么对付我们的。首先,我们提交给苹果的,是一个 ipa 文件,里面的 bin 文件,都是编译好的二进制可执行文件,苹果生态中叫做 machO 格式,machO 格式定义了各种分段,比如引用的库列表,定义的类列表,方法列表,协议列表,字符串列表,然后又在一个地址映射表中记载着这些类,方法的对应关系,和实际的机器码机址。苹果只要对这些特定的段进行扫描,就能扫出来有没有引用一些非公开的 API,类,系统库。 根据 UC 多年的经验积累,苹果会特别关注以下几点
为了解决 iOS 开发者的这个困扰,岩鼠深入研究了如何去发现及应对以上问题,毕竟,提审流程太长了,被拒的滋味真的不好受。
我们知道,iOS 都是自成体系的,很多东西脱离不了 macOS 系统,我们需要平台化,通用化,首先需要解决 macOS 系统的依赖。所以要把 machO 格式的解析啃下来,我们要把所加载的动态库,所有方法名,类名,有实现的方法名,所有 ascii 字符串都加载出来。这些都在 ipa 的 bin 文件里面,我们按照 machO 格式去读取出来即可。怎么做呢?
首先我们把 ipa 里的 bin 文件解压出来,然后依次读取主模块,各种插件的 bin,关于 machO 格式,这里简单说明一下,machO 文件会分成多个段,一个段又分成多个块,如下图:
然后找出我们需要的段在哪里,然后再把里面的内容读出来,如__objc_methname 块,__objc_classname 块,就是我们要找的 oc 的方法名和类名,当然,如果你在 xcode 中修改过默认的编译链接参数,生成的段名可能会有差异,需要在 Load commands 块读出来。这些信息读取出来后再做一个简单的加工,就可以跟我们的数据库做对比了。
上面解决了静态扫描的问题,那么,运行时的扫描怎么办?这里我们可以期待一下私有 api 扫描加强版,我们计划在岩鼠上面运行被扫描的 app,在执行深度智能遍历的时候,通过注入等手段,执行运行时扫描,然后再跟数据库的私有 api 做对比。
利用 RuntimeBrowser,在当前主流固件的真机运行,并导出的所有 Frameworks 和私有的 PrivateFrameworks 库,取出后进行对比,最终把私有 API 按固件版本入库。
完成初始化私有 API 库的工作后,是不是就一劳永逸了呢?其实不是的,一方面是私有 API 库的准确性需要持续提升,另一方面是新的一些私有 API 也要持续加入,这样才能保证 iOS 预审的有效性和准确率。
岩鼠的私有 API 库建立了智能学习机制,会收集阿里内部应用审核被拒的记录,分析其中私有 API 被拒的情况,主动添加新的私有 API,不断完善私有 API 库。与此同时也会建立白名单,提升准确率。
在岩鼠上进行 iOS 预审十分简单,只需要上传待提审的 ipa 包,稍等几分钟,即可查看扫描的结果。
当前岩鼠 iOS 预审可以免费试用,欢迎大家来体验:
https://yanshu.effirst.com/product/pretrial/overview