Apple 怎么知道你在使用私有 API?

Posted

技术标签:

【中文标题】Apple 怎么知道你在使用私有 API?【英文标题】:How does Apple know you are using private API? 【发布时间】:2011-02-20 00:07:09 【问题描述】:

我向 Apple 提交了一个没有任何源代码的二进制文件。

除了手动检查源代码之外,Apple 如何知道您使用了什么以及调用了哪些 API?

【问题讨论】:

更改了标题 - 我想您的意思是“Apple 怎么知道..” 【参考方案1】:

我知道有 3 种方法。这些只是一些猜测,因为我不在 Apple 审核团队工作。

1。 otool -L

这将列出该应用已链接到的所有库。显然你不应该使用的东西,比如 IOKit 和 WebKit 可以被它检测到。

2。 nm -u

这将列出所有链接的符号。这可以检测到

未记录的 C 函数,例如 _UIImageWithName; Objective-C 类,例如 UIProgressHUD 诸如 UITouch._phase 之类的 Ivar(这可能是最近几个月出现 rejection of Three20-based apps 的原因。)

3。列出 Objective-C 选择器,或 strings

Objective-C 选择器存储在二进制文件的一个特殊区域中,因此 Apple 可以从那里提取内容,并检查您是否使用了一些未记录的 Objective-C 方法,例如 -[UIDevice setOrientation:]

由于选择器独立于您发送消息的类,即使您的自定义类定义了与 UIDevice 无关的 -setOrientation:,也有可能被拒绝。


您可以使用 Erica Sadun's APIKit 检测由于私有 API(错误警报)而导致的潜在拒绝。


(如果您真的真的很想解决这些检查,您可以使用运行时功能,例如

dlopen,dlsym objc_getClass、sel_registerName、objc_msgSend -valueForKey:; object_getInstanceVariable、object_getIvar 等

获取那些私有库、类、方法和 ivars。 )

【讨论】:

很好的答案。我只想补充一点,如果您的应用程序正在做一些不使用私有 API 就很难做到的事情,我相信您的应用程序会受到额外的审查。 我很好奇调用私有方法的解决方法。我认为编译器会为 [foo privateMethod] 生成对 objc_msgSend(foo, @selector(privateMethod)) 的调用,因此如果 Apple 可以检测到 privateMethod 的直接调用,他们也可以通过 objc_msgSend(或 performSelector:) 检测到间接调用。 我想知道为什么你说你不应该链接到 IOKit 和 WebKit? 你在什么上执行 otool? .app 文件? @Eric,他们可以,尽管这样的检测版本可能会影响性能。无论如何,看到私有 API 反复进入 App Store,很明显它们不会这样做,或者至少不会一直这样做。【参考方案2】:

您可以在终端中使用以下单行列出 Mach-O 程序中的选择器:

otool -s __TEXT __objc_methname "$1" |expand -8 | cut -c17- | sed -n '3,$p' | perl -n -e 'print join("\n",split(/\x00/,scalar reverse (reverse unpack("(a4)*",pack("(H8)*",split(/\s/,$_))))))'

【讨论】:

+1,@Robert Diamond,你能不能再描述一下。我需要检查 Google 分析是否使用 UDID 调用。谢谢【参考方案3】:

假设您想使用一些私有 API; Objective C 允许你从一个字符串构造任何 SEL:

   SEL my_sel = NSSelectorFromString([NSString stringWithFormat:\
@"%@%@%@", "se","tOr","ientation:"]);
    [UIDevice performSelector:my_sel ...];

机器人或图书馆扫描如何捕捉到这一点?他们将不得不使用一些在运行时监控私有访问的工具来捕捉这一点。即使他们构建了这样一个运行时工具,也很难捕捉到,因为这个调用可能隐藏在一些很少使用的路径中。

【讨论】:

