iOS逆向之文件系统

时间:2022-07-24
本文章向大家介绍iOS逆向之文件系统,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前言

作为一名iOS开发者,长期以来和MacOS、iOS系统打交道,对iOS和MacOS系统并不陌生。在开发中,我们也经常访问甚至修改MacOS的某些目录,每个系统目录都有其特殊的功能定位。而iOS系统源自MacOS,在很多方面iOS都和MacOS很相似,笔者借助最近逆向的机会,系统的学习&梳理了下iOS的系统目录及其结构,顺便总结了常见的文件目录的特殊定位。希望本篇文章能够让读者有所收获。

iOS系统目录

iOS源自macOS,而macOS又基于Unix系统内核,因此其目录结构与UNIX系统相同。
iOS系统包含两类目录,一类是保留的UNIX传统目录,另一类是iOS/macOS特有的目录。

iOS设备越狱后可以用工具对iOS文件系统目录一探究竟。下图是笔者使用iFunbox查看的越狱后iPhone设备的目录结构。

iOS文件系统目录

UNIX传统目录

  • /bin:“binary” 的简称。存放提供用户级基础功能的二进制文件。如 cat、chomod、chown等。
  • /sbin:“system binaries” 的简称。提供系统级基础功能的二进制文件,如mount、reboot等。
  • /dev:“device” 的简称。存放BSD设备文件。
  • /etc:“EtCetera” 的简称。存放系统脚本及配置文件。如passwd、hosts等。iOS中此目录是一个符号链接,实际指向/private/etc。
  • /boot:存放能使系统成功启动的所有文件,iOS中此目录为空。
  • /lib:存放系统文件、内核模块及设备驱动等。iOS中此目录为空。
  • /mnt:“mount” 的简称。存放临时的文件系统挂载点。iOS中此目录为空。
  • /tmp:临时文件存放目录。在iOS中,此目录是一个符号链接,实际指向/private/var/tmp。
  • /usr:存放大量的工具和第三方程序。
    • 其中,/usr/lib 目录存放了各种dylib(动态链接库)。
    • /usr/include 目录存放了所有的标准C头文件。
    • /usr/bin目录存放着一些后期安装的用户命令,如zip、unzip等。iOS逆向动态调试用到的debugserver也将是放到此目录。
  • /var:“variable” 的简称。存放经常变化的文件,如日志文件。其中,/var/mobile和/var/root分别存放了mobile用户和root用户的文件,是非常重要的目录。在iOS中,此目录是一个符号链接,实际指向/private/var/tmp。

iOS特有目录

  • /Applications:存放所有系统应用以及从Cydia安装的应用,但不包括从App Store下载安装的应用。
  • /Developer:当设备连接到Xcode时,此目录下会存放一些开发调试相关的文件和工具,如debugserver。
  • /Library:存放一些提供系统支持的数据,其中的/Library/MobileSubstrate/DynamicLibraries 是越狱开发者最感兴趣的目录,里面存放了所有基于CydiaSubstrate的插件。
  • /System:仅包含一个Library子目录,是iOS文件系统中最重要的目录之一,存放着大量的系统组件。其中,/System/Library/CoreServices 里面的SpringBoard.app 是iOS桌面管理器,是用户与系统交互的重要媒介;/System/Library/Frameworks 和 /System/Library/PrivateFrameworks 目录存放iOS系统中的公开及私有框架。总之,/System是系统中最重要的目录,一般情况下轻易不要修改他。
  • /User:用户目录,实际指向/var/mobile。这个目录下存放着大量的用户数据,比如用户照片、录音、短信数据及语音等。
  • /cores:内核转储文件存放目录,当一个进程崩溃时,如果系统允许则会产生转储文件。
  • /private:存放/etc、/var两个链接目录的目标目录,分别是/private/etc和/private/var。

部分系统目录

  • /var/root/Library/Lockdown:设备激活证书存放目录。
  • /Library/Keychains:设备系统级密码等存放目录。
  • /Library/Logs:系统日志存放目录,./var/logs也指向此目录。
  • /Library/Logs/CrashReporter:系统进程崩溃日志目录。
  • /System/Library/LaunchDaemon:系统启动进程plist文件存放目录,若想不启动某进程,删除该目录下对应的plist的文件(操作需慎重,删除之前先备份)。
  • /System/Library/Frameworks:公有框架(开发者可使用)存放目录。
  • /System/Library/PrivateFrameworks:私有框架(开发者不可使用)存放目录。
  • /System/Library/CoreServices/SpringBoard.app:桌面管理器应用,用户与系统交互的中介。
  • /var/mobile/Containers:存放App Store应用相关文件,其中,子目录/Bundle存放应用可执行文件(App Store下载的App就存放在这个目录),子目录/Data存放应用数据。

