注意事项
- 测试环境
- macOS: 10.14.6
- iPhoneOS: iOS11.0、iOS12.0、
- iPhone机型:两个iPhone6
- 越狱工具:unc0ver3.6.2
- 没有测试:iOS13和iOS10,也许可以。
- 关于链接
- 原文传送门
- 此文使用Theos新建的App,如果使用Xcode新建的App,请转入RunAppAsRootForXcode
- 阅读本文前,请首先阅读狗神的 Run an App as root on iOS
- 实现目标:点击按钮执行
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
进行新建$ 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
中填写以下内容#import <spawn.h> 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。
RootAppTest: 501, 501, 1
设置uid和euid
-
main.m
中设置uid#import "RAAppDelegate.h" int main(int argc, char *argv[]) { @autoreleasepool { setuid(0); return UIApplicationMain(argc, argv, nil, NSStringFromClass(RAAppDelegate. class)); } }
-
Makefile
中添加如下内容设置euidafter-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,注销操作执行失败,还需要为可执行文件签权RootAppTest: 0, 0, 1
可执行文件签权
- 新建RootApp.entitlements文件,填写内容为:
<?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填入下面内容对可执行文件签权
RootApp_CODESIGN_FLAGS = -SRootApp.entitlements
最后
- 最终
Makefile
内容为ARCHS = 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成功。