Run a daemon (as root) on iOS11 and iOS12
daemon包括三个部分:一个可执行的二进制文件、一个plist配置文件、一个二进制文件授权文件
注意事项
- 测试环境
- macOS: 10.14.6
- iPhoneOS: iOS11.0和iOS12.0
- iPhone机型:两个iPhone6
- 越狱工具:unc0ver3.6.2
可执行二进制文件配置
- 下载最新版theos,利用theos来创建一个可执行二进制文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23$ 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
填入以下内容1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#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文件并配置权限
1
2
3$ cd k9sd/
$ touch com.slfh.k9sd.plist
$ chmod 644 com.slfh.k9sd.plist安装后把
com.slfh.k9sd.plist
放到iPhone上的/Library/LaunchDaemons/
目录1
2$ mkdir -p ./Layout/Library/LaunchDaemons/
$ mv com.slfh.k9sd.plist ./Layout/Library/LaunchDaemons/sublime打开
com.slfh.k9sd.plist
,并填入内容1
2
3
4
5
6
7
8
9
10
11
12
13
14<?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
,发现并没有启动 - 使用控制台可以查看如下错误,错误是由于没有给二进制文件授权
1
Sandbox: hook..execve() killing k9sd[pid=14153, uid=0]: outside of container && !i_can_has_debugger
二进制文件授权
新建授权文件
1
touch ./Layout/Library/LaunchDaemons/com.slfh.k9sd.entitlements
打开
com.slfh.k9sd.entitlements
,填入以下内容1
2
3
4
5
6
7
8<?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安装完成后执行相应的命令
1
2
3$ mkdir ./bin
$ touch ./bin/postinst
$ chmod 755 ./bin/postinst打开postinst文件,填入以下内容
1
2
3
4#!/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)
1
2
3
4
5
6before-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
,发现已经启动了1
2
3
4
5slfh:~ 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如下
1
2
3
4
5
6
7slfh:~ 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如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19iPhone:~ 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#
- iOS11如下
成功,到此结束