使用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程序。

➜  ~        cd ~/Desktop

➜  Desktop  mkdir mytweaks

➜  Desktop  cd mytweaks

然後執行我們剛纔的獲得的theos來生成一個tweak的模板:

➜  mytweaks  /opt/theos/bin/nic.pl

NIC 2.0 - New Instance Creator

------------------------------

  [1.] iphone/application

  [2.] iphone/library

  [3.] iphone/preference_bundle

  [4.] iphone/tool

  [5.] iphone/tweak

Choose a Template (required): 5

Project Name (required): FirstTweak

Package Name [com.yourcompany.firsttweak]: com.joeyio.firsttweak

Author/Maintainer Name [Joey]:

[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]:

[iphone/tweak] List of applications to terminate upon installation (space-separated,'-' for none) [SpringBoard]:

Instantiating iphone/tweak in firsttweak/...

Done.

在創建模板的時候,我們選擇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編譯一下,可能結果是這樣的:

➜  firsttweak  make

/Users/qiaoxueshi/Desktop/mytweaks/firsttweak/theos/makefiles/targets/Darwin/iphone.mk:41: Deploying to iOS 3.0 while building for 6.0 will generate armv7-only binaries.

Making all for tweak FirstTweak...

 Preprocessing Tweak.xm...

Name "Data::Dumper::Purity" used only once: possible typo at /Users/qiaoxueshi/Desktop/mytweaks/firsttweak/theos/bin/logos.pl line 615.

 Compiling Tweak.xm...

 Linking tweak FirstTweak...

 Stripping FirstTweak...

 Signing FirstTweak...

 /bin/sh: ldid: command not found

我們看到裏面有2個警告,第一個我沒有搜索到什麼結果,第二個是隻要手機上安裝ldid就行了,這裏不用管它。我自己試了一下,是可以安裝到手機上的,可以暫時忽略,如果哪位小夥伴知道什麼原因,歡迎告知。

在部署到手機之前確認手機和電腦在一個wifi環境下,並且可以通過SSH連接到手機,方法是在Terminal下,通過SSH連接到手機,之後會提示你輸入root密碼(上面安裝SSH步驟中有提到),確保連接成功再往下進行。手機的IP地址可以在wifi設置中看到。

ssh root@手機IP地址

然後把手機IP地址放在THEOS_DEVICE_IP環境變量中,這樣theos才知道安裝到哪裏,如下:

export THEOS_DEVICE_IP=手機IP地址

然後執行make package install打包並安裝到手機上 (如果Cydia在前臺,把它退到後臺,否則安裝會失敗):

➜  firsttweak  make package install

/Users/qiaoxueshi/Desktop/mytweaks/firsttweak/theos/makefiles/targets/Darwin/iphone.mk:41: Deploying to iOS 3.0 while building for 6.0 will generate armv7-only binaries.

Making all for tweak FirstTweak...

make[2]: Nothing to be done for `internal-library-compile'.

Making stage for tweak FirstTweak...

dpkg-deb:正在新建軟件包“com.joeyio.firsttweak”,包文件爲“./com.joeyio.firsttweak_0.0.1-2_iphoneos-arm.deb”。

install.exec "cat > /tmp/_theos_install.deb; dpkg -i /tmp/_theos_install.deb && rm /tmp/_theos_install.deb" < "./com.joeyio.firsttweak_0.0.1-2_iphoneos-arm.deb"

[email protected]'s password:

Selecting previously deselected package com.joeyio.firsttweak.

(Reading database ... 6250 files and directories currently installed.)

Unpacking com.joeyio.firsttweak (from /tmp/_theos_install.deb) ...

Setting up com.joeyio.firsttweak (0.0.1-2) ...

install.exec "killall -9 SpringBoard"

[email protected]'s password:

安裝過程中需要輸入兩次手機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。整個文件看起來像這樣:

include theos/makefiles/common.mk


TWEAK_NAME = FirstTweak

FirstTweak_FILES = Tweak.xm

FirstTweak_FRAMEWORKS = UIKit


include $(THEOS_MAKE_PATH)/tweak.mk


after-install::

    install.exec "killall -9 SpringBoard"

這個步驟完成之後,我們就要找到鎖屏界面對應的ViewController,然後替換它的某個方法,把UILabel添加到它的view上。這個ViewController的名字叫SBAwayController, SB是SpringBoard的縮寫,不要想偏了 :).我們要替換它的- (void)activate方法。SBAwayController類的頭文件可以在iOS6的私有類的頭文件中找到。在SBAwayController裏有個叫_awayViewivar,獲得這個ivar需要一個theos中不存在的方法,好吧,它叫MSHookIvar,這個方法在默認的theos的substrate.h頭文件裏沒有,可以在GitHub得到包含這個方法的頭文件。下載到本地,覆蓋theos/include下的同名文件(推薦將原有的substrate.h頭文件重命名)。

OK,到這裏萬事具備,只欠Coding了。

打開firsttweak目錄下的Tweak.xm文件並清空,添加下面這段代碼:

%hook SBAwayController 

- (void)activate  {

    %orig(); //invoke the orignal method to do what should to do.

    NSLog(@"=========================================================");

    NSLog(@"Hello MobileSubstrate!!");

    NSLog(@"=========================================================");

    

    //get _awayView via MSHookIvar method

    UIView *_awayView = MSHookIvar<*>(self,"_awayView");

    

    //create a lable whose width = 200 and height = 100 and add to _awayView

    float w =200;

    float h =100;

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((_awayView.frame.size.width - w)/2,100,w,h)];

    label.text = @"Hello, MobileSubstate!!";

    label.textAlignment = NSTextAlignmentCenter;

    label.backgroundColor = [UIColor clearColor];

    label.textColor = [UIColor whiteColor];

    [_awayView addSubview:label];

}

%end

大概解釋一下,%hook SBAwayController以及裏面的- (void)activate方法,其實就類似swizzling了SBAwayControlleractivate方法。當系統執行SBAwayControlleractivate方法的時候會執行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

原文地址:http://joeyio.com/ios/2014/01/01/make-a-mobile-substrate-tweak-using-theos/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章