Run a daemon (as root) on iOS11 and iOS12

daemon包括三个部分:一个可执行的二进制文件、一个plist配置文件、一个二进制文件授权文件

注意事项

可执行二进制文件配置

  • 下载最新版theos,利用theos来创建一个可执行二进制文件
    $ 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): 11
    Project Name (required): k9sd
    Package Name [com.yourcompany.k9sd]: com.slfh.k9sd
    Author/Maintainer Name [XX]: slfh
    Instantiating iphone/tool in k9sd/...
    Done
    
  • sublime打开main.mm填入以下内容
    #include <spawn.h>
    
    int spawn(const char* executable, ...) {
        int     ret;
        pid_t   pid;
        va_list args;
        va_start(args, executable);
        setuid(0);
        ret = posix_spawn(&pid, executable, NULL, NULL, (char* const *)args, NULL);
        if (ret == 0) waitpid(pid, NULL, 0);
        return ret;
    }
    
    static void logout(CFNotificationCenterRef center, void   *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
        spawn("/usr/bin/killall", "/usr/bin/killall", "-9", "SpringBoard", NULL);
    }
    
    int main(int argc, char **argv, char **envp) {
        NSLog(@"k9sd: k9sd is launched!");
        CFNotificationCenterAddObserver(  CFNotificationCenterGetDarwinNotifyCenter(), NULL, logout,   CFSTR("com.slfh.k9sd.logout"), NULL,   CFNotificationSuspensionBehaviorCoalesce);
        CFRunLoopRun(); // keep it running in background
        return 0;
    }
    

plist文件配置

  • 创建plist文件并配置权限

    $ cd k9sd/
    $ touch com.slfh.k9sd.plist
    $ chmod 644 com.slfh.k9sd.plist
    
  • 安装后把com.slfh.k9sd.plist放到iPhone上的/Library/LaunchDaemons/目录

     $ mkdir -p ./Layout/Library/LaunchDaemons/
     $ mv com.slfh.k9sd.plist ./Layout/Library/LaunchDaemons/
    
  • sublime打开com.slfh.k9sd.plist,并填入内容

    <?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>KeepAlive</key>
            <true/>
            <key>Label</key>
            <string>com.slfh.k9sd</string>
            <key>Program</key>
            <string>/usr/bin/k9sd</string>
            <key>RunAtLoad</key>
            <true/>
    </dict>
    </plist>
    

测试

  • 利用make install进行安装
  • 安装后ssh进入iPhone执行ps -e | grep k9sd,发现并没有启动
  • 使用控制台可以查看如下错误,错误是由于没有给二进制文件授权
    Sandbox: hook..execve() killing k9sd[pid=14153, uid=0]: outside of container && !i_can_has_debugger
    

二进制文件授权

  • 新建授权文件

    touch ./Layout/Library/LaunchDaemons/com.slfh.k9sd.entitlements
    
  • 打开com.slfh.k9sd.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>platform-application</key>
        <true/>
    </dict>
    </plist>
    
  • 新建postinst文件,作用是deb安装完成后执行相应的命令

    $ mkdir ./bin
    $ touch ./bin/postinst
    $ chmod 755 ./bin/postinst
    
  • 打开postinst文件,填入以下内容

    #!/bin/sh
    /usr/bin/ldid -S/Library/LaunchDaemons/com.slfh.k9sd.entitlements /usr/bin/k9sd;
    /bin/launchctl load /Library/LaunchDaemons/com.slfh.k9sd.plist;
    exit 0;
    
  • 打开Makefile文件填入以下内容(如果make错误,需要把这些命令缩进对齐然后再次tab)

    before-package::  
      cp ./bin/postinst ./.theos/_/DEBIAN/
      rm -rf ./packages/*.deb
    
    after-install::
      install.exec "killall -9 SpringBoard"
    

再次测试

  • 利用make clean && make && make package && make install进行安装(记得要先打包然后安装!!!)

  • 安装后ssh进入iPhone执行ps -e | grep k9sd,发现已经启动了

    slfh:~ root# ps -e | grep k9sd
    13572 ??         0:00.00 (k9sd)
    14184 ??         0:00.02 /usr/bin/k9sd
    14318 ttys000    0:00.04 grep k9sd
    slfh:~ root#
    
  • 使用Cycript发送通知,进行重启SpringBoard操作

iOS11使用Cycript参考
iOS12使用Cycript参考

  • iOS11如下
    slfh:~ root# cycript -p SpringBoard
    cy# np = @encode(unsigned int(*)(char const*))(dlsym(RTLD_DEFAULT,     "notify_post"))
    &(extern "C" unsigned int notify_post(char const*))
    cy# np("com.slfh.k9sd.logout")
    [14621] DarwinInjector.cpp[246]: _krncall(mach_vm_read_overwrite) =10000003
    *** _assert(status == 0):../Inject.cpp(143):InjectLibrary
    slfh:~ root#
    
  • iOS12如下
    iPhone:~ root# cyrun -n SpringBoard -e -d -f
    applicationName: SpringBoard is running (9707)
        executableName: SpringBoard
        bundleIdentifier: com.apple.springboard
        Cycript is inactive:
        Device is not passcode locked
        Tweak Mode
    Waiting for Process to close...
    Waiting for SpringBoard to launch...
    Waiting for Cycript to become active...
    Success, you may now run
        cycript -r 127.0.0.1:8556
    cy# np = @encode(unsigned int(*)(char const*))(dlsym(RTLD_DEFAULT,         "notify_post"))
    &(extern "C" unsigned int notify_post(char const*))
    cy# &(extern "C" unsigned int notify_post(char const*))
    &(extern "C" unsigned int notify_post(char const*))
    cy# np("com.slfh.k9sd.logout")
    0
    cy#
    
  • 成功,到此结束
5 Likes

感谢分享,总结很到位 :+1:

感谢分享,总结很到位 :+1:

感谢分享。