在 Mac 上查看 iPhone 备份内容,导出短信和联系人

想查看 Mac 上的 iPhone 备份,可以先用访达找到备份目录,把整份备份复制出来,再检查里面的文件。访达能管理和恢复备份,但没有逐条阅读短信、联系人和备忘录的界面,未加密的备份可以用 SQLite 查看文件索引,需要直接读会话、导出单条记录时,可以用 Yado 的本地备份浏览,加密备份则需要输入这份备份的密码。
先用访达找到备份
在访达菜单栏点开前往,选前往文件夹,粘贴下面的路径,再按 Return。
~/Library/Application Support/MobileSync/Backup/
如果目录里有多份备份,可以连接 iPhone,在访达中选中设备,打开通用,点管理备份,右键点需要的那份,选在访达中显示。Apple 的备份位置说明也列出了归档操作,归档后,这份备份就不会被后续备份覆盖。
只想找到备份、保留某个日期的版本,用访达就够了,打开目录后看到的是备份文件,里面的短信还需要按备份格式解析,才能读成会话。
等正在进行的备份结束,把其中一份完整的备份文件夹复制到单独的位置,保留里面的文件名和目录结构,后面的检查都对着副本做,原件留着不动。如果 Mac 上还没有本地备份,可以先看把 iPhone 备份到 Mac。
备份里的文件怎样对应到原始内容
本地备份中的文件用了哈希名称,Manifest.db 保存着这些名称和原始位置的对应关系,每条记录里的 fileID 对应实际文件,domain 和 relativePath 一起标出它属于哪部分数据、原来放在哪里。比如手机主目录的数据和 App 群组共享的数据,就在不同的 domain 里。
短信、联系人和备忘录用到的数据库分别在下面这些位置。
| 内容 | Domain | 相对路径 |
|---|---|---|
| 信息 | HomeDomain |
Library/SMS/sms.db |
| 联系人 | HomeDomain |
Library/AddressBook/AddressBook.sqlitedb |
| 备忘录 | AppDomainGroup-group.com.apple.notes |
NoteStore.sqlite |
备忘录数据库的名字是 NoteStore.sqlite,Note 后面没有 s,在备份目录里直接搜索名叫 sms.db 的文件,也找不到对应的哈希文件,需要先查索引,拿到它的 fileID。
Yado 读取的这类备份,把文件放在以 fileID 前两个字符命名的子目录里,文件名则是完整的 40 位 fileID,找到文件后,还要继续读数据库的表和编码字段,才能把记录显示出来。

用只读命令检查未加密的备份
下面的命令只读取副本中的索引,把 /path/to/copied-backup 换成那份包含 Manifest.db 的备份目录,路径带空格时,外面的双引号要保留。
sqlite3 -readonly -header -column "/path/to/copied-backup/Manifest.db" \
"SELECT fileID, domain, relativePath
FROM Files
WHERE flags = 1 AND (
(domain = 'HomeDomain' AND relativePath IN (
'Library/SMS/sms.db',
'Library/AddressBook/AddressBook.sqlitedb'
)) OR
(domain = 'AppDomainGroup-group.com.apple.notes'
AND relativePath = 'NoteStore.sqlite')
);"
SQLite 的 -readonly 参数让数据库以只读方式打开,-header 和 -column 负责显示列名、对齐输出,这条查询只筛出文件索引,查到一行只能说明索引里有这个文件,不能证明其中每条短信或备忘录都能解析。
接下来可以把信息数据库和它的配套文件一起查出来,不用逐个打开那些看不出名字的文件。
sqlite3 -readonly -header -column "/path/to/copied-backup/Manifest.db" \
"SELECT fileID, relativePath
FROM Files
WHERE flags = 1 AND domain = 'HomeDomain'
AND relativePath LIKE 'Library/SMS/sms.db%';"
这条查询也会列出备份中存在的 sms.db-wal 和 sms.db-shm,SQLite 已提交的修改可能还在预写日志里,只复制主数据库,就可能少读一些记录。如果要在另一个工作目录里手动还原数据库文件,把索引对应的配套文件也复制过去,恢复成同名配套文件,备份副本本身继续保持原样。
这两条命令只检查索引,导出可读会话还需要继续解析数据库,直接查询 message 表的 text 列可能读不全,Yado 在纯文本为空时还会读取编码后的 attributedBody,再把信息与会话、发送者关联起来。
加密备份为什么需要密码
加密备份会保护索引数据库和里面的文件,Yado 先用备份密码解开 keybag 中的密钥,再解密索引和需要读取的数据,因此上面的 SQLite 命令只适用于未加密的备份。
这里需要的是当时加密这份备份用的密码,Yado 的解锁操作不能绕过它,改文件名也不会让文件解密。Apple 在加密备份说明里写得很清楚,忘记密码后重设,可以为手机当前的数据创建一份新备份,但无法让之前的加密备份重新可用。
在 Yado 里逐条查看和导出
打开 Yado 的概览标签,在备份卡片里点管理,找到已有备份下需要的那一行,鼠标移过去后点查看内容。没连接手机时,只要本地列表里有备份,也可以点开 Yado 标志的菜单,选查看备份。
Yado 扫描的是设置里的备份位置,和访达的默认目录分开,查看从访达复制出来的备份时,打开设置,在备份位置旁点更改,选中那份备份副本的上一级目录。这个操作也会改变以后 Yado 备份的存放位置,需要的话先记下原来的位置,查看结束后再改回去,备份放在其他磁盘时,也可以参考把 iPhone 备份放到外置硬盘。
- 备份已加密时,输入这份备份的密码,点解锁。
- 打开信息、通讯录或备忘录,查看里面的记录。
- 在搜索中输入会话标识或短信里的词,结果会列出匹配的会话,打开后就能读里面的信息。
- 会话和备忘录点导出文本,联系人点导出 vCard,再选目标文件夹。
一段会话导出成 .txt,里面有时间、发送者和正文,备忘录也是 .txt,联系人则是 .vcf,信息里的单条记录指一段会话,不是单独选中的一条气泡。列表底部的全部导出会导出整个类别,当前搜索结果之外的记录也在其中。
浏览期间,解析后的记录和搜索结果保存在内存里,不建立长期保存的搜索索引,读取用的数据库副本会临时放进工作目录,加密备份解密后的数据库也一样,关闭浏览、等读取任务结束后再移除。查看本地备份不用连着 iPhone,试用结束后,这项浏览能力也会保留。
导出后核对内容,缺少记录时先看范围
打开导出的会话文本,找一段自己知道的内容,对照浏览界面里的发送者和日期,联系人则检查需要的字段,再决定是否导入其他地方,可读的导出文件和能恢复手机的备份用途不同,原备份也继续留着。
逐条浏览目前只用于联系人、备忘录和信息,其他类别提供导出,没有同样的记录详情页。信息里的附件可能显示为 [附件],文本不会把照片、视频一起嵌进去,备忘录提取的是纯文本,不保留附件和富文本排版,已锁定、标记删除的备忘录也会跳过。
某个类别为空,不能据此判断手机当时没有这些数据,Apple 的电脑备份说明列出了已经同步并储存在 iCloud 中的数据不进入电脑备份,iCloud 照片和信息都在这个范围里,同时也要核对选中的设备和备份日期。
无法读取时先保留备份,对照原目录确认副本是否复制完整,再继续尝试,不完整、格式不支持和密码错误是不同的问题。导出失败时检查目标文件夹能否写入,再亲自打开生成的文件核对内容,能读出一段会话,也不能证明整份备份已经通过 iPhone 恢复验证。