daemon包括三个部分:一个可执行的二进制文件、一个plist配置文件、一个二进制文件授权文件
注意事项
-
测试环境
- macOS: 10.14.6
- iPhoneOS: iOS11.0和iOS12.0
- iPhone机型:两个iPhone6
-
关于链接
- 原文传送门
- 阅读本文前,请首先阅读狗神的Run a daemon (as root) on iOS
可执行二进制文件配置
- 下载最新版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如下
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#
- 成功,到此结束