Run an App as root on iOS11 and iOS12

注意事项

  • 测试环境
    • 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进行新建

    $ 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,点击加号按钮打印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中添加如下内容设置euid
      after-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成功。

需要 root 干啥呢? 可以问下?

比如package manager?

我的iOS13 设置uid和euid后一打开APP就crash掉,按狗神说的 backboardd是mobile权限的,无法启动root进程,因此加了个bash脚本,然后就

一直报这个错,我的bash脚本也是个可执行文件,也执行了sudo chmod 777 权限的,ps:设置uid和euid之前APP是可以运行的,点右上角+按钮会crash掉,查看日志输出是501,501,0

chmod +s或者chmod 6755

嗯,试了你的方法,好像不太行,还是那个权限问题