diff --git a/.gitignore b/.gitignore index ebf8995..908ae3d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,14 @@ *.dylib *.bin cmake-build-*/ -.DS_Store \ No newline at end of file +.DS_Store +.vscode +krnl +kernelcache +*.i64 +*.nam +*.id0 +*.id1 +*.til +panic.txt +IOKernelRW \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cd1858..033e14e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,22 @@ cmake_minimum_required(VERSION 3.27) +option(MACOS "Enable building for macOS" OFF) project(x8A4 C) set(CMAKE_C_STANDARD 17) string(COMPARE EQUAL "${CMAKE_OSX_ARCHITECTURES}" "" arch_not_set) if(NOT DEFINED CMAKE_OSX_ARCHITECTURES OR arch_not_set) - set(CMAKE_OSX_ARCHITECTURES arm64 arm64e) + set(CMAKE_OSX_ARCHITECTURES arm64) endif() set(CMAKE_OSX_DEPLOYMENT_TARGET "") +if(MACOS) + set(ENT mac_ent.plist) + set(BUILD_SDK macosx) +else() + set(ENT tfp0.plist) + set(BUILD_SDK iphoneos) +endif() + find_program(LDID ldid2) if(NOT LDID) find_program(LDID ldid) @@ -18,7 +27,7 @@ endif() find_program(XCRUN xcrun) if(XCRUN) -execute_process(COMMAND ${XCRUN} --sdk iphoneos --show-sdk-path +execute_process(COMMAND ${XCRUN} --sdk ${BUILD_SDK} --show-sdk-path OUTPUT_VARIABLE CMAKE_OSX_SYSROOT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -63,14 +72,16 @@ target_include_directories(x8A4 PRIVATE set(RPATH "/var/jb/usr/lib") set(RPATH2 "/usr/lib") +set(RPATH3 "/opt/procursus/lib") +set(RPATH4 "/usr/local/lib") set_target_properties(x8A4 PROPERTIES # LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2} -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin/ -lclang_rt.asan_abi_ios -lclang_rt.asan_ios_dynamic") - LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2} ") + LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2} -Wl,-rpath,${RPATH3} -Wl,-rpath,${RPATH4} ") set_target_properties(x8A4 PROPERTIES # COMPILE_FLAGS "-Wall -Werror -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") - COMPILE_FLAGS "-Wall -Werror") + COMPILE_FLAGS "-Wall -Werror -Wno-deprecated-declarations") set(SOVERSION 1) set_target_properties(x8A4 PROPERTIES SOVERSION ${SOVERSION}) @@ -102,10 +113,12 @@ target_include_directories(x8A4_CLI PRIVATE "${CMAKE_SOURCE_DIR}/Include") set(RPATH "/var/jb/usr/lib") set(RPATH2 "/usr/lib") +set(RPATH3 "/opt/procursus/lib") +set(RPATH4 "/usr/local/lib") set_target_properties(x8A4_CLI PROPERTIES # LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2} -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin -lclang_rt.asan_abi_ios -lclang_rt.asan_ios_dynamic") - LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2}") + LINK_FLAGS "-Wl,-rpath,${RPATH} -Wl,-rpath,${RPATH2} -Wl,-rpath,${RPATH3} -Wl,-rpath,${RPATH4} ") set_target_properties(x8A4_CLI PROPERTIES # COMPILE_FLAGS "-Wall -Werror -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") @@ -125,7 +138,7 @@ add_custom_command(TARGET x8A4 POST_BUILD ) add_custom_command(TARGET x8A4_CLI POST_BUILD - COMMAND ${LDID} -Stfp0.plist -Hsha256 -Cadhoc ${CMAKE_CURRENT_BINARY_DIR}/x8A4_CLI + COMMAND ${LDID} -S${ENT} -Hsha256 -Cadhoc ${CMAKE_CURRENT_BINARY_DIR}/x8A4_CLI WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMENT "Signing x8A4_CLI" ) diff --git a/Include/x8A4/Kernel/offsets.h b/Include/x8A4/Kernel/offsets.h index fa28be6..c4cce63 100644 --- a/Include/x8A4/Kernel/offsets.h +++ b/Include/x8A4/Kernel/offsets.h @@ -27,6 +27,7 @@ enum apple_mobile_apnonce_external_selectors { /* Structure Variables */ struct kernel_offsets { + uint64_t macos; uint64_t proc_pid; uint64_t proc_task; uint64_t proc_list_next; diff --git a/Kernel/kernel.c b/Kernel/kernel.c index dffbe44..82b70a0 100644 --- a/Kernel/kernel.c +++ b/Kernel/kernel.c @@ -79,6 +79,94 @@ int xpf_init(void) { // int xpf_init(void) { return // xpf_start_with_kernel_path(get_kernel_path_legacy()); } +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Function to get mount point for a BSD device name +char* getMountPoint(const char* bsdName) { + if (!bsdName) return NULL; + + // Use getmntinfo to get all mounted filesystems + struct statfs *mounts; + int numMounts = getmntinfo(&mounts, MNT_NOWAIT); + + if (numMounts == 0) return NULL; + + char devicePath[256]; + snprintf(devicePath, sizeof(devicePath), "/dev/%s", bsdName); + + for (int i = 0; i < numMounts; i++) { + if (strcmp(mounts[i].f_mntfromname, devicePath) == 0) { + // Found the mount, return a copy of the mount point + return strdup(mounts[i].f_mntonname); + } + } + + return NULL; +} +char* getStringProperty(io_object_t obj, CFStringRef key) { + CFTypeRef prop = IORegistryEntryCreateCFProperty(obj, key, kCFAllocatorDefault, 0); + if (!prop) return NULL; + + char* result = NULL; + if (CFGetTypeID(prop) == CFStringGetTypeID()) { + CFIndex length = CFStringGetLength((CFStringRef)prop); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1; + result = malloc(maxSize); + if (result) { + CFStringGetCString((CFStringRef)prop, result, maxSize, kCFStringEncodingUTF8); + } + } + + CFRelease(prop); + return result; +} + +const char *get_boot_uuid(void) { + io_iterator_t iterator; + io_object_t obj; + + CFMutableDictionaryRef volumeMatching = IOServiceMatching("AppleAPFSVolume"); + if (!volumeMatching) { + printf("Failed to create volume matching dictionary\n"); + return NULL; + } + + kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, volumeMatching, &iterator); + if (kr != KERN_SUCCESS) { + printf("Failed to get APFS volumes: %d\n", kr); + return NULL; + } + char* volumeUUID = NULL; + while ((obj = IOIteratorNext(iterator)) != 0) { + char* volumeName = getStringProperty(obj, CFSTR("BSD Name")); + volumeUUID = getStringProperty(obj, CFSTR("UUID")); + + char* mountPoint = getMountPoint(volumeName); + if(mountPoint && strncmp(mountPoint, "/System/Volumes/Data", strlen(mountPoint)) == 0) { + if (volumeName) free(volumeName); + if (mountPoint) free(mountPoint); + break; + } + + if (volumeName) free(volumeName); + if (volumeUUID) free(volumeUUID); + if (mountPoint) free(mountPoint); + + IOObjectRelease(obj); + } + + IOObjectRelease(iterator); + return volumeUUID; +} + /** * @brief Get the path to the filesystem kernel inside preboot * @return Kernel path @@ -87,7 +175,7 @@ const char *get_kernel_path(void) { if (kernel_path_cached) { return kernel_path_cached; } - const char *preboot_path = "/private/preboot/"; + const char *preboot_path = "/System/Volumes/Preboot/"; if (access(preboot_path, F_OK) != 0) { x8A4_log_error("Can't proceed with kernel init, %s not found!\n", preboot_path); return NULL; @@ -118,11 +206,12 @@ const char *get_kernel_path(void) { j+=2; } boot_manifest_hash_str[end] = '\0'; + const char *uuid = get_boot_uuid(); - const char *format = "/private/preboot/%s/System/Library/Caches/" + const char *format = "/System/Volumes/Preboot/%s/boot/%s/System/Library/Caches/" "com.apple.kernelcaches/kernelcache"; - char *kernel_path = (char *)calloc(1, 256); - snprintf(kernel_path, 256, format, boot_manifest_hash_str); + char *kernel_path = (char *)calloc(1, 1024); + snprintf(kernel_path, 1024, format, uuid ? uuid : "", boot_manifest_hash_str); kernel_path_cached = kernel_path; return (const char *)kernel_path; } @@ -354,6 +443,7 @@ uint64_t get_ipc_port(mach_port_name_t port_name) { table + (MACH_PORT_INDEX(port_name) * koffsets_cached->ipc_entry_size) + koffsets_cached->ipc_entry_object, &port, 8); + unsign_ptr(&port); if (ret || !port) { x8A4_log_error("Failed to read port from kernel ipc_entry object! (%d:0x%016llX)\\n", ret, port); return 0; diff --git a/Kernel/offsets.c b/Kernel/offsets.c index 2c6d7d2..266a22f 100644 --- a/Kernel/offsets.c +++ b/Kernel/offsets.c @@ -61,6 +61,13 @@ int offsets_init(void) { x8A4_log_error("Failed calloc kernel_offsets, impossible!\n", ""); return -1; } + koffsets_cached->macos = 0; + const char *DTPlatformName = strstr(gXPF.kernelInfoPlist, "DTPlatformName"); + char osName[100]; + sscanf(DTPlatformName, "DTPlatformName\t%9[^<]", osName); + if(strcmp(osName, "macosx") == 0) { + koffsets_cached->macos = 1; + } koffsets_cached->proc_pid = 0x10; koffsets_cached->proc_task = 0x18; koffsets_cached->proc_list_next = 0x0; @@ -97,10 +104,18 @@ int offsets_init(void) { koffsets_cached->io_dt_nvram = 0xB8; } if (ios_1430b) { - koffsets_cached->io_dt_nvram = 0xC0; + if(koffsets_cached->macos) { + koffsets_cached->io_dt_nvram = 0xE0; + } else { + koffsets_cached->io_dt_nvram = 0xC0; + } } if (ios_1430b_) { - koffsets_cached->io_dt_nvram = 0xC8; + if(koffsets_cached->macos) { + koffsets_cached->io_dt_nvram = 0xE8; + } else { + koffsets_cached->io_dt_nvram = 0xC8; + } } if (ios_1500) { koffsets_cached->proc_pid = 0x68; @@ -110,12 +125,20 @@ int offsets_init(void) { } if (ios_1540) { koffsets_cached->ipc_port_kobject = 0x48; - koffsets_cached->io_dt_nvram = 0xB8; + if(koffsets_cached->macos) { + koffsets_cached->io_dt_nvram = 0xC0; + } else { + koffsets_cached->io_dt_nvram = 0xB8; + } } if (ios_1600) { koffsets_cached->proc_pid = 0x60; koffsets_cached->smr = 0x3; - koffsets_cached->io_dt_nvram = 0xC0; + if(koffsets_cached->macos) { + koffsets_cached->io_dt_nvram = 0xC8; + } else { + koffsets_cached->io_dt_nvram = 0xC0; + } } if (ios_1610) { koffsets_cached->table_smr = 0x1; diff --git a/Lib/libchoma.a b/Lib/libchoma.a index f032ba9..d0c4780 100644 Binary files a/Lib/libchoma.a and b/Lib/libchoma.a differ diff --git a/Lib/libkrw.tbd b/Lib/libkrw.tbd index 302129d..04abc37 100644 --- a/Lib/libkrw.tbd +++ b/Lib/libkrw.tbd @@ -1,6 +1,6 @@ --- !tapi-tbd-v2 archs: [ arm64, arm64e ] -platform: ios +platform: ios, macos flags: [ not_app_extension_safe ] install-name: '@rpath/libkrw.0.dylib' current-version: 1.1.2 diff --git a/Lib/libxpf.a b/Lib/libxpf.a deleted file mode 100644 index dd02f70..0000000 Binary files a/Lib/libxpf.a and /dev/null differ diff --git a/Plugins/IOKernelRW/Makefile b/Plugins/IOKernelRW/Makefile new file mode 100644 index 0000000..3e4b0f3 --- /dev/null +++ b/Plugins/IOKernelRW/Makefile @@ -0,0 +1,15 @@ +CC=clang +CFLAGS=-fPIC -shared -isysroot $(shell xcrun --sdk macosx --show-sdk-path) +IPATH=-I../../Include -I/usr/local/include + +iokernelrw_krw_plugin.dylib: iokernelrw_krw_plugin.c + $(CC) $(CFLAGS) $(IPATH) $^ -o $@ -framework IOKit -Wl,-bundle + +.PHONY: install clean + +install: iokernelrw_krw_plugin.dylib + sudo mkdir -p /opt/libkrw/ + sudo cp iokernelrw_krw_plugin.dylib /opt/libkrw/ + +clean: + rm -f iokernelrw_krw_plugin.dylib \ No newline at end of file diff --git a/Plugins/IOKernelRW/iokernelrw_krw_plugin.c b/Plugins/IOKernelRW/iokernelrw_krw_plugin.c new file mode 100644 index 0000000..77f9953 --- /dev/null +++ b/Plugins/IOKernelRW/iokernelrw_krw_plugin.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "libkrw_plugin.h" + +io_connect_t krw_client = IO_OBJECT_NULL; + +int kbase_wrapper(uint64_t *to) { + kern_return_t result_read; + int result; + + if (krw_client == IO_OBJECT_NULL) + { + krw_client = iokernelrw_open(); + } + + result_read = iokernelrw_kbase(krw_client, to); + + if (result_read == KERN_SUCCESS) + { + result = 0; + } + else + { + result = EDEVERR; + } + + return result; +} + +int kread_wrapper(uint64_t from, void* to, size_t len) +{ + kern_return_t result_read; + int result; + + if (krw_client == IO_OBJECT_NULL) + { + krw_client = iokernelrw_open(); + } + + result_read = iokernelrw_read(krw_client, from, to, len); + + if (result_read == KERN_SUCCESS) + { + result = 0; + } + else + { + result = EDEVERR; + } + + return result; +} + +int kwrite_wrapper(void* from, uint64_t to, size_t len) +{ + kern_return_t result_write; + int result; + + if (krw_client == IO_OBJECT_NULL) + { + krw_client = iokernelrw_open(); + } + + result_write = iokernelrw_write(krw_client, from, to, len); + + if (result_write == KERN_SUCCESS) + { + result = 0; + } + else + { + result = EDEVERR; + } + + return result; +} + +int krw_initializer(krw_handlers_t handlers) +{ + iokernelrw_open(); + + //handlers->version = TODO; + handlers->kbase = kbase_wrapper; + handlers->kread = kread_wrapper; + handlers->kwrite = kwrite_wrapper; + //handlers->kmalloc = TODO; + //handlers->kdealloc = TODO; + //handlers->kcall = TODO; + //handlers->physread = TODO; + //handlers->physwrite = TODO; + + return 0; +} \ No newline at end of file diff --git a/mac_ent.plist b/mac_ent.plist new file mode 100644 index 0000000..f9498f2 --- /dev/null +++ b/mac_ent.plist @@ -0,0 +1,8 @@ + + + + + com.apple.security.siguza.kernel-rw + + + diff --git a/x8A4.c b/x8A4.c index ff9008b..7866df6 100644 --- a/x8A4.c +++ b/x8A4.c @@ -1635,4 +1635,4 @@ void x8A4_cli_set_cryptex_seed(const char *new_seed) { } x8A4_log("Done!\n", ""); x8A4_log("Successfully set cryptex seed(%s)!\n", new_seed); -} +} \ No newline at end of file