记一次(没有成功的)macOS 故障修复

macOS 自带的 Dictionary.app 中,只有维基百科一个词典
macOS 自带的 Dictionary.app 中,只有维基百科一个词典

在我升级 macOS Catalina 之后,发现系统自带的词典(Dictionary.app)无法使用,打开后只有「维基百科」一个词典。

然后,我就开始尝试一系列故障修复的过程,虽然最终没有成功,但在这个过程中,还是发现了一些有意思的东西,想通过这篇博客记录下来。

初步分析

由于打开 Dictionary.app 之后,会出现一两秒中的「正在下载」的对话框。基本上可以确定,这些词典不是安装系统的时候已经安装好的,而是需要安装完系统,联网下载的。

首先上网搜索一下词典下载目录,发现在 macOS Catalina 上,这些动态下载的内容,存放在 /System/Library/AssetsV2 路径下。例如,/System/Library/AssetsV2/com_apple_MobileAsset_DictionaryServices_dictionaryOSX 里面存放词典,System/Library/AssetsV2/com_apple_MobileAsset_Font6 下存放附加字体。

而在我的电脑上,/System/Library/AssetsV2 里面没有这些目录。再打开 Font Book.app,发现确实除了词典,还有许多字体也是灰色的,无法下载。

/System/Library/AssetsV2 中,也没有找到词典、附加字体等目录
/System/Library/AssetsV2 中,也没有找到词典、附加字体等目录

先是怀疑可能是我的 SIP 没设置好,导致系统无法在这个目录下面写入文件。但是无论是完全打开 SIP,还是完全关闭 SIP,都无法解决问题。

分析 log

由于词典文件是动态下载的,那么下载词典失败的时候,应该会有日志信息。于是我打开了 Console.app,然后再打开词典,果然,控制台里面出现了不少 log。

下载词典的目录叫 AssetsV2,我就在控制台中,以 asset 为关键词来进行搜索,确实有找到下载失败的 log,而且,还发现了下载词典的进程,名字叫 mobileassetd

打开 Dictionary.app,发现控制台中 mobileassetd 输出了错误 log
打开 Dictionary.app,发现控制台中 mobileassetd 输出了错误 log

进一步分析 log,发现词典是从 basejumper.apple.com 这个域名上下载的,但是通过 nslookup 命令对其进行 DNS 查询,并没有查询到 A 记录,也就是说,下载词典的网址是一个无效的网址,导致词典下载不下来。

观察 log,发现是从 basejumper.apple.com 下载文件失败
观察 log,发现是从 basejumper.apple.com 下载文件失败

而对比了一台正常的 macOS 电脑,在正常的电脑上,词典是从 mesu.apple.com 下载的,而这个网址是能够正常访问的。那为什么两台电脑下载词典的网址不一样?在网上以 basejumper、mesu 等关键词搜索,发现这个链接中,有一些有用的信息:

https://opensource.apple.com/source/security_certificates/security_certificates-55093.1.2/Pinning/README.txt

* Mesu - the production / public-facing host for MobileAssets.
* Basejumper - the internal server for hosting / testing MobileAssets. Users must be within the internal network and have a default set in order to reach Basejumper.

也就是说,mesu.apple.com 是实际生产环境中使用的服务器,用户的电脑下载词典等文件的时候,都应该使用 mesu.apple.com。而 basejumper.apple.com 应该是 Apple 内部用于测试的服务器。

怀疑电脑中的配置文件存在问题,但经过查找,也没有找到哪个文件中存在 basejumper 字样的配置。于是,我开始了下一步分析。

分析 mobileassetd 文件

前文中提到,下载词典是 mobileassetd 进程进行的,经过简单查找,发现这个文件位于 /usr/libexec/mobileassetd。我想确认一下 basejumper.apple.commesu.apple.com 这两个可执行文件是不是写死在 mobileassetd 中,而不是从配置文件中动态读取的。

使用 Synalyze It! 十六进制编辑器,打开 mobileassetd,搜索 basejumper,确实发现了这两个网址,都是以字符串形式直接存在于 mobileassetd 中的。

用十六进制编辑器打开 /usr/libexec/mobileassetd,发现里面有 basejumper.apple.com 的字符串
用十六进制编辑器打开 /usr/libexec/mobileassetd,发现里面有 basejumper.apple.com 的字符串

反汇编

既然已经确定了这两个网址是存在于 mobileassetd 中的,我决定尝试一下反汇编,看能不能得出一些结论。

这是我第一次尝试反汇编,经过搜索,知道了在 macOS/iOS 上,可以使用 Hopper Disassembler。而这个工具也提供了 30 分钟的试用版。

下载之后,用这个工具打开 mobileassetd,在里面查找 basejumper 字符串,然后一级一级查看这个字符串的引用关系,以及函数调用关系,最终发现在 serverURLForAssetType 这个函数/方法中,能够根据传入的参数,判断是返回 mesu.apple.com,还是 basejumper.apple.com。不过进一步分析调用关系,就不太好分析了,所以我也没有再继续分析。

另外,我还看到了 serverURLForAssetType 中也会读取 com.apple.MobileAsset.SystemApp 配置。

(由于不确定 macOS 系统文件的反汇编结果是否允许公开,此处不再附上反汇编的截图。)

最后的一些分析

由于在反汇编的过程中,找到了 com.apple.MobileAsset.SystemApp 这条配置,我最后尝试了一下读取这条配置,但对应的配置也不存在。

使用 default read com.apple.MobileAsset,无法读取到配置
使用 default read com.apple.MobileAsset,无法读取到配置

继续上网搜索,阅读了一些文章后,发现对应的配置常存在于 macOS 和 iOS beta 版本的描述文件中,可用于指定版本升级的服务器。

这样一来,如果通过 Apple Configurator 手动指定正确的服务器地址,获取能够临时解决问题。不过暂时也没有进行尝试。

上网搜索 com.apple.MobileAsset,发现 iOS 描述文件中,有用到 com.apple.MobileAsset,可能通过描述文件的方式,强制指定服务器地址为 mesu.apple.com,能够解决问题
上网搜索 com.apple.MobileAsset,发现 iOS 描述文件中,有用到 com.apple.MobileAsset,可能通过描述文件的方式,强制指定服务器地址为 mesu.apple.com,能够解决问题

后记

经过上述分析,最终能够确定 macOS 的词典列表为空,是因为在这些词典是系统安装后,从 Apple 的服务器下载的。而我的电脑上,没有使用正确的服务器地址。

但服务器的地址是固定在 mobileassetd 可执行文件中的,通过传入不同的函数参数来获取不同的服务器地址。目前还没有弄明白这个函数参数是从哪里来的。不过后续尝试了一下全新安装 macOS,问题依旧存在,怀疑与 bootloader 有关。

另外,我前几天刚刚阅读到了一篇论文:One Billion Apples’ Secret Sauce: Recipe for the Apple Wireless Direct Link Ad hoc Protocol。这篇文章通过抓包、反汇编等多种方式,分析 Apple 的 AWDL 协议。其中的分析方法值得学习。

“记一次(没有成功的)macOS 故障修复”的3个回复

  1. 这问题应该是苹果的吧。
    我也遇到了很多奇葩问题,比如下载几十MB文件提示空间不足,但还400G……
    自带mail程序提示空间不足…
    受不了了,回滚系统了

    1. 不知道是不是因为我自己做的融合硬盘.原厂是32G+1T机械,我自己做的32G+512G的SSD。然后按官方方法做成了融合硬盘。

发表评论

电子邮件地址不会被公开。 必填项已用*标注