2.2 iOS二进制文件类型
在iOS逆向工程初学阶段,我们的目标主要是Application、Dynamic Library(以下简称dylib)和Daemon这三类二进制文件,对它们的了解越深入,逆向工程就会越顺利。这三类文件分工不同,其目录结构和文件权限也有一些区别。
2.2.1 Application
Application就是我们最熟悉的App了。虽然对于大多数iOS开发者来说,工作都是在跟App打交道,但在iOS逆向工程中,关注App的侧重点与正向开发还是不尽相同的。了解下面的几个App相关概念,是开始逆向工程前的必备工作。
1. bundle
bundle的概念来源于NeXTSTEP,它不是一个文件,而是一个按某种标准结构来组织的目录,其中包含了二进制文件及运行所需的资源。正向开发中常见的App和framework都是以bundle的形式存在的;在越狱iOS中常见的PreferenceBundle(如图2-10所示),可以看成是一种依附于Settings的App,结构与App类似,本质也是bundle。
Framework也是bundle,但framework的bundle中存放的是一个dylib,而不是可执行文件。相对来说,framework的地位比App更高,因为一个App的绝大多数功能都是通过调用framework提供的接口来实现的。将某个bundle确立为逆向目标后,绝大多数逆向线索都可以在bundle内找到,这大大降低了逆向工程的复杂度。
2. App目录结构
在iOS逆向工程中,对App目录结构的熟悉程度是决定工作效率的重要因素。App目录的以下三个部分比较重要。
Info.plist
Info.plist记录了App的基本信息,如bundle identifier、可执行文件名、图标文件名等。其中bundle identifier会在后续章节的CydiaSubstrate中成为tweak的重要配置信息。可以通过Xcode查看它的值,如图2-11所示。
也可以通过Xcode自带的命令行工具plutil查看它的值,如下:
snakeninnysiMac:~ snakeninny$ plutil -p /Users/snakeninny/Code/iOSSystemBinaries/8.1_iPhone5/SiriViewService.app/Info.plist | grep CFBundleIdentifier
"CFBundleIdentifier" => "com.apple.SiriViewService"
本书主要采用plutil的方式来查看plist文件。
可执行文件
可执行文件的重要性不言而喻,它是App目录下最核心的部分,也是逆向工程最主要的目标。同样可以通过Xcode和plutil两种方式来查看Info.plist,定位可执行文件。用Xcode查看Info.plist的界面如图2-12所示。
也可以通过Xcode自带的命令行工具plutil查看它的值,如下:
snakeninnysiMac:~ snakeninny$ plutil -p /Users/snakeninny/Code/iOSSystemBinaries/8.1_iPhone5/SiriViewService.app/Info.plist | grep CFBundleExecutable
"CFBundleExecutable" => "SiriViewService"
lproj目录
lproj目录下存放的是各种本地化的字符串(.strings),是iOS逆向工程的重要线索,也可以用plutil查看,如下:
snakeninnysiMac:~ snakeninny$ plutil -p /Users/snakeninny/Code/iOSSystemBinaries/8.1_iPhone5/SiriViewService.app/en.lproj/Localizable.strings
{
"ASSISTANT_INITIAL_QUERY_IPAD" => "What can I help you with?"
"ASSISTANT_BOREALIS_EDUCATION_SUBHEADER_IPAD" => "Just say "Hey Siri" to learn more."
"ASSISTANT_FIRST_UNLOCK_SUBTITLE_FORMAT" => "Your passcode is required when %@ restarts"
……
这部分内容的应用场景会在第5章出现。
3. 系统App VS. StoreApp
/Applications/目录存放系统App和从Cydia下载的App(我们把来自Cydia的App视为系统App),而/var/mobile/Containers/目录存放的则是StoreApp。虽然两者都是App,但它们在如下方面存在着一些差别。
目录结构
两种App的bundle内部目录结构区别不大,都含有Info.plist、可执行文件、lproj目录等,但是数据目录的位置不同:StoreApp的数据目录在/var/mobile/Containers/Data/下,以mobile权限运行的系统App的数据目录在/var/mobile/下,而以root权限运行的系统App的数据目录在/var/root/下。
安装包格式与权限
Cydia App的安装包格式一般是deb,StoreApp的安装包格式一般是ipa。其中deb是来自Debian的安装包格式,由Cydia作者saurik移植到iOS中,它的属主用户和属主组一般是root和admin,能够以root权限运行;而ipa是苹果为iOS推出的专属App安装包格式,属主用户和属主组都是mobile,只能以mobile权限运行。
沙盒(sandbox)
通俗地说,iOS中的沙盒就是一种访问限制机制,我们可以把它看作是权限的一种表现形式,授权文件(entitlements)也是沙盒的一部分。它是iOS最核心的安全组件之一,其实现很复杂,这里不过多讨论其细节。总的来说,沙盒会将App的文件访问范围限制在这个App内部,一个App一般不知道其他App的存在,更别说访问它们了;沙盒还会限制App的功能,例如对iCloud接口的调用就必须经过沙盒的允许。
在初学阶段,我们的目标不是沙盒,知道有这样一个东西存在就够了。在iOS逆向工程中,越狱本身已经破除了iOS的绝大多数安全限制,并对沙盒进行了一定程度的扩充,因此我们往往很容易忽略sandbox的存在,从而碰到一些看似很奇怪的问题。比如某个tweak不能写文件,调用了某个函数却没有出现应有的效果,在确保自己的代码没有问题的前提下,就要回过头来检查这些问题是不是因为权限不够,或者沙盒限制造成的。App相关的概念不是用三言两语可以描述完的,如果有什么疑问,可以直接来http://bbs.iosre.com交流讨论。