使用 Theos 做一个简单的 Mobile Substrate Tweak
Mobile Substrate 和 Theos
Mobile Substrate 是 Cydia 的作者 Jay Freeman (@saurik) 的另外一个牛 X 的作品,也叫 Cydia Substrate, 它的主要功能是 hook 某个 App,修改代码比如替换其中方法的实现,Cydia 上的 tweak 都是基于 Mobile Substrate 实现的。目前支持 iOS 和 Android 平台。
根据 github 上的介绍,theos 是一个跨平台 iPhone Makefile 系统。它的主要功能是生成 iPhone 越狱 App、tweak 等程序的框架结构,并提供 makefile 来编译、打包和安装。
需要的准备工作:
#Mac
- 安装 Theos,从 Theos 的 GitHub 上 clone 下来一份,放到某个目录下,这里我放到了
/opt/
下。 - 安装 Xcode Command Line Tools,可以在命令行下执行
xcode-select --install
来安装或者参考 SO 来安装,安装完之后再进行下一步。 - 安装 dpkg ,首先安装 MacPorts,可以通过它的官网 , 根据自己的系统版本来选择。安装好之后,重启 Terminal,执行
port version
,显示出版本号说明安装成功。如果提示command not found
,尝试在/etc/paths
文件中加入下面两个路径:/opt/local/bin
/opt/local/sbin
,需要使用 root 权限来编辑,比如用 Vim 的话:sudo vi /etc/paths
. 重启 Terminal,再次输入port version
就应该会显示版本号了,然后执行sudo port selfupdate
来更新一下,之后执行sudo port install dpkg
来安装 dpkg. 安装 dpkg 的目的是把我们写的 tweak 打成 deb 包。
#JailBreaked iPhone iOS 5/6
- 安装 OpenSSH,打开 Cydia 的主界面就能看到
OpenSSH Access How-To
以及Root Password How-To
的选项,可以按照它的提示一步一步安装,这里不赘述了,需要提醒的是一定要改掉 root 的密码,防止别人通过 SSH 连接到你的手机。这一步是为了后面我们通过 SSH 连接到手机,把 deb 包安装到手机上准备的。
iOS7 上的 Mobile Substrate 还有 bug,32 位的系统下每次重启后需要重新安装 Mobile Substrate 才能正常使用,64 位今天貌似才能用。推荐暂时在 iOS5/6 的机器上测试 [2014-01-01]。 - apt. 在 cydia 中搜索 Apt 检查是否已经安装,没有安装就安装一下。
- ldid. 全名是 Link Identify Editor, 也直接可以在 Cydia 中搜索全名安装。
创建 Tweak 并安装到手机上
首先我在桌面上创建一 mytweaks
的文件夹,保存我们要创建的 tweak 程序。
1 | ➜ ~ cd ~/Desktop |
然后执行我们刚才的获得的 theos 来生成一个 tweak 的模板:
1 | ➜ mytweaks /opt/theos/bin/nic.pl |
在创建模板的时候,我们选择 5,创建一个 iPhone 的 tweak. 其他 4 个选项可以自己去搜索下。名字输入 FirstTweak,包名我输入 com.joeyio.firsttweak,下面的三个选项都直接回车使用缺省值。MobileSubstrate Bundle filter
这一项表示要 hook 的程序,默认是 com.apple.springboard
,就是 hook Spring Board,如果你想 hook 别的 App,这里改成那个 App 的 BundleID.
OK,那么我们的第一个 tweak 就创建好了,好像一点也不难啊。进入到 firsttweak 目录下,使用 make
编译一下,可能结果是这样的:
1 | ➜ firsttweak make |
我们看到里面有 2 个警告,第一个我没有搜索到什么结果,第二个是只要手机上安装 ldid 就行了,这里不用管它。我自己试了一下,是可以安装到手机上的,可以暂时忽略,如果哪位小伙伴知道什么原因,欢迎告知。
在部署到手机之前确认手机和电脑在一个 wifi 环境下,并且可以通过 SSH 连接到手机,方法是在 Terminal 下,通过 SSH 连接到手机,之后会提示你输入 root 密码(上面安装 SSH 步骤中有提到),确保连接成功再往下进行。手机的 IP 地址可以在 wifi 设置中看到。
1 | ssh root@手机IP地址 |
然后把手机 IP 地址放在 THEOS_DEVICE_IP
环境变量中,这样 theos 才知道安装到哪里,如下:
1 | export THEOS_DEVICE_IP=手机IP地址 |
然后执行 make package install
打包并安装到手机上 (如果 Cydia 在前台,把它退到后台,否则安装会失败):
1 | ➜ firsttweak make package install |
安装过程中需要输入两次手机 Root 密码,一次是为了把打包后的 deb 程序文件传到手机上,另外一次是 kill 掉 SpringBoard,使 SpringBoard 重启。
完成后在 Cydia 里的 “变更” 里,往下翻一翻,就能看到一个名字为 “FirstTweak” 的插件了了,想想接下来出任 CEO,迎娶白富美,走向人生巅峰,有木有一点小激动?
完成一个小功能
到目前为止,我们还没写过一行代码呢。下面我们要完成一个小功能:在锁屏界面增加一个 UILabel 显示一行文字,可以是你的座右铭或者其他的,这里我们显示 Hello, MobileSubstate!!
。
打开我们刚才创建的 firsttweak 目录下的 Makefile
文件,在 FirstTweak_FILES = Tweak.xm
下面增加一行 FirstTweak_FRAMEWORKS = UIKit
并保存文件,前缀都是 TWEAK_NAME
的值,也就是 FirstTweak
, 注意根据你自己的情况来修改。增加这行的原因很明显,增加 UILabel 需要用到 UIKit Framework。整个文件看起来像这样:
1 | include theos/makefiles/common.mk |
这个步骤完成之后,我们就要找到锁屏界面对应的 ViewController,然后替换它的某个方法,把 UILabel 添加到它的 view 上。这个 ViewController 的名字叫 SBAwayController
, SB 是 SpringBoard
的缩写,不要想偏了 :). 我们要替换它的 - (void)activate
方法。SBAwayController
类的头文件可以在 iOS6 的私有类的头文件中找到。在 SBAwayController 里有个叫_awayView
的 ivar
,获得这个 ivar 需要一个 theos 中不存在的方法,好吧,它叫 MSHookIvar
, 这个方法在默认的 theos 的 substrate.h
头文件里没有,可以在 GitHub 得到包含这个方法的头文件。下载到本地,覆盖 theos/include 下的同名文件(推荐将原有的 substrate.h
头文件重命名)。
OK,到这里万事具备,只欠 Coding 了。
打开 firsttweak 目录下的 Tweak.xm
文件并清空,添加下面这段代码:
1 | %hook SBAwayController |
大概解释一下,%hook SBAwayController
以及里面的 - (void)activate
方法,其实就类似 swizzling 了 SBAwayController
的 activate
方法。当系统执行 SBAwayController
的 activate
方法的时候会执行 tweak 里的 activate
的方法。 在这里方法里我们先执行了 %orig()
,就是执行原来的 activate
方法,保证原有的方法先执行,再执行我们自己的代码。
这个 activate
方法在第一次进入锁屏界面的时候会执行,在以后每次非锁屏状态下,按关机键也会执行。
接下来就是通过 MSHookIvar
获得_awayView
。然后就是我们非常熟悉的了,创建一个 UILabel,添加到_awayView
里。到这里就结束了。make package install
一下 (还需要先执行一下 export THEOS_DEVICE_IP=手机IP地址
),安装到手机上,等 SpringBoard 重启完,你会看到类似下图的界面:
把手机连接到电脑上,打开 Xcode,在 Organizer 里的 Console 里能看到程序中使用 NSLog 打印的信息,用来调试很方便呢。
总结
本文主要是讲 Mobile Substrate 的作用以及如何使用 Theos 开发一个简单的 tweak。有了这些入门的基础之后,你就可以根据自己的想法来写自己喜欢的 tweak。如果你是在 iOS7 下越狱的话,可以尝试一下把控制中心的 AirDrop 和音乐播放器给隐藏掉,让控制中心看起来更简洁。接着可以再进行改进,比如在蓝牙关闭的时候不显示 AirDrop,开启的时候依然显示,音乐正在播放的时候显示音乐播放器,否则不显示。
这个小 Demo 是前两周写的,一直没有时间整理出来,今天抽时间整理了一下文字发了出来,算是送给自己新年的一件礼物吧!
Thanks,Have Fun!
More About Substrate And Theos
- iphonedevwiki
- Theos/Getting Started
- Cydia Substrate(Mobile Substrate 也叫做 Cydia Substrate)