Theos
Theos简介
Theos是一个越狱开发工具包,由iOS越狱界知名人士 Dustin Howett 开发并分享到 GitHub 上。Theos 与其他越狱开发工具相比,最大特点就是简单:下载安装简单、Logos语法简单、编译发布简单,可以让使用者将精力都放在开发工作上去。
安装 Theos
1、安装Xcode与Command Line Tools
一般来说,iOS开发者都会安装Xcode,其中附带 了Command Line Tools。如果还没有安装Xcode,请到 Apple Developer 免费下载。如果安装了多个Xcode, 需要使用xcode-select命令指定一个活动Xcode,即Theos默认使用的Xcode。假设安装了3个Xcode,并将它们分别命名为Xcode1.app、Xcode2.app和 Xcode3.app,若要指定Xcode3为活动Xcode,则运行如下命令:
sudo xcode-select -s /Applications/Xcode3.app/Contents/Developer
2、签名工具ldid安装
brew install ldi
3、修改环境变量
Theos官方建议我们将Theos克隆到/theos目录下,而且/theos路径之后需要多次使用,所以将~/theos配置为环境变量
- 首先,进入cd ~进入根目录,在根目录下有访问.bash_profile文件
vim ~/.bash_profile
- 在.bash_profile文件最后加入下面两行
export THEOS=~/theos
export PATH=$THEOS/bin:$PATH
- 配置完成之后,在终端执行source命令,使.bash_profile文件的配置立即生效
source ~/bash_profile
- 此时我们通过$PATH来打印出PATH信息,就可以看到THEOS目录已经添加到了PATH中
4、下载Theos
通过以下命令将Theos下载到上面配置的$THEOS
目录中
git clone --recursive https://github.com/theos/theos.git $THEOS
--recursive表示递归下载,因为Theos会依赖其它库,使用此命令可以递归的将所有依赖的库都下载下来
tweak项目
1、创建tweak项目
1)cd到存放项目的目录,执行nic.pl指令,如下:
cd ~/Desktop/Theos
nic.pl
2)选择“17”,即创建一个tweak工程,命令如下:
Choose a Template (required): 17
3)输入tweak的工程名称,命令如下:
Project Name (required): iOSProject
4)输入deb包的名字(类似于bundle identifier),命令如下:
Package Name [com.yourcompany.iosproject]: com.ios.iosproject
5)输入tweak作者的名字,命令如下:
Author/Maintainer Name [作者的名字]: 作者的名字
6)输入“MobileSubstrate Bundle filter”,也就是 tweak作用对象的bundle identifier,命令如下:
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.apple.springboard
7)输入tweak安装完成后需要重启的应用,以进 程名表示,如下:
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]: SpringBoard
Instantiating iphone/tweak in iosproject/...
Done.
简单的7步完成之后,一个名为iosproject的文件夹就在当前目录生成了,该文件夹里就是刚创建的 tweak 工程。
2、定制工程文件
进入工程中可以看到生成的工程目录,如下:
(1)MakeFile
Makefile文件指定工程用到的文件、框架、库等 信息,将整个过程自动化。iOSREProject的Makefile内 容如下:
TARGET := iphone:clang:latest:7.0
INSTALL_TARGET_PROCESSES = SpringBoard
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = iOSProject
iOSProject_FILES = Tweak.x
iOSProject_CFLAGS = -fobjc-arc
include $(THEOS_MAKE_PATH)/tweak.mk
下面来逐行解读:
- 指定SDK版本
TARGET := iphone:clang:latest:7.0
- 目标安装的项目
INSTALL_TARGET_PROCESSES = SpringBoard
- 固定写法,不要更改
include $(THEOS)/makefiles/common.mk
- tweak的名字,即用Theos创建工程时指定的“Project Name”,跟control文件中“Name”字段对应,不要更改。
TWEAK_NAME = iOSProject
- tweak包含的源文件(不包括头文件)
iOSProject_FILES = Tweak.x
多个文件间以空格分隔,如:
iOSREProject_FILES = Tweak.xm Hook.xm New.x ObjC.m ObjC++.mm
- 采用ARC内存管理
iOSProject_CFLAGS = -fobjc-arc
- 根据不同的Theos工程类型,通过include命令指 定不同的.mk文件;在逆向工程初级段,我们开发的一般是Application、Tweak和Tool三种类型的程序, 它们对应的.mk文件分别是application.mk、tweak.mk 和tool.mk,可以按需更改。
include $(THEOS_MAKE_PATH)/tweak.mk
添加其他信息:
- 指定处理器架构
ARCHS = armv7 arm64
- 导入framework
iOSProject_FRAMEWORKS = framework name
例如:
iOSREProject_FRAMEWORKS = UIKit CoreTelephony CoreAudio
- 链接Mach-O对象
iOSProject_LDFLAGS = -lx
例如:
iOSProject_LDFLAGS = -lz –lsqlite3.0 –dylib1.o
(2)control
control文件记录了deb包管理系统所需的基本信 息,会被打包进deb包里。iOSProject里control文件 的内容如下:
Package: com.ios.iosproject
Name: iOSProject
Version: 0.0.1
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: shh
Author: shh
Section: Tweaks
Depends: mobilesubstrate (>= 0.9.5000)
-
Package
字段用于描述这个deb包的名字,采用的命名方式同bundle identifier类似,均为反向DNS格式,可以按需更改; -
Name
字段用于描述这个工程的名字,可以按需更改; -
Version
字段用于描述这个deb包的版本号,可 以按需更改; -
Architecture
字段用于描述deb包安装的目标设 备架构,不要更改; -
Description
字段是deb包的简单介绍,可以按需更改; -
Maintainter
字段用于描述deb包的维护人,例如BigBoss源中所有deb包的维护人均为BigBoss,而非软件作者,可以按需更改; -
Author
字段用于描述tweak的作者(注意与Maintainer的区别),可以按需更改; -
Section
字段用于描述deb包所属的程序类别,不要更改。 -
Depends
字段用于描述这个deb包的“依赖”。“依赖”指的是这个程序运行的基本条件,可以填写固件版本或其他程序,如果当前iOS不满足“依赖”中定义的条件,则此tweak无法正常运 行。如
Depends: mobilesubstrate, firmware (>= 8.0)
表示当前iOS版本必须在8.0以上,且必须安装mobilesubstrate,才能正常运行这个tweak,可以按需更改。
(3)iOSProject.plist
这个plist文件的作用和App中的Info.plist类似,它记录了一些配置信息,描述了tweak的作用范围。我们可以用plutil,也可以用Xcode来编辑它。
iOSProject.plist 的最外层是一个dictionary,只有一个名为“Filter”的键,
Filter下是一系列array,可以分为三类:
- Bundles,指定多干bundle为tweak的作用对象。按如下图的配置,tweak的作用对象是一个bundle,即 Springboard、AddressBook。
- Classes,指定若干class为tweak的作用对象。按如下图的配置,tweak的作用对象是三个 class,即NSString、SBAwayController和 SBIconModel。
- Executables,指定若干可执行文件为tweak的作用对象。如下图所示,tweak的作用对象是三个可执行文件,即callservicesd、imagent和mediaserverd。
这三类array可以混合使用,如下图所示:
注意:
当Filter下有不同类的array时,需要添加一个“Model: Any”键值对。当Filter下的array只有一类时,不需要添加“Model: Any”
(4)Tweak.xm
用Theos创建tweak工程,默认生成的源文件是 Tweak.xm。xm
中的x
代表这个文件支持Logos语法,如果后缀名是单独一个x
,说明源文件支持Logos和C语法;如果后缀名是xm
,说明源文件支持Logos和C/C++语法,与m
和mm
的区别类似。 Tweak.xm的内容如下:
%hook ClassName
// Hooking a class method
+ (id)sharedInstance {
return %orig;
}
// Hooking an instance method with an argument.
- (void)messageName:(int)argument {
%log; // Write a message about this call, including its class, name and arguments, to the system log.
%orig; // Call through to the original function with its original arguments.
%orig(nil); // Call through to the original function with a custom argument.
// If you use %orig(), you MUST supply all arguments (except for self and _cmd, the automatically generated ones.)
}
// Hooking an instance method with no arguments.
- (id)noArguments {
%log;
id awesome = %orig;
[awesome doSomethingElse];
return awesome;
}
// Always make sure you clean up after yourself; Not doing so could have grave consequences!
%end
语法简介
tweak使用的Logos语法简介,可以点击Logos官网查看完整的语法介绍。
%hook、%end :#表示hook一个类的开始和结束
%log :#打印方法调用详情,可以通过Xcode -> Window -> Devices and Simulators
HBDebugLog : #和NSLog类似
%new :#添加一个新的方法
%c(className) : #生成一个Class对象,比如%c(NSObject),类似于NSStringFromClass()、objc_getClass()
%orig :#调用原先的方法逻辑
%ctor :#加载动态库的时候调用
%dtor :#在程序退出时调用
3、编译/打包/安装
(1)编译
Theos 采用“make”命令来编译Theos工程。在Theos工程目录下运行make命令,如下:
从输出的信息看,Theos完成了预处理、编译、 签名等一系列动作。此时会发现在当前目录下多了一个新的“.theos”文件夹,如下:
里面有一个.dylib文件,他就是tweak的核心
(2)打包
打包使用的“make package”命令来自于Theos本身,其实就是先执行“make”命令,然后再执行“dpkg- deb”命令,如下:
上面生成了一个com.ios.iosproject_0.0.1-1+debug_iphoneos-arm.deb
的文件,这就是最终发布的安装包。
“make package”命令还有一个很重要的功能。在执行完“make package”之后,除了“obj”文件夹外,你 会发现tweak工程目录下还生成了一个“_”文件夹,如下:
其中“DEBIAN”里只有tweak工程里的control文件,Theos在编译过程中向control文件里稍稍增加了 几个字段而已,如下:
Package: com.ios.iosproject
Name: iOSProject
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: shh
Author: shh
Section: Tweaks
Depends: mobilesubstrate (>= 0.9.5000)
Version: 0.0.1-1+debug
Installed-Size: 104
“Library”的目录结构如上图所示;
对比生成的deb包的内容如下:
以及在Cydia中的iOSProject文件系统,如下:
可以看到,三者是完全相同的。到这里,你可能也猜到了,这个deb包其实就是由“DEBIAN”提供debian信息,“Library”提供实际文件的简单组合。事实上,还可以在工程目录下创建一个名为“layout”的文件夹,然后把工程打包成deb并安装到iOS中,此时“layout”中的所有文件会被解包到iOS文件系统的相同位置(这里的“layout”相当于iOS中的根目录“/”), 这极大扩充了deb包的作用范围。
(3)安装
此处介绍两种最具代表性的:图形界 面安装法和命令行安装法。
- 图形界面安装
这个方法确实简单:通过iFunBox等软件把deb拖到iOS里去,然后用iFile安装它,最后重启iOS。虽然全过程都由图形界面操作,但人机交互太多,又要动电脑又要滑手机,一来二去非常繁琐,并不适用于 tweak开发。
- 命令行安装法
这个方法要用到简单的ssh命令,故而要求越狱的iOS安装了OpenSSH。下面具体介绍安装法。
首先,需要在Makefile的最上一行加上本机IP地址,如下:
THEOS_DEVICE_IP = iOSIP
ARCHS = armv7 arm64
TARGET = iphone:latest:8.0
然后调用“make package install”命令完成编译打包安装一条龙服务,如下:
Theos开发tweak示例
1、用Theos新建tweak工程“iOSREGreetings”
2、编辑Tweak.x
%hook SpringBoard
- (void)applicationDidFinishLaunching:(id)application {
%orig;
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Hello World!" message:nil delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
%end
3、编辑Makefile及control
编辑后的Makefile内容如下:
THEOS_DEVICE_IP = iOSIP
TARGET := iphone:clang:latest:7.0
INSTALL_TARGET_PROCESSES = SpringBoard
THEOS_DEVICE_IP = iOSIP
ARCHS = armv7 arm64
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = iOSREGreetings
iOSREGreetings_FILES = Tweak.x
iOSREGreetings_CFLAGS = -fobjc-arc
IOSREGreetings_FRMEWORKDS = UIKit
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
install.exec "killall -9 SpringBoard"
SUBPROJECTS += iosretargetapp
include $(THEOS_MAKE_PATH)/aggregate.mk
编辑后的control内容如下:
Package: com.iosre.iosregreetings
Name: iOSREGreetings
Version: 0.0.1
Architecture: iphoneos-arm
Description: An awesome MobileSubstrate tweak!
Maintainer: shh
Author: shh
Section: Tweaks
Depends: mobilesubstrate (>= 0.9.5000)
以上代码非常简单,当SpringBoard的applicationDidFinishLaunching:
函数得到调用时,代表SpringBoard的启动过程已经结束。钩住(hook)这个函数,调用%orig完成它的原始操作,然后弹出一个自定义的UIAlertView;这样一来,每次重启SpringBoard都会弹出一个对话框。你看懂了吗?
准备就绪,在Terminal中敲入“make package install”,即可安装到手机中。