user1203764 comments 这种调用实际上可以被检测到 @Rup 想在这里就我关于使用 valueForKey 的问题发表意见,好吗? ***.com/questions/11923597/… @Yar 有趣的问题!但我还不够专家评论抱歉。 Farcaller 所说的对我来说似乎很合理 感谢@Rup,显然没有人能胜任这一领域的专家:) 我认识的一个人说他刚刚在 App Store 接到了这样一个电话。【参考方案4】:

我想他们会查看您的二进制文件尝试导入的所有符号(信息无疑很容易在其符号表中提供给他们),如果在他们的“私有 API 列表”中找到任何这些符号,他们就会告诉您。事实上,很容易实现自动化。

【讨论】:

实际上,根据我知道的私有 API 使用情况,我可以肯定地说,情况并非如此(至少不是他们所做的全部)。如果这就是所需要的,私有 API 的使用就不会溜走了。我的经验表明,KennyTM 的答案几乎肯定是正确的。这是 Objective-C 与其他语言(如 C)根本不同的领域。【参考方案5】:

可执行文件并不完全是一个黑匣子。如果你打电话给图书馆,很容易找到。这就是为什么我哀叹现代计算机科学教育中失去汇编语言的原因。 =] ldd 之类的工具会告诉您链接的内容,尽管我不记得 ldd 的什么化身使它进入了 mac iPhone 开发工具包。

【讨论】:

我经常想知道:如果您要编写二进制文件进行自我修改,只有在满足某些条件后(例如,在您的发布日期之后)才生成导入私有 API 的代码。应用程序)苹果是否会抓住它。他们肯定会向我们报告一些有趣的统计数据,例如在越狱手机上运行的游戏数量。 @user30997, 特权代码可能只能通过系统调用访问;执行线程切换到更高的权限并检查先前的权限是否具有执行代码的权限。这只是一个例子,还有其他方法可以做到,但我高度怀疑开发人员是否天真地忽略了这样的基本运行时权限检查机制,它肯定会被现在。【参考方案6】:
otool -L somebinary

【讨论】:

【参考方案7】:

除了符号调查...

apple 可以很容易地拥有一个 sdk 版本,该版本在调用时检查每个私有方法堆栈,以确保它是从指定方法之一输入的。

【讨论】:

这还不够,因为程序只能在未来的任意时间调用这个私人调用,这取决于其他逻辑。为此,Apple 必须实际完全阻止私有 API,或者让框架自动向 Apple 报告私有 API 调用——这会严重损害性能。【参考方案8】:

即使您是静态链接,在最坏的情况下,他们也可以从其列表中的私有 API 中提取代码样本,并针对它们搜索您的二进制文件(也相对容易自动化)。

了解 Apple,我敢打赌他们有一个全面的自动化系统,任何不确定性都可能被拒绝或手动审查。

归根结底,我认为尝试愚弄 Apple 可能不值得。

【讨论】:

了解 Apple 在遇到任何不确定性时的审核流程包括掷出一组骰子,以获得最大的奇思妙想。【参考方案9】:

此桌面应用程序App Scanner 可以通过拆分 Mach-O 二进制文件来扫描 .app 文件以供私有 api 使用。如果可以,那么 Apple 也可以!

【讨论】:

【参考方案10】:

有很多逆向工程工具可以检查代码

nm - 列出目标文件中的符号 objdump - 显示来自目标文件的信息。 otool - 查看 Mach-O[About] 可执行文件的内容 strings - 这将为您提供所有字符串。

您可以在 Objective-C 和 Swift 的要点中找到使用这些命令的示例/表示

【讨论】:

以上是关于Apple 怎么知道你在使用私有 API?的主要内容,如果未能解决你的问题,请参考以下文章

IOS6.1 上的 Apple 802.11 API - 有人有正确的捆绑包吗?

私有 API 到底是啥,如果使用了一个 iOS 应用程序,为啥 Apple 会拒绝它?

如何使用私有系统 API?

使用私有 api 检测 iOS 中启用的热点

在没有私有 API 的情况下以纵向 MPMoviePlayerController 播放视频 - 我会被 Apple 拒绝吗?

iOS - APP审核Guideline 2.5.1被拒,使用了私有API