苹果如何知道你在使用私有API?
我提交了一个二进制文件给苹果没有任何源代码。
除了手动检查源代码之外,Apple如何知道所使用的以及所调用的API?
我知道有三种方法。 这些只是一些猜测,因为我不在苹果审查小组工作。
1. otool -L
这将列出应用程序链接到的所有库。 显然你不应该使用的东西,比如IOKit和WebKit可以被这个检测到。
2. nm -u
这将列出所有链接的符号。 这可以检测到
- 未logging的C函数,如_UIImageWithName;
- Objective-C类,如UIProgressHUD
- 像
UITouch._phase
(这可能是过去几个月内拒绝基于Three20的应用程序的原因)。
列出Objective-Cselect器或strings
Objective-Cselect器存储在二进制文件的特殊区域,因此Apple可以从那里提取内容,并检查是否使用了一些未logging的Objective-C方法,例如-[UIDevice setOrientation:]
。
由于select器独立于您正在传递的类, 即使您的自定义类定义了-setOrientation:
与UIDevice无关,也可能会被拒绝。
您可以使用Erica Sadun的APIKit来检测由于私有API(错误警报)而导致的潜在拒绝。
(如果你真的真的真的想要解决这些检查,你可以使用运行时function,如
- dlopen,dlsym
- objc_getClass,sel_registerName,objc_msgSend
-
-valueForKey:
object_getInstanceVariable,object_getIvar等
得到那些私人图书馆,类,方法和ivars。 )
您可以在Terminal中使用以下一行命令在Mach-O程序中列出select器:
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/,$_))))))'
假设你想使用一些私人API; 目标C允许你从一个string构造任何SEL:
SEL my_sel = NSSelectorFromString([NSString stringWithFormat:\ @"%@%@%@", "se","tOr","ientation:"]); [UIDevice performSelector:my_sel ...];
机器人或图书馆扫描怎么能抓住这个? 他们将不得不使用一些工具来监视运行时的私人访问。 即使他们构build了这样一个运行时工具,也很难捕捉到,因为这个调用可能隐藏在一些很less被执行的path中。
我想他们会看到你的二进制文件试图导入的所有符号(这些符号在其符号表中很容易find),如果在它们的“私有API列表”中find这些符号的话,那么你就会知道这些符号。 事实上,很容易实现自动化。
可执行文件不完全是黑盒子。 如果你打电话给图书馆,这是一件容易的事情。 这就是为什么我感叹现代CS教育中汇编语言的stream失。 =]像ldd这样的工具会告诉你你链接了什么,虽然我不记得ldd是什么化身的mac的iPhone开发工具包。
即使你是静态链接,最糟糕的情况是,他们可以从列表中的私有API获取代码样本,并search你的二进制文件(也相对容易自动化)。
了解苹果,我敢打赌他们有一个全面的自动化系统,任何不确定性可能被拒绝或手动审查。
一天的结束,我认为这可能是不值得尝试和愚弄苹果的努力。
otool -L somebinary
这个桌面应用程序, 应用程序扫描仪 ,可以通过拉开Mach-O二进制文件来扫描.app文件,以便私人使用api。 如果可以的话,苹果也可以!
除了符号调查…
苹果可以非常容易地拥有一个版本的sdk,它在调用时检查每个私有方法堆栈,以确保它是从指定方法之一input的。