Skip to content

Commit

Permalink
Improve arm64 kcall jbupdate logic
Browse files Browse the repository at this point in the history
  • Loading branch information
opa334 committed Apr 30, 2024
1 parent 9cfe9ce commit 56f0342
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
6 changes: 6 additions & 0 deletions BaseBin/launchdhook/src/update.m
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <libjailbreak/util.h>
#include <libjailbreak/trustcache.h>
#include <libjailbreak/kcall_arm64.h>
#include <xpc/xpc.h>
#include <dlfcn.h>

Expand Down Expand Up @@ -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
}
}
36 changes: 21 additions & 15 deletions BaseBin/libjailbreak/src/kcall_arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 56f0342

Please sign in to comment.