Run an App as root on iOS11 and iOS12 with Theos
注意事项
- 测试环境
- macOS: 10.14.6
- iPhoneOS: iOS11.0、iOS12.0、
- iPhone机型:两个iPhone6
- 越狱工具:unc0ver3.6.2
- 没有测试:iOS13和iOS10,也许可以。
- 实现目标:点击按钮执行
killall -9 SpringBoard
,注销SpringBoard
理论部分
1. App所有权
/Applications
目录存放系统自带的应用,这个目录下存放的应用一般属于root:admin
。- 想要
Run an App as root
,要把自己的.app文件放到这个目录下
2. 用户标识
- 文件的所有者和程序的所有者是不一样的,程序的所有者通常被用作用户标识
- 为了
Run an App as root
,我们需要更改用户的uid和euid为0
新建RootApp
使用
nic.pl
进行新建1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24$ nic.pl
NIC 2.0 - New Instance Creator
------------------------------
[1.] iphone/activator_event
[2.] iphone/application_modern
[3.] iphone/application_swift
[4.] iphone/cydget
[5.] iphone/flipswitch_switch
[6.] iphone/framework
[7.] iphone/ios7_notification_center_widget
[8.] iphone/library
[9.] iphone/notification_center_widget
[10.] iphone/preference_bundle_modern
[11.] iphone/tool
[12.] iphone/tool_swift
[13.] iphone/tweak
[14.] iphone/xpc_service
Choose a Template (required): 2
Project Name (required): RootApp
Package Name [com.yourcompany.rootapp]: me.rootapp.app
Author/Maintainer Name [XX]: drag
[iphone/application_modern] Class name prefix (two or more characters) [XX]: RA
Instantiating iphone/application_modern in rootapp/...
Done.RARootViewController.m
中填写以下内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int spawn(const char* executable, ...) {
int ret;
pid_t pid;
va_list args;
va_start(args, executable);
ret = posix_spawn(&pid, executable, NULL, NULL, (char* const *)args, NULL);
if (ret == 0) waitpid(pid, NULL, 0);
return ret;
}
- (void)addButtonTapped:(id)sender {
[_objects insertObject:[NSDate date] atIndex:0];
[self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:0 inSection:0] ] withRowAnimation:UITableViewRowAnimationAutomatic];
NSLog(@"RootAppTest: %d, %d, %d", getuid(), geteuid(), spawn("/usr/bin/killall","/usr/bin/killall", "-9", "SpringBoard", NULL));
}执行
make clean && make && make package && make install
进行编译安装- 看不到App图标,执行
uicache
刷新就可以了 - RootApp会安装到/Applications目录下
- 看不到App图标,执行
打开App,点击加号按钮打印uid和euid都为501,注销操作也失败,所以我们需要设置uid和euid。
1
RootAppTest: 501, 501, 1
设置uid和euid
main.m
中设置uid1
2
3
4
5
6
7
int main(int argc, char *argv[]) {
@autoreleasepool {
setuid(0);
return UIApplicationMain(argc, argv, nil, NSStringFromClass(RAAppDelegate. class));
}
}Makefile
中添加如下内容设置euid1
2after-stage::
$(ECHO_NOTHING)chmod +s $(THEOS_STAGING_DIR)/Applications/RootApp.app/RootApp$(ECHO_END)- 执行
make clean && make && make package && make install
后,打开App,点击加号按钮,打印uid和euid都为0,注销操作执行失败,还需要为可执行文件签权1
RootAppTest: 0, 0, 1
可执行文件签权
- 新建RootApp.entitlements文件,填写内容为:
1
2
3
4
5
6
7
8
9
10
11
12<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/ DTDs /PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.private.security.no-container</key>
<true/>
<key>com.apple.private.skip-library-validation</key>
<true/>
<key>platform-application</key>
<true/>
</dict>
</plist> - 把RootApp.entitlements放到和Makefile同级目录,Makefile填入下面内容对可执行文件签权
1
RootApp_CODESIGN_FLAGS = -SRootApp.entitlements
最后
- 最终
Makefile
内容为1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18ARCHS = arm64
TARGET = iPhone:latest:8.0
include $(THEOS)/makefiles/common.mk
APPLICATION_NAME = RootApp
RootApp_FILES = main.m RAAppDelegate.m RARootViewController.m
RootApp_FRAMEWORKS = UIKit CoreGraphics
RootApp_CODESIGN_FLAGS = -SRootApp.entitlements
include $(THEOS_MAKE_PATH)/application.mk
after-stage::
$(ECHO_NOTHING)chmod +s $(THEOS_STAGING_DIR)/Applications/RootApp.app/ RootApp$(ECHO_END)
after-install::
install.exec "su mobile -c uicache"
install.exec "killall \"RootApp\"" || true - 执行
make clean && make && make package && make install
后,点击按钮,注销SpringBoard成功。