我们说iOS系统是由OSX系统演化,而OSX基于UNIX操作系统。Filesystem Hierachy Standard
为类UNIX操作系统的文件目录结构制定了一套标准,FHS的初衷是为了让用户知道文件或者是目录的存放位置,OSX在此基础上形成了自己的hier(7)框架。类UNIX操作系统常见的目录结构:
上面的目录多用于系统底层。
我们的iOS操作系统独有的目录:
iOS是一个多用户操作系统,用户
是一个抽象概念,代表它能对操作系统的所有权和使用权。例如一个mobile用户无法调用reboot命令重启iOS,而root用户却可以。“组”是用户的一种组织方式,一个组可以包含多个用户,一个用户可以属于多个组。
iOS中使用3位(bit)来表示文件的权限,从高到低分别是r(read),w(write),x(execute)权限。文件与用户的关系存在三种可能:1.用户属于主用户;2.用户不是属于主用户,但是属于主组;3.用户既不是主用户也不属于主组。
所以我们需要3*3位来表示一个文件的权限,如果这一位代表为1则代表权限有效,否则无效。例如:111101101代表rwxr-xr-x,表示该文件主用户拥有rwx权限,而属于主组而不是主用户只有rx权限,不属于主组也不是主用户的只有rx权限。转换为八进制755也是一种常见的权限表示方式。
在iOS逆向工程中,我们的目标主要是Application
、Dunamic Library(dylib)
和Daemon
这三类二进制文件。
Application就是我们最熟悉的App了。现在来熟悉几个常见的目录
bundle的概念来源于NeXTSTEP,它不是一个文件,而是一个按某种标准结构来组织的目录,其中包含了二进制文件及运行所需的资源。正像开发中常见的App和framework都是以bundle的形式存在的;在越狱iOS中常见的PreferenctBundle可以看成是一种依附在Setting的App,结构与App相似,本质是bundle。
Framework也是bundle,但framework的bundle中存放的是一个dylib,而不是一个可执行文件。相对来说frmakework的地位比App还高,因为一个App的大多数功能都是通过调用framework提供的接口来实现的。将某个bundle确立为逆向目标之后,绝大多数逆向线索都可以在bundle内找到,这大大降低了逆向工程的复杂度。
在iOS逆向工程中,对App目录结构的熟悉程度决定工作效率的重要因素,App目录的以下三个部分比较重要
1.Info.plist
Info.plist记录了App得基本信息,如bundle identifier、可执行文件名、图标文件名等。我们也可以通过XCode自带的命令行工具plutil查看他的值。
2.可执行文件
可执行文件的重要性不言而喻,它是App目录下最核心的部分,也是逆向工程的主要目标。同样可以通过XCode和plutil两种方式来查看Info.plist,定位可执行文件。
3.lproj目录
lproj目录下存放的是各种本地化的字符串(.strings),他是逆向工程的重要线索,也可以通过plutil查看。
/Application/目录下存放系统App和从Cydia下载的App(我们把来自Cydia的App视为系统App),而/var/mobile/Containers/目录下存放的则是StoreApp。虽然两者都为App,但是他们在如下方面存在差异。
1.目录结构
两种App的bundle内部目录结构区别不大,都含有Info.plist、可执行文件、lproj目录等,但是数据目录的位置不同;StoreApp的数据目录在/var/mobile/Containers/Data/下,以,mobile权限运行的系统App的数据目录在/var/mobile/下,而以root权限下运行的数据目录在/var/root/下。
2.安装包的格式和权限
Cydia App的安装包格式一般为deb,StoreApp的安装包格式一般为ipa。其中deb是来自Debian得安装包格式,由Cydia得作者saurik移植到iOS中,他得属主用户和属主组一般是root和admin,能够以root权限运行;而ipa则是苹果为iOS推出的专属App安装包格式,属主用户和属主组都是mobile,只能以mobile权限运行。
3.沙盒
通俗的说,iOS的沙盒就是一种访问限制机制,我们可以把它看做是权限的一种表现形式,授权文件(entitlements)也是沙盒的一部分。它是iOS最核心的安全组件之一,其实很复杂,在这里不讨论细节。总的来说,沙盒会将App的文件访问方位限制在这个App内部,一个App一般不知道其他App的存在,更别说访问他们了;沙盒还会限制App的功能,例如对iCloud接口的调用必须经过沙盒的允许。
dylib在iOS开发中的实例:在我们XCode工程里导入的各种framework,链接的各种lib,其实本质都是dylib。我们可以用命令“file”验证。
如果把焦点放到越狱iOS中,Cydia里面各种无一不是以dylib形式工作的,正是这些tweak的存在让我们能够随便定义我们的iOS。在逆向工程中,我们会频繁接触各种dylib,因此我们需要了解一些相关知识。
在iOS中,lib分为static
和dynamic
两种,其中static lib
在编译阶段成为App可执行文件的一部分,会增加可执行文件的大小。因为App尺寸变大,启动时需要加载的内容变多,所以可能会导致App启动变慢。dylib
则相对智能一些,它不会改变可执行文件的大小,只有当App需要用到这个dylib的时候,iOS才把它加载进内存,成为App进程的一部分。
Daemon
即守护进程,为后台而生,给用户提供了各种守护
,如imagent保障了iMessage得正确收放,mediaserverd处理了几乎所有的音频、视频,syslogd则用于记录系统日志等。iOS中daemon主要由一个可执行文件和一个plist文件构成。iOS的根进程是launchd,他会在开机时检查/Ststem/Library/LaunchDaemons和/Library/LaunchDaemons下所有格式符合规定的plist文件,然后启动对应的daemon。
daemon提供的功能相对底层,随意改动会造成严重后果,例如白苹果。