diff --git a/BaseBin/launchdhook/src/update.m b/BaseBin/launchdhook/src/update.m index 68f1e5bf8..6c3a35b1c 100644 --- a/BaseBin/launchdhook/src/update.m +++ b/BaseBin/launchdhook/src/update.m @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -195,5 +196,10 @@ void jbupdate_finalize_stage2(const char *prevVersion, const char *newVersion) // Default value for this pref is true // Set it during jbupdate if prev version is <2.1 and new version is >=2.1 gSystemInfo.jailbreakSettings.markAppsAsDebugged = true; + +#ifndef __arm64e__ + // Initilaize kcall only after we have the offsets required for it + arm64_kcall_init(); +#endif } } \ No newline at end of file diff --git a/BaseBin/libjailbreak/src/kcall_arm64.c b/BaseBin/libjailbreak/src/kcall_arm64.c index 1bbb0a83f..234b35c25 100644 --- a/BaseBin/libjailbreak/src/kcall_arm64.c +++ b/BaseBin/libjailbreak/src/kcall_arm64.c @@ -111,21 +111,27 @@ uint64_t arm64_kcall(uint64_t func, int argc, const uint64_t *argv) int arm64_kcall_init(void) { if (!gPrimitives.kalloc_local) return -1; - - pthread_mutex_init(&gArm64KcallThead.lock, NULL); - - // Kcall thread - // The thread that we make execute in kernelspace by ovewriting it's cpsr in kernel memory - thread_create(mach_task_self_, &gArm64KcallThead.thread); - uint64_t threadKptr = task_get_ipc_port_kobject(task_self(), gArm64KcallThead.thread); - gArm64KcallThead.actContext = kread_ptr(threadKptr + koffsetof(thread, machine_contextData)); - - // In order to do kcalls, we need to make a kernel allocation that is used as the stack - kalloc_with_options(&gArm64KcallThead.kernelStack, 0x10000, KALLOC_OPTION_LOCAL); - gArm64KcallThead.kernelStack += 0x8000; - - // Aligned state, we write to this allocation and then we can get the kernel pointer from it to pass to exception_return - posix_memalign((void **)&gArm64KcallThead.alignedState, vm_real_kernel_page_size, vm_real_kernel_page_size); + + // When doing an OTA update from 2.0.x to >=2.1, we will not have offsets for kcall yet so we can't initialize it + if (!koffsetof(thread, machine_contextData)) return -1; + + static dispatch_once_t ot; + dispatch_once(&ot, ^{ + pthread_mutex_init(&gArm64KcallThead.lock, NULL); + + // Kcall thread + // The thread that we make execute in kernelspace by ovewriting it's cpsr in kernel memory + thread_create(mach_task_self_, &gArm64KcallThead.thread); + uint64_t threadKptr = task_get_ipc_port_kobject(task_self(), gArm64KcallThead.thread); + gArm64KcallThead.actContext = kread_ptr(threadKptr + koffsetof(thread, machine_contextData)); + + // In order to do kcalls, we need to make a kernel allocation that is used as the stack + kalloc_with_options(&gArm64KcallThead.kernelStack, 0x10000, KALLOC_OPTION_LOCAL); + gArm64KcallThead.kernelStack += 0x8000; + + // Aligned state, we write to this allocation and then we can get the kernel pointer from it to pass to exception_return + posix_memalign((void **)&gArm64KcallThead.alignedState, vm_real_kernel_page_size, vm_real_kernel_page_size); + }); gPrimitives.kcall = arm64_kcall; gPrimitives.kexec = arm64_kexec;