Theos是什么?
Theos是国外大神DHowett发明的开发 iOS 越狱插件的工具,DHowett的 Theos 大幅简化了编写越狱程序的流程。
Theos工作流程?
开发者编写 hook 代码 -> deb插件 -> 安装到手机
一、安装 thoes
- 环境介绍:
- macOS Catalina 10.15.4
- theos 2.5
- iPhone 6 / iOS 12.3.1
- Xcode 11.5
- 安装 ldid 签名库
brew install ldid xz
- 设置环境变量
// ~/.bash_profile 文件添加如下两句
export THEOS=~/theos
export PATH=$THEOS/bin:$PATH
再运行 source ~/.bash_profile
指令让配置立刻生效
- 下载 theos 代码
git clone --recursive https://github.com/theos/theos.git $THEOS
为什么我们不在 Github 直接利用浏览器 clone 按钮下载呢?
解答:打开 theos 中的 .gitmodules
文件我们发现,它依赖了很多子模块,直接下载代码会导致依赖的子模块未下载。
- 下载 theos 需要的 iOS SDK
从 Xcode7.3 开始,不在提供私有库供我们使用,所以我们需要执行下面指令去下载。
curl -LO https://github.com/theos/sdks/archive/master.zip
TMP=$(mktemp -d)
unzip master.zip -d $TMP
mv $TMP/sdks-master/*.sdk $THEOS/sdks
rm -r master.zip $TMP
二、使用 theos,结合结合之前的工具把某 APP 的广告去掉。
去掉图中广告-
使用 Reveal 工具分析,如上图所示,我们找到该广告的类为
XMPlayPageAdView
-
因为该 APP 是我们从 App Store 下载的,需要使用
dumpdecrypted
工具进行动态脱壳。 -
脱壳完成后,使用
class-dump
工具抽取该 APP 的头文件。 -
分析头文件:
该类没有初始化方法
我们找它的父类 -
结论:我们需要使用 theos 来 hook 掉
XMBaseAdView
的- (id)initWithFrame:(struct CGRect)arg1;
方法。 -
在 mac 上 输入
nic.pl
指令初始化一个 theos 项目。
carrotdeMacBook-Pro:ting carrot__lsp$ nic.pl
NIC 2.0 - New Instance Creator
------------------------------
[1.] iphone/activator_event
[2.] iphone/activator_listener
[3.] iphone/application_modern
[4.] iphone/application_swift
[5.] iphone/cydget
[6.] iphone/flipswitch_switch
[7.] iphone/framework
[8.] iphone/library
[9.] iphone/notification_center_widget
[10.] iphone/notification_center_widget-7up
[11.] iphone/preference_bundle_modern
[12.] iphone/theme
[13.] iphone/tool
[14.] iphone/tool_swift
[15.] iphone/tweak
[16.] iphone/tweak_with_simple_preferences
[17.] iphone/xpc_service
Choose a Template (required): 15
Project Name (required): tingtweak
Package Name [com.yourcompany.tingtweak]: com.mj.tingtweak
Author/Maintainer Name [carrot__lsp]: carrot
[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: com.gemd.iting
[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard]:
Instantiating iphone/tweak in tingtweak/...
Done.
初始化过程如上所示,唯一注意的是 MobileSubstrate Bundle filter
这是我们需要 hook 的项目的 BundleID,我们可以使用 cycript
去手机上获取。
-
配置 theos 项目。
打开项目,配置手机 ip 和端口
// Tweak.x 文件中加入的代码
%hook XMBaseAdView
- (id)initWithFrame:(struct CGRect)arg1 {
return nil;
}
%end
- 分别 在 theos 项目中运行
make clean
->make
->make package
->make install
四个命令。如果顺利,我们手机将会重启 SpringBoard,打开刚刚我们 hook 的 APP。
效果图,广告不见了
三、使用 theos 可能会遇到的问题
- 没有按照以上步骤按照,导致命令无法成功执行
- theos2.5 我使用 usb 进行
make install
的时候会导致卡住,最后发现使用Wifi
模式一下就成功了。(暂时还不确定是什么问题)
四、使用 theos 让 iPhone 桌面上所有烦人的小红点消息提示永远消失。
让设置和 App Store 的小红点消失我们看的 iPhone 桌面,也是运行在 iOS 上的一个 APP,它的名字叫做
SpringBoard
,但是我们无法用Reveal
这个 App 的页面结构。
- 在 iPhone 上使用
ps -A
指令找到SpringBoard
。
15519 ?? 1:17.68 /System/Library/CoreServices/SpringBoard.app/SpringBoard
- 使用
cycript -p SpringBoard
登陆它 - 打印出当前页面所有的 view
密密麻麻的 view
这时候就要考验开发经验了,通常我们开发红点的时候一般会叫做badge
,这个名字,我们拿着这个名字,去搜索,发现可以找到
SBIconParallaxBadgeView
我们如何确定是否是我们需要控制的红点 view 呢?我可以拿到它的地址,通过如下代码验证
#0x145248c10.hidden=1
结果设置身上的红点消失了,说明我们找对了。
- 接下来我们找到
SpringBoard
的Mach-O
文件,发现并不需要脱壳,所以重复上面二、使用 theos,结合结合之前的工具把某 APP 的广告去掉
的思路,即可将红点隐藏了。
四、使用 theos 给 qq 加些页面。
任务要求:1.添加一个带有开关音乐cell,保存开关的状态。2.添加一个能退出程序的退出按钮。
在红框位置修改
- 使用
Reveal
找到相关 view 的所在控制器。
Reveal 分析
分析可知这些 cell 都是在QQRecommendViewController
中 - 利用
dumpdecrypted
脱壳,然后用class-dump
导出头文件,找到QQRecommendViewController
的头文件,发现里面有tableView
相关方法。
- 接下来的思路就是用
theos
来 hook 这些方法,添加我们自己的 cell 了。
// hook 代码如下
@interface QQRecommendViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
@end
@interface QQRecomViewTableViewCell
@property(retain, nonatomic) UILabel *titleNickLabel;
@property(retain, nonatomic) UIView *accessoryView;
@end
@class QQRecommendViewController;
@class QQRecomViewTableViewCell;
%hook QQRecommendViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return %orig;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return %orig;
}
- (id)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (([self numberOfSectionsInTableView:tableView] - 1) == indexPath.section) {
if (indexPath.row == 0) {
QQRecomViewTableViewCell *musicCell = (QQRecomViewTableViewCell*)%orig;
musicCell.titleNickLabel.text = @"音乐开关";
UISwitch *musicSwitch = [[UISwitch alloc] init];
musicSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:@"CarrotMusicSwitch"];
musicCell.accessoryView = musicSwitch;
[musicSwitch addTarget:self action:@selector(musicSwitchClicked:) forControlEvents:UIControlEventValueChanged];
return musicCell;
} else {
QQRecomViewTableViewCell *logoutCell = (QQRecomViewTableViewCell*)%orig;
logoutCell.titleNickLabel.text = @"退出登录";
return logoutCell;
}
} else {
return %orig;
}
}
%new
- (void)musicSwitchClicked:(UISwitch*)musicSwitch {
[[NSUserDefaults standardUserDefaults] setBool:musicSwitch.on forKey:@"CarrotMusicSwitch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (([self numberOfSectionsInTableView:tableView] - 1) == indexPath.section) {
return 44;
} else {
return %orig;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (([self numberOfSectionsInTableView:tableView] - 1) == indexPath.section) {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == 0) {
} else {
exit(0);
}
} else {
%orig;
}
}
%end
- 最终效果图
四、使用 theos,实现改造 QQ 任务实现的注意点。
-
%hook
类里面的代码,默认的行为是只能替换,不能新创建方法。 - 所以我们
musicSwitchClicked
这个方法前面要使用%new
老告诉 theos,我们需要创建新的方法。 - 使用
%orig
是让代码执行原有代码的逻辑,自己会自动传原本需要的参数。 - 如果需要再 theos 调用其他类和方法,需要用
@class
和@interface
进行声明,不然会报错。 - 如果 thoes 报错
control reaches end of non-void function
,是表示有些方法必须有返回值,而我们没有给返回值。 - 如果在我们添加 hook 代码之后,程序奔溃了怎么办呢?我们可以
Xcode
的window
菜单中找到Devices and Simulator
,里面可以查看 iPhone 的崩溃信息。
网友评论