部分系统应用资料存放目录

  • /var/wireless/Library/CallHistory:存放通话记录,网络流量,使用时间等记录。
  • /var/mobile/Library/AddressBook:存放联系人数据。
  • /var/mobile/Library/Calendar:存放日历及提醒事项记录文件。
  • /var/mobile/Library/Maps:存放地图搜索书签记录。
  • /var/mobile/Library/SMS:存放短信。
  • /var/mobile/Library/Notes:存放备忘录。
  • /var/mobile/Library/Safari:存放Safari保存的书签等。
  • /var/mobile/Library/Mail:存放电子邮件数据。
  • /var/mobile/Library/Preferences/com.apple.accountsettings.plist:存放邮箱设置。
  • /var/mobile/Library/Preferences/com.apple.mobilephone.speeddial.plist :存放个人收藏(快速拨号)。
  • /var/mobile/Media/Recordings:存放语音备忘录。
  • /var/mobile/Media/iTunes_Control:存放iTunes 同步的电影,歌曲等媒体文件。
  • /var/mobile/Media/DCIM:存放照片里面的胶卷。
  • /var/mobile/Media/PhotoData:存放照片里面的图片(含相机胶卷的识别库缩略图等)。
  • /var/mobile/Media/Books:存放iBooks同步的书籍。
  • /var/mobile/Media/PhotoStreamsData:存放照片流。

iOS App沙盒目录结构

出于安全考虑,iOS系统把每个应用以及数据都放到一个沙盒(sandbox)里面,应用只能访问自己沙盒目录里面的文件、网络资源等(也有例外,比如系统通讯录、照相机、照片等能在用户授权的情况下被第三方应用访问)[1]

请注意,使用沙盒的目的是为了防止被攻击的应用危害到系统或者其他应用,它并不能阻止应用本身被攻击,因此,开发者需要防御式的编程来避免应用被攻击。苹果官方是这样说的:

Important: The purpose of a sandbox is to limit the damage that a compromised app can cause to the system. Sandboxes do not prevent attacks from happening to a particular app and it is still your responsibility to code defensively to prevent attacks. For example, if your app does not validate user input and there is an exploitable buffer overflow in your input-handling code, an attacker could still hijack your app or cause it to crash. The sandbox only prevents the hijacked app from affecting other apps and other parts of the system.

为了便于应用组织数据,每个沙盒内都有几个名字固定的子目录用来保存文件,下图是沙盒的目录结构:

iOS沙河目录结构

主要有4个目录官方文档

  • MyApp.app 该目录包含了应用程序本身的数据,程序打包的时候的资源文件和一些本地文件就是存放在这个目录下的。程序的可执行程序、plist文件也在这个目录下。

这个目录不会被iTunes同步

  • Documents使用这个目录来保存关键数据。关键数据指那些应用不可再生的数据。

这个目录会被iTunes同步

  • Library用来保存一些配置文件和其他一些文件。其中使用NSUserDefaults写的设置数据都会保存到Library/Preferences目录下的一个plist文件中。Library/Caches可以用来保存可再生的数据,比如网络请求,用户需要负责删除对应文件。

这个目录(除了Library/Caches外)会被iTunes同步

  • tmp

使用这个目录来保存各种应用下次启动不再需要的临时文件。当应用不再需要这些文件的时候,需要主动将其删除。(当应用不再运行的时候,系统可能会将此目录清空。) 这个目录不会被iTunes同步

获取主要目录路径的方式

沙盒目录

NSLog(@"%@",NSHomeDirectory());

MyApp.app

NSLog(@"%@",[[NSBundle mainBundle] bundlePath]);

tmp

NSLog(@"%@",NSTemporaryDirectory());

Documents

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [paths objectAtIndex:0];
NSLog(@"%@",docPath);

Library

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libPath = [paths objectAtIndex:0];
NSLog(@"%@",libPath);

iOS应用结构

  • App Store下载的App安装在/var/mobile/Container/Bundle/Application下
  • 系统自身的App和越狱商店安装的App安装在/Applications下

iOS文件权限

iOS是一个多用户操作系统,每个用户扮演着不同的角色,对系统的控制权也各不相同。root用户具有系统最高控制权,可以执行所有命令,而mobile用户只能执行一些权限比较低的命令。“组”是用户的一种组织方式,一个组可以包含多个用户,一个用户也可以归属于多个组。

我们使用ls -l命令可以查看文件的各种权限。类似“-rwxr-xr--”这样的就是文件的权限信息。权限信息由10个bit来划分,最前面一个bit表示文件类型。如“d”表示目录、“l”表示符号链接、“-”表示普通文件。接下来的9个bit平分为3组,分别如下:

  • 所有者权限:决定文件的所有者可以对文件执行的操作。
  • 所属组权限:决定属于改组的成员对他所拥有的文件能够执行的操作。
  • 其他人权限:表示其他人对于该文件能够进行的操作。

r:read 代表读权限 w: write 代表写权限 x: execute代表执行权限 -: 该位置无对应权限

权限设置

权限设置使用二进制表示:如果某一位为1则代表权限生效,为0无效。例如:要使某个文件的所有者具有r、w、x权限,所属组具有r、w权限,其他人只有r权限。则可用二进制表示为:111-110-100。同时二进制111-110-100转成八进制为764。所以可以使用chmod命令设置权限:

chmod 764 xxx.txt

参考文章

File System Programming Guide

iOS之系统文件目录

《iOS应用逆向与安全之道》