From 94100149ea098703480320f0297f0e632bbe9c3f Mon Sep 17 00:00:00 2001 From: Nick Chan Date: Tue, 2 Apr 2024 14:39:02 +0800 Subject: [PATCH] changes --- include/libjailbreak/libjailbreak.h | 3 +- include/payload/payload.h | 6 ++- include/payload_dylib/common.h | 4 +- src/fakedyld/main/fakedyld.c | 11 +++-- src/payload/loader/launchdaemons.c | 20 +++++++- src/payload/loader/prelaunchd.c | 27 ++++++++-- src/payload/loader/setup_fakefs.c | 21 +++----- src/payload/loader/sysstatuscheck.c | 3 +- src/payload_dylib/bootscreend.c | 62 +++++++++++++++-------- src/payload_dylib/main.c | 77 +++++++++++++++++++++-------- src/payload_dylib/pspawn.c | 2 +- src/payload_dylib/xpc.c | 12 ++--- 12 files changed, 171 insertions(+), 77 deletions(-) diff --git a/include/libjailbreak/libjailbreak.h b/include/libjailbreak/libjailbreak.h index eb9e102..0b125b9 100644 --- a/include/libjailbreak/libjailbreak.h +++ b/include/libjailbreak/libjailbreak.h @@ -29,7 +29,8 @@ enum { LAUNCHD_CMD_SET_TWEAKLOADER_PATH, LAUNCHD_CMD_SET_PINFO_FLAGS, LAUNCHD_CMD_DRAW_IMAGE, - LAUNCHD_CMD_CRASH + LAUNCHD_CMD_CRASH, + LAUNCHD_CMD_RUN_BOOTSCREEND }; struct xpc_global_data { diff --git a/include/payload/payload.h b/include/payload/payload.h index 597ea11..1947552 100644 --- a/include/payload/payload.h +++ b/include/payload/payload.h @@ -20,8 +20,8 @@ void NSLog(CFStringRef, ...); #define CHECK_ERROR(action, loop, msg, ...) do { \ {int ___CHECK_ERROR_ret = (action); \ if (unlikely(___CHECK_ERROR_ret)) { \ - fprintf(stderr, msg ": %d (%s)\n", ##__VA_ARGS__, errno, strerror(errno)); \ - if (loop) spin(); \ + if (!loop) fprintf(stderr, msg ": %d (%s)\n", ##__VA_ARGS__, errno, strerror(errno)); \ + else _panic(msg ": %d (%s)\n", ##__VA_ARGS__, errno, strerror(errno)); \ }} \ } while (0) @@ -94,6 +94,8 @@ int overwrite_main(int argc, char* argv[]); void reload_launchd_env(void); void perform_reboot3(xpc_object_t peer, xpc_object_t xreply, xpc_object_t request, struct paleinfo* pinfo_p); ssize_t write_fdout(int fd, void* buf, size_t len); +_Noreturn void _panic(char* fmt, ...); +extern bool panic_did_enter; enum { /* only for sysstatuscheck and prelaunchd stage! */ diff --git a/include/payload_dylib/common.h b/include/payload_dylib/common.h index 639619b..5bd4ddb 100644 --- a/include/payload_dylib/common.h +++ b/include/payload_dylib/common.h @@ -16,8 +16,7 @@ #define CHECK_ERROR(action, msg) do { \ ret = action; \ if (unlikely(ret)) { \ - dprintf(fd_console, msg ": %d (%s)\n", errno, strerror(errno)); \ - spin(); \ +_panic(msg ": %d (%s)\n", errno, strerror(errno)); \ } \ } while (0) @@ -49,6 +48,7 @@ extern int (*spawn_hook_common_p)(pid_t *restrict pid, const char *restrict path char *const argv[restrict], char *const envp[restrict], void *pspawn_org); +_Noreturn void _panic(char* fmt, ...); #endif diff --git a/src/fakedyld/main/fakedyld.c b/src/fakedyld/main/fakedyld.c index b555b7d..44edadb 100644 --- a/src/fakedyld/main/fakedyld.c +++ b/src/fakedyld/main/fakedyld.c @@ -79,6 +79,8 @@ int main(int argc, char* argv[], char* envp[], char* apple[]) { } else { JBRootPathEnv = "JB_ROOT_PATH=/var/jb"; /* will fixup to preboot path in sysstatuscheck stage */ } + + char* hasVerboseBootEnv = has_verbose_boot ? "JB_HAS_VERBOSE_BOOT=1" : "JB_HAS_VERBOSE_BOOT=0"; char pinfo_buffer[50]; snprintf(pinfo_buffer, 50, "JB_PINFO_FLAGS=0x%llx", pinfo.flags); @@ -91,12 +93,14 @@ int main(int argc, char* argv[], char* envp[], char* apple[]) { char* launchd_envp1 = (launchd_envp0 + sizeof(INSERT_DYLIB)); char* launchd_envp2 = (launchd_envp1 + strlen(pinfo_buffer) + 1); char* launchd_envp3 = (launchd_envp2 + strlen(JBRootPathEnv) + 1); + char* launchd_envp4 = (launchd_envp3 + sizeof(DEFAULT_TWEAKLOADER)); memcpy(launchd_argv0, "/sbin/launchd", sizeof("/sbin/launchd")); memcpy(launchd_envp0, INSERT_DYLIB, sizeof(INSERT_DYLIB)); memcpy(launchd_envp1, pinfo_buffer, strlen(pinfo_buffer) + 1); memcpy(launchd_envp2, JBRootPathEnv, strlen(JBRootPathEnv) + 1); memcpy(launchd_envp3, DEFAULT_TWEAKLOADER, sizeof(DEFAULT_TWEAKLOADER)); - char** launchd_argv = (char**)((char*)launchd_envp3 + sizeof(DEFAULT_TWEAKLOADER)); + memcpy(launchd_envp4, hasVerboseBootEnv, strlen(hasVerboseBootEnv) + 1); + char** launchd_argv = (char**)((char*)launchd_envp4 + strlen(hasVerboseBootEnv) + 1); char** launchd_envp = (char**)((char*)launchd_argv + (2*sizeof(char*))); launchd_argv[0] = launchd_argv0; launchd_argv[1] = NULL; @@ -104,7 +108,8 @@ int main(int argc, char* argv[], char* envp[], char* apple[]) { launchd_envp[1] = launchd_envp1; launchd_envp[2] = launchd_envp2; launchd_envp[3] = launchd_envp3; - launchd_envp[4] = NULL; + launchd_envp[4] = launchd_envp4; + launchd_envp[5] = NULL; LOG("launchd environmental variables: "); for (int i = 0; launchd_envp[i] != NULL; i++) { LOG("%s", launchd_envp[i]); @@ -131,6 +136,4 @@ _Noreturn void panic(char* fmt, ...) { sleep(60); } abort_with_payload(42, 0x69, NULL, 0, reason_real, 0); - __asm__ ("b ."); - __builtin_unreachable(); } diff --git a/src/payload/loader/launchdaemons.c b/src/payload/loader/launchdaemons.c index 18ecb2c..f1393b9 100644 --- a/src/payload/loader/launchdaemons.c +++ b/src/payload/loader/launchdaemons.c @@ -5,6 +5,7 @@ #include #include #include +#include #include mach_port_t (*SBSSpringBoardServerPort)(void); @@ -15,7 +16,7 @@ void sb_launched(CFNotificationCenterRef __unused center, void __unused *observe CFRunLoopStop(loop); } -int launchdaemons(uint32_t __unused payload_options, uint64_t pflags) { +int launchdaemons(uint32_t payload_options, uint64_t pflags) { printf("plooshInit launchdaemons...\n"); int platform = get_platform(); if (platform == -1) { @@ -37,7 +38,22 @@ int launchdaemons(uint32_t __unused payload_options, uint64_t pflags) { fprintf(stderr, "failed to dlopen springboardservices\n"); } } else if (platform == PLATFORM_TVOS) { - sleep(15); // ??? +#if 0 + sleep(10); + if ((payload_options & payload_option_userspace_rebooted) == 0) { + xpc_object_t xdict, xreply; + xdict = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(xdict, "cmd", LAUNCHD_CMD_RUN_BOOTSCREEND); + int ret = jailbreak_send_launchd_message(xdict, &xreply); + if (ret) { + print_jailbreakd_reply(xreply); + } + xpc_release(xdict); + xpc_release(xreply); + } + sleep(5); // ??? +#endif + sleep(15); } if (pflags & palerain_option_safemode) { diff --git a/src/payload/loader/prelaunchd.c b/src/payload/loader/prelaunchd.c index 2d1bac7..4722be6 100644 --- a/src/payload/loader/prelaunchd.c +++ b/src/payload/loader/prelaunchd.c @@ -22,14 +22,17 @@ #include #include +bool has_verbose_boot; +bool panic_did_enter = false; + int prelaunchd(uint32_t payload_options, struct paleinfo* pinfo_p) { + has_verbose_boot = (strcmp(getenv("JB_HAS_VERBOSE_BOOT"), "1") == 0); setvbuf(stderr, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); printf("plooshInit prelaunchd...\n"); int platform = get_platform(); if (platform == -1) { - fprintf(stderr, "failed to determine current platform\n"); - spin(); + _panic("failed to determine current platform\n"); } if ((payload_options & payload_option_userspace_rebooted) == 0) { @@ -53,8 +56,7 @@ int prelaunchd(uint32_t payload_options, struct paleinfo* pinfo_p) { CHECK_ERROR(APFSVolumeRole(dev_rootdev, &role, NULL), 0, "APFSVolumeRole(%s) Failed", dev_rootdev); printf("found apfs volume role: 0x%04x\n", role); if (role != APFS_VOL_ROLE_RECOVERY) { - fprintf(stderr, "BUG: SAFETY: deleting non-recovery volume is not allowed\n"); - spin(); + _panic("BUG: SAFETY: deleting non-recovery volume is not allowed\n"); } else { CHECK_ERROR(errno = APFSVolumeDelete(pinfo_p->rootdev), 1, "failed to delete fakefs"); } @@ -77,3 +79,20 @@ int prelaunchd(uint32_t payload_options, struct paleinfo* pinfo_p) { return 0; } + +_Noreturn void _panic(char* fmt, ...) { + panic_did_enter = true; + char reason[1024], reason_real[1024]; + va_list va; + va_start(va, fmt); + vsnprintf(reason, 1024, fmt, va); + va_end(va); + snprintf(reason_real, 1024, "payload: %s", reason); + int fd = open("/cores/panic.txt", O_WRONLY | O_CREAT, 0644); + if (fd != -1) { + write(fd, reason_real, 1024); + close(fd); + } + kill(1, SIGUSR1); + while (1) sleep (86400); +} diff --git a/src/payload/loader/setup_fakefs.c b/src/payload/loader/setup_fakefs.c index 5aba8e5..98ab0d8 100644 --- a/src/payload/loader/setup_fakefs.c +++ b/src/payload/loader/setup_fakefs.c @@ -106,16 +106,14 @@ int setup_fakefs(uint32_t __unused payload_options, struct paleinfo* pinfo_p) { struct statfs rootfs_st; CHECK_ERROR(statfs("/", &rootfs_st), 1, "statfs / failed"); if (strcmp(rootfs_st.f_fstypename, "apfs")) { - fprintf(stderr, "unexpected filesystem type of /\n"); - spin(); + panic("unexpected filesystem type of /"); } char fakefs_mntfromname[50]; snprintf(fakefs_mntfromname, 50, "/dev/%s", pinfo_p->rootdev); if (access(fakefs_mntfromname, F_OK) == 0) { - fprintf(stderr, "fakefs already exists\n"); - spin(); + panic("fakefs already exists"); } struct cb_context context = { .pinfo_p = pinfo_p, .bytesToCopy = 0 }; @@ -131,8 +129,7 @@ int setup_fakefs(uint32_t __unused payload_options, struct paleinfo* pinfo_p) { context.bytesToCopy = attrbuf.spaceused; if ((attrbuf.spaceused + MINIMUM_EXTRA_SPACE) > (rootfs_st.f_bavail * rootfs_st.f_bsize)) { - fprintf(stderr, "Not enough space! need %lld bytes (%d bytes buffer), have %lld bytes.\n", (attrbuf.spaceused + MINIMUM_EXTRA_SPACE), MINIMUM_EXTRA_SPACE, (rootfs_st.f_bavail * rootfs_st.f_bsize)); - spin(); + panic("Not enough space! need %lld bytes (%d bytes buffer), have %lld bytes.`", (attrbuf.spaceused + MINIMUM_EXTRA_SPACE), MINIMUM_EXTRA_SPACE, (rootfs_st.f_bavail * rootfs_st.f_bsize)); } } @@ -154,8 +151,7 @@ int setup_fakefs(uint32_t __unused payload_options, struct paleinfo* pinfo_p) { int retval = APFSVolumeCreate(container, dict); if (retval) { - fprintf(stderr, "APFSVolumeCreate failed: %d: %s\n", retval, mach_error_string(retval)); - spin(); + panic("APFSVolumeCreate failed: %d: %s\n", retval, mach_error_string(retval)); } char actual_fakefs_mntfromname[50]; @@ -169,12 +165,10 @@ int setup_fakefs(uint32_t __unused payload_options, struct paleinfo* pinfo_p) { } else if (strstr(rootfs_st.f_mntfromname, "/dev/disk1s") != NULL) { snprintf(actual_fakefs_mntfromname, 50, "/dev/disk1s%d", fsindex+1); } else { - fprintf(stderr, "unexpected rootfs f_mntfromname %s\n", rootfs_st.f_mntfromname); - spin(); + panic("unexpected rootfs f_mntfromname %s", rootfs_st.f_mntfromname); } if (strcmp(actual_fakefs_mntfromname, fakefs_mntfromname)) { - fprintf(stderr, "unexpected fakefs name %s (expected %s)\n", actual_fakefs_mntfromname, fakefs_mntfromname); - spin(); + panic("unexpected fakefs name %s (expected %s)", actual_fakefs_mntfromname, fakefs_mntfromname); } sleep(2); struct apfs_mount_args args = { @@ -205,8 +199,7 @@ int setup_fakefs(uint32_t __unused payload_options, struct paleinfo* pinfo_p) { int fd_fakefs = open("/cores/fs/fake", O_RDONLY | O_DIRECTORY); if (fd_fakefs == -1) { - fprintf(stderr, "cannot open fakefs fd\n"); - spin(); + panic("cannot open fakefs fd"); } CHECK_ERROR(fs_snapshot_create(fd_fakefs, "orig-fs", 0), 1, "cannot create orig-fs snapshot on fakefs"); diff --git a/src/payload/loader/sysstatuscheck.c b/src/payload/loader/sysstatuscheck.c index a4ef943..b44fc93 100644 --- a/src/payload/loader/sysstatuscheck.c +++ b/src/payload/loader/sysstatuscheck.c @@ -13,6 +13,8 @@ #include #include +uint32_t dyld_get_active_platform(void); + #define SB_PREF_PLIST_PATH "/var/mobile/Library/Preferences/com.apple.springboard.plist" #define CF_STRING_GET_CSTRING_PTR(cfStr, cPtr) do { \ cPtr = (char*)CFStringGetCStringPtr(cfStr, kCFStringEncodingUTF8); \ @@ -169,7 +171,6 @@ int sysstatuscheck(uint32_t __unused payload_options, uint64_t pflags) { } remount(); - uint32_t dyld_get_active_platform(void); if (dyld_get_active_platform() == PLATFORM_IOS) enable_non_default_system_apps(); if (access("/private/var/dropbear_rsa_host_key", F_OK) != 0) { printf("generating ssh host key...\n"); diff --git a/src/payload_dylib/bootscreend.c b/src/payload_dylib/bootscreend.c index 879e841..e0b04c7 100644 --- a/src/payload_dylib/bootscreend.c +++ b/src/payload_dylib/bootscreend.c @@ -24,6 +24,28 @@ static void *base = NULL; static int bytesPerRow = 0; static int height = 0; static int width = 0; +#define BSD_LOG_TO_FILE + +#if !defined(TESTMAIN) +static int bsd_printf(const char* fmt, ...) { + va_list va; + va_start(va, fmt); + int retval = vfprintf(stderr, fmt, va); + va_end(va); +#if defined(BSD_LOG_TO_FILE) + int fd = open("/cores/bootscreend.txt", O_CREAT | O_WRONLY | O_APPEND, 0644); + if (fd != -1) { + va_start(va, fmt); + vdprintf(fd, fmt, va); + va_end(va); + close(fd); + } +#endif + return retval; +} +#else +#define bsd_printf(__VA_ARGS__) printf(__VA_ARGS__); +#endif static int init_display(void) { IOMobileFramebufferReturn retval = 0; @@ -31,11 +53,11 @@ static int init_display(void) { IOMobileFramebufferRef display = NULL; retval = IOMobileFramebufferGetMainDisplay(&display); if (retval) { - fprintf(stderr, "IOMobileFramebufferGetMainDisplay: %s\n", mach_error_string(retval)); - printf("trying IOMobileFramebufferGetSecondaryDisplay instead\n"); + bsd_printf("IOMobileFramebufferGetMainDisplay: %s\n", mach_error_string(retval)); + bsd_printf("trying IOMobileFramebufferGetSecondaryDisplay instead\n"); retval = IOMobileFramebufferGetSecondaryDisplay(&display); if (retval) { - fprintf(stderr, "IOMobileFramebufferGetSecondaryDisplay: %s\n", mach_error_string(retval)); + bsd_printf("IOMobileFramebufferGetSecondaryDisplay: %s\n", mach_error_string(retval)); return -1; } } @@ -43,10 +65,10 @@ static int init_display(void) { IOMobileFramebufferGetDisplaySize(display, &size); IOSurfaceRef buffer; IOMobileFramebufferGetLayerDefaultSurface(display, 0, &buffer); - printf("got display %p\n", display); + bsd_printf("got display %p\n", display); width = size.width; height = size.height; - printf("width: %d, height: %d\n", width, height); + bsd_printf("width: %d, height: %d\n", width, height); // create buffer CFMutableDictionaryRef properties = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); @@ -56,22 +78,22 @@ static int init_display(void) { CFDictionarySetValue(properties, CFSTR("IOSurfacePixelFormat"), CFNumberCreate(NULL, kCFNumberIntType, &(int){ 0x42475241 })); CFDictionarySetValue(properties, CFSTR("IOSurfaceBytesPerElement"), CFNumberCreate(NULL, kCFNumberIntType, &(int){ 4 })); buffer = IOSurfaceCreate(properties); - printf("created buffer at: %p\n", buffer); + bsd_printf("created buffer at: %p\n", buffer); IOSurfaceLock(buffer, 0, 0); - printf("locked buffer\n"); + bsd_printf("locked buffer\n"); base = IOSurfaceGetBaseAddress(buffer); - printf("got base address at: %p\n", base); + bsd_printf("got base address at: %p\n", base); bytesPerRow = IOSurfaceGetBytesPerRow(buffer); - printf("got bytes per row: %d\n", bytesPerRow); + bsd_printf("got bytes per row: %d\n", bytesPerRow); for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { int offset = i * bytesPerRow + j * 4; *(int *)(base + offset) = 0x00000000; } } - printf("wrote to buffer\n"); + bsd_printf("wrote to buffer\n"); IOSurfaceUnlock(buffer, 0, 0); - printf("unlocked buffer\n"); + bsd_printf("unlocked buffer\n"); int token; IOMobileFramebufferSwapBegin(display, &token); @@ -91,7 +113,7 @@ int bootscreend_draw_cgimage(const char* image_path) { retval = init_display(); if (retval) { - fprintf(stderr, "could not init display\n"); + bsd_printf("could not init display\n"); goto finish; } for (int i = 0; i < height; i++) { @@ -103,28 +125,28 @@ int bootscreend_draw_cgimage(const char* image_path) { bootImageCfString = CFStringCreateWithCString(kCFAllocatorDefault, image_path, kCFStringEncodingUTF8); if (!bootImageCfString) { - fprintf(stderr, "could not create boot image cfstring\n"); + bsd_printf("could not create boot image cfstring\n"); goto finish; } imageURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bootImageCfString, kCFURLPOSIXPathStyle, false); if (!imageURL) { - fprintf(stderr, "could not create image URL\n"); + bsd_printf("could not create image URL\n"); goto finish; } cgImageSource = CGImageSourceCreateWithURL(imageURL, NULL); if (!cgImageSource) { - fprintf(stderr, "could not create image source\n"); + bsd_printf("could not create image source\n"); goto finish; } cgImage = CGImageSourceCreateImageAtIndex(cgImageSource, 0, NULL); if (!cgImage) { - fprintf(stderr, "could not create image\n"); + bsd_printf("could not create image\n"); goto finish; } rgbColorSpace = CGColorSpaceCreateDeviceRGB(); if (!rgbColorSpace) { - fprintf(stderr, "could not create device RGB color space\n"); + bsd_printf("could not create device RGB color space\n"); goto finish; } @@ -149,14 +171,14 @@ int bootscreend_draw_cgimage(const char* image_path) { context = CGBitmapContextCreate(base, width, height, 8, bytesPerRow, rgbColorSpace, kCGImageAlphaPremultipliedFirst | kCGImageByteOrder32Little); if (!context) { - fprintf(stderr, "could not create context\n"); + bsd_printf("could not create context\n"); goto finish; } CGContextDrawImage(context, destinationRect, cgImage); retval = 0; - fprintf(stderr, "bootscreend: done\n"); + bsd_printf("bootscreend: done\n"); finish: if (bootImageCfString) CFRelease(bootImageCfString); @@ -173,7 +195,7 @@ static int bootscreend_draw_gradient(void) { int retval = -1; retval = init_display(); if (retval) { - fprintf(stderr, "could not init display\n"); + bsd_printf("could not init display\n"); goto finish_; } diff --git a/src/payload_dylib/main.c b/src/payload_dylib/main.c index 304141c..f0f6d11 100644 --- a/src/payload_dylib/main.c +++ b/src/payload_dylib/main.c @@ -16,10 +16,13 @@ #include #include #include +#include +#include #define HOOK_DYLIB_PATH "/cores/binpack/usr/lib/systemhook.dylib" #define ELLEKIT_PATH "/cores/binpack/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate" +bool has_verbose_boot; uint64_t pflags; void (*MSHookFunction_p)(void *symbol, void *replace, void **result) = NULL; int (*spawn_hook_common_p)(pid_t *restrict pid, const char *restrict path, @@ -110,14 +113,28 @@ uint64_t load_pflags(void) { return pflags; } +void _panic_on_signal(int signal) { + char panicBuffer[1024]; + panicBuffer[1023] = '\0'; + FILE* f = fopen("/cores/panic.txt", "r"); + if (!f) { + _panic("payload_dylib: panic signal received but could not open panic file"); + } + fread(panicBuffer, 1023, 1, f); + fclose(f); + _panic("%s", panicBuffer); +} + __attribute__((constructor))void launchd_hook_main(void) { if (getpid() != 1) return; + signal(SIGUSR1, _panic_on_signal); + has_verbose_boot = (strcmp(getenv("JB_HAS_VERBOSE_BOOT"), "1") == 0); + int fd_console = open("/dev/console",O_RDWR|O_SYNC|O_CLOEXEC,0); if (fd_console == -1) { - char errMsg[1024]; - snprintf(errMsg, 1024, "payload.dylib cannot open /dev/console: %d (%s)", errno, strerror(errno)); - reboot_np(RB_PANIC, errMsg); + _panic("payload.dylib cannot open /dev/console: %d (%s)", errno, strerror(errno)); } + dup2(fd_console, STDIN_FILENO); dup2(fd_console, STDOUT_FILENO); @@ -133,14 +150,12 @@ __attribute__((constructor))void launchd_hook_main(void) { waitpid(pid, &status, 0); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) { - fprintf(stderr, "/cores/payload exited with status code %d\n", WEXITSTATUS(status)); - spin(); + _panic("/cores/payload exited with status code %d\n", WEXITSTATUS(status)); } } else if (WIFSIGNALED(status)) { - fprintf(stderr, "/cores/payload exited abnormally: signal %d\n", WTERMSIG(status)); - spin(); + _panic("/cores/payload exited abnormally: signal %d\n", WTERMSIG(status)); } else { - spin(); + _panic("/cores/payload exited abnormally"); } if ((pflags & palerain_option_setup_rootful)) { @@ -150,37 +165,59 @@ __attribute__((constructor))void launchd_hook_main(void) { CHECK_ERROR(unmount("/cores/binpack", MNT_FORCE), "unmount(/cores/binpack)"); printf("Rebooting\n"); kern_return_t failed = host_reboot(mach_host_self(), 0x1000); - fprintf(stderr, "reboot failed: %d (%s)\n", failed, mach_error_string(failed)); - spin(); + _panic("reboot failed: %d (%s)\n", failed, mach_error_string(failed)); } - if ((pflags & palerain_option_verbose_boot) == 0) bootscreend_main(); + uint32_t dyld_get_active_platform(void); + if ( + ((pflags & palerain_option_verbose_boot) == 0) + && (dyld_get_active_platform() != PLATFORM_TVOS || getenv("XPC_USERSPACE_REBOOTED")) + ) bootscreend_main(); + void* systemhook_handle = dlopen(HOOK_DYLIB_PATH, RTLD_NOW); if (!systemhook_handle) { - fprintf(stderr, "dlopen systemhook failed: %s\n", dlerror()); - spin(); + _panic("dlopen systemhook failed: %s\n", dlerror()); } spawn_hook_common_p = dlsym(systemhook_handle, "spawn_hook_common"); if (!spawn_hook_common_p) { - fprintf(stderr, "symbol spawn_hook_common not found in " HOOK_DYLIB_PATH ": %s\n", dlerror()); - spin(); + _panic("symbol spawn_hook_common not found in " HOOK_DYLIB_PATH ": %s\n", dlerror()); } void* ellekit_handle = dlopen(ELLEKIT_PATH, RTLD_NOW); if (!ellekit_handle) { - fprintf(stderr, "dlopen ellekit failed: %s\n", dlerror()); - spin(); + _panic("dlopen ellekit failed: %s\n", dlerror()); } MSHookFunction_p = dlsym(ellekit_handle, "MSHookFunction"); if (!MSHookFunction_p) { - fprintf(stderr, "symbol MSHookFunction not found in " ELLEKIT_PATH ": %s\n", dlerror()); - spin(); + _panic("symbol MSHookFunction not found in " ELLEKIT_PATH ": %s\n", dlerror()); } initSpawnHooks(); InitDaemonHooks(); InitXPCHooks(); - + + signal(SIGUSR1, SIG_DFL); printf("=========== bye from payload.dylib ===========\n"); } + +_Noreturn +void +abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload, + uint32_t payload_size, const char *reason_string, + uint64_t reason_flags); + +_Noreturn void _panic(char* fmt, ...) { + char reason[1024], reason_real[1024]; + va_list va; + va_start(va, fmt); + vsnprintf(reason, 1024, fmt, va); + va_end(va); + snprintf(reason_real, 1024, "payload_dylib: %s", reason); + if (has_verbose_boot) { + printf("%s\n", reason_real); + printf("jbinit DIED!\n"); + sleep(60); + } + abort_with_payload(42, 0x69, NULL, 0, reason_real, 0); +} diff --git a/src/payload_dylib/pspawn.c b/src/payload_dylib/pspawn.c index 934e665..7d8b1a7 100644 --- a/src/payload_dylib/pspawn.c +++ b/src/payload_dylib/pspawn.c @@ -113,7 +113,7 @@ static int posix_spawn_hook(pid_t *restrict pid, const char *restrict path, return spawn_hook_common_p(pid, path, file_actions, attrp, argv, envp, posix_spawn_orig_wrapper); } -//#define ENABLE_CONSOLE_HOOK +#define ENABLE_CONSOLE_HOOK #ifdef ENABLE_CONSOLE_HOOK dev_t dev_console_d = 0; diff --git a/src/payload_dylib/xpc.c b/src/payload_dylib/xpc.c index 96abb9b..7e6cbc1 100644 --- a/src/payload_dylib/xpc.c +++ b/src/payload_dylib/xpc.c @@ -110,6 +110,9 @@ static void xpc_handler_hook(uint64_t a1, uint64_t a2, xpc_object_t xdict) { xpc_dictionary_set_int64(xreply, "error", ENOTDEVELOPMENT); #endif break; + case LAUNCHD_CMD_RUN_BOOTSCREEND: + bootscreend_main(); + break; default: { xpc_dictionary_set_int64(xreply, "error", EINVAL); break; @@ -174,8 +177,7 @@ void InitXPCHooks(void) { int launchd_image_index = 0; int ret = _NSGetExecutablePath(launchd_path, &bufsize); if (ret) { - fprintf(stderr, "_NSGetExecutablePath() failed\n"); - spin(); + _panic("_NSGetExecutablePath() failed\n"); } for (uint32_t i = 0; i < _dyld_image_count(); i++) { if(!strcmp(_dyld_get_image_name(i), launchd_path)) { @@ -206,8 +208,7 @@ void InitXPCHooks(void) { } if (!text_size) { - fprintf(stderr, "failed to find launchd __TEXT segment"); - spin(); + _panic("failed to find launchd __TEXT segment"); } uint32_t matches[] = { @@ -240,7 +241,6 @@ void InitXPCHooks(void) { if (xpc_handler) { MSHookFunction_p(xpc_handler, (void*)xpc_handler_hook, (void**)&xpc_handler_orig); } else { - fprintf(stderr, "patchfind launchd failed\n"); - spin(); + _panic("patchfind launchd failed\n"); } }