背景
升级最新的MAC OSX El Capitan已经有段时间了,事实上最近系统已经更新到了10.11.2,也就是该大版本的第2个update。我有一台2011年的老Macbook Pro 15,我相信应该是其做工的问题,蓝牙信号很不好。拿去当地天才吧看过,确认了这个问题,但是告知我这款机器是将蓝牙天线集成在屏幕中的,如果要解决这个问题就需要连屏幕一起换了,于是我就算了。我需要在这台机器上使用蓝牙耳机,于是单独买了一个USB的蓝牙dongle(El Capitan直接支持一些外接USB蓝牙适配器,Broadcom 20702A1芯片,0a5c:21e8这款是大路货),这个问题也就算曲线解决了。但是我是一个不升级最新版本不舒服的人,也因为这点后面问题来了。
MAC中蓝牙驱动固件机制
大部分的Broadcom蓝牙设备使用一种叫RAMUSB的系统机制,这种机制允许系统把该设备的固件即时上传,但是每次关机或者重启就会丢失。在Broadcom提供给windows的驱动中,broadcom的驱动做法是每次开机就会上传一次最新的驱动。但是Mac OSX中不是这样的。所以针对我这款USB蓝牙适配器,虽然即插即用,但是固件版本是v4096(后续更新后可以到v5555)。那么自然就需要把类似windows中的做法也在mac中实现就可以了
BrcmPatchRAM
这方面老外总是早早的就有了想法,并且有了proof of concept的实现。BrcmPatchRAM就是这样一个可以帮我完成上节问题的开源项目,放在github上。实现方法大概如下: 以Mac OSX的内核扩展形式在每次开机时加载一次,将从windows驱动中提取出来的zhx格式固件上传,这样设备就可以用新版固件运行。
签名的内核扩展
好东西是有了,但是新问题又来了。早在OSX 10.8的时候,苹果就以安全为名义引入了需要签名的内核扩展,意思就是说不是随随便便的就可以写一个kext,放到系统中让系统在启动时一起加载的。OSX系统需要审查!只有获得苹果签名的kext才可以正常加载。而这类实用的野路子kext是肯定不会获得苹果的签名的。幸好在桌面系统上,苹果并没有严格到将以上规定设计成绝对。事实上一直以来都留了一个官方的开关,允许用户主动关闭这种审查。当然后果就是给恶意代码也开了方便之门。到了El Capitan,苹果将这个开关变了个法子,引入了所谓的SIP机制。一直到El Capitan的DP8之前,其实SIP是有明显的漏洞的。根据Pike的说法,他找到了在DP8之前根本不需要关闭SIP就可以随便植入不签名的kext的玩法。有兴趣的可以自翻看那篇博客,内容很是干货。
植入未签名kext
不管是SIP还是之前的kext-dev-mode,其实从安全性角度是很有必要打开的,确实我们平时实际使用中,针对弹出的要sudo权限的密码窗口,基本是直接给的。真的碰上一些恶意软件也是麻烦。截至目前10.11.2,苹果是允许你暂时关闭SIP,然后将未签名的kext复制到/System/Library/Extensions(俗称/S/L/E)。重启机器,这样osx系统会根据最新的改动,重新生成/System/Library/PrelinkedKernels/prelinkedkernel这个文件。然后我们可以将SIP重新打开,后续只要prelinkedkernel没有变化就没问题(一般在系统update时这个文件肯定会变。所以未签名的kext在系统小版本号更新后都会失效,需要重新开关SIP重启系统)。
爷,收下我的膝盖!
感受学习的力量!