@@ -1229,6 +1229,48 @@ bool kpf_apfs_root_snapshot_name(struct xnu_pf_patch *patch, uint32_t *opcode_st
12291229 return true;
12301230}
12311231
1232+ bool found_apfs_root_hash_new = false;
1233+ bool kpf_apfs_root_hash_new (struct xnu_pf_patch * patch , uint32_t * opcode_stream ) {
1234+ uint32_t * b = find_prev_insn (opcode_stream , 3 , 0x14000000 , 0xfc000000 );
1235+
1236+ if (!b ) return false;
1237+
1238+ uint32_t * cbz = find_next_insn (opcode_stream , 10 , 0x34000000 , 0xff00001f ); // cbz w0, Lvalidated_root_hash
1239+
1240+ if (!cbz ) return false;
1241+
1242+ if ((cbz [-1 ] & 0xfc000000 ) != 0x94000000 ) return false; // bl
1243+
1244+ if (found_apfs_root_hash_new )
1245+ panic ("kpf_apfs_root_hash_new: found twice!" );
1246+
1247+ cbz [-1 ] = 0x52800000 ; // mov w0, #0
1248+
1249+ found_apfs_root_hash_new = true;
1250+
1251+ printf ("KPF: found apfs_root_hash_new\n" );
1252+ return true;
1253+ }
1254+
1255+ void * found_apfs_handle_fsioc_graft = NULL ;
1256+ bool kpf_apfs_handle_fsioc_graft_new (struct xnu_pf_patch * patch , uint32_t * opcode_stream ) {
1257+ uint32_t * cbz = find_prev_insn (opcode_stream , 20 , 0x34000000 , 0xff00001f ); // cbz w0, Lvalidated_payload_and_manifest
1258+
1259+ if (!cbz ) return false;
1260+
1261+ if ((cbz [-1 ] & 0xfc000000 ) != 0x94000000 ) return false; // bl
1262+
1263+ if (found_apfs_handle_fsioc_graft && found_apfs_handle_fsioc_graft != cbz )
1264+ panic ("kpf_apfs_handle_fsioc_graft_new: found twice!" );
1265+
1266+ cbz [-1 ] = 0x52800000 ; // mov w0, #0
1267+
1268+ found_apfs_handle_fsioc_graft = cbz ;
1269+
1270+ printf ("KPF: found apfs_handle_fsioc_graft_new\n" );
1271+ return true;
1272+ }
1273+
12321274#if 0
12331275bool handled_eval_rootauth = false;
12341276bool kpf_apfs_rootauth (struct xnu_pf_patch * patch , uint32_t * opcode_stream ) {
@@ -1280,7 +1322,7 @@ bool kpf_apfs_rootauth_new(struct xnu_pf_patch *patch, uint32_t *opcode_stream)
12801322}
12811323#endif
12821324
1283- void kpf_apfs_patches (xnu_pf_patchset_t * patchset , bool have_ssv , bool apfs_vfsop_mount_string_match ) {
1325+ void kpf_apfs_patches (xnu_pf_patchset_t * patchset , bool have_ssv , bool apfs_vfsop_mount_string_match , bool ipad6_ipados18 ) {
12841326 // there is a check in the apfs mount function that makes sure that the kernel task is calling this function (current_task() == kernel_task)
12851327 // we also want to call it so we patch that check out
12861328 // example from i7 13.3:
@@ -1435,6 +1477,46 @@ void kpf_apfs_patches(xnu_pf_patchset_t* patchset, bool have_ssv, bool apfs_vfso
14351477 xnu_pf_maskmatch (patchset ,
14361478 "apfs_root_snapshot_name" , root_snapshot_matches , root_snapshot_masks , sizeof (root_snapshot_matches ) / sizeof (uint64_t ), true ,(void * )kpf_apfs_root_snapshot_name );
14371479 }
1480+
1481+ if (ipad6_ipados18 ) {
1482+ // Patch root hash verification
1483+
1484+ uint64_t root_hash_new_matches [] = {
1485+ 0xd3430c02 // ubfx x2, xN, #3, #1
1486+ };
1487+
1488+ uint64_t root_hash_new_masks [] = {
1489+ 0xfffffc1f
1490+ };
1491+
1492+ xnu_pf_maskmatch (patchset ,
1493+ "apfs_graft_new" , root_hash_new_matches , root_hash_new_masks , sizeof (root_hash_new_matches ) / sizeof (uint64_t ), true ,(void * )kpf_apfs_root_hash_new );
1494+
1495+ // Patch root hash image4 verification
1496+
1497+ uint64_t handle_fsioc_graft_matches [] = {
1498+ 0xaa1003e0 , // mov x0, x{16-31}
1499+ 0xaa1003e1 , // mov x1, x{16-31}
1500+ 0xaa1003e3 , // mov x3, x{16-31}
1501+ 0xd2800004 , // mov x4, #0
1502+ 0xd2800005 , // mov x5, #0
1503+ 0xaa1003e6 , // mov x6, x{16-31}
1504+ 0x14000000 // b
1505+ };
1506+
1507+ uint64_t handle_fsioc_graft_masks [] = {
1508+ 0xfff0ffff ,
1509+ 0xfff0ffff ,
1510+ 0xfff0ffff ,
1511+ 0xffffffff ,
1512+ 0xffffffff ,
1513+ 0xfff0ffff ,
1514+ 0xfc000000
1515+ };
1516+
1517+ xnu_pf_maskmatch (patchset ,
1518+ "handle_fsioc_graft_new" , handle_fsioc_graft_matches , handle_fsioc_graft_masks , sizeof (handle_fsioc_graft_matches ) / sizeof (uint64_t ), false ,(void * )kpf_apfs_handle_fsioc_graft_new );
1519+ }
14381520}
14391521static uint32_t * amfi_ret ;
14401522bool kpf_amfi_execve_tail (struct xnu_pf_patch * patch , uint32_t * opcode_stream ) {
@@ -2371,6 +2453,19 @@ static void kpf_cmd(const char *cmd, char *args)
23712453#endif
23722454 }
23732455
2456+ const char root_hash_string [] = "%s:%d: %s Failed to authenticate root hash (volume type %d): %d\n" ;
2457+ const char * root_hash_string_match = apfs_text_cstring_range ? memmem (apfs_text_cstring_range -> cacheable_base , apfs_text_cstring_range -> size , root_hash_string , sizeof (root_hash_string )) : NULL ;
2458+ if (!root_hash_string_match ) root_hash_string_match = memmem (text_cstring_range -> cacheable_base , text_cstring_range -> size , root_hash_string , sizeof (root_hash_string ));
2459+
2460+ const char graft_image4_string [] = "%s:%d: %s Failed to validate image4 payload and manifest for grafting: %d\n" ;
2461+ const char * graft_image4_string_match = apfs_text_cstring_range ? memmem (apfs_text_cstring_range -> cacheable_base , apfs_text_cstring_range -> size , graft_image4_string , sizeof (graft_image4_string )) : NULL ;
2462+ if (!graft_image4_string_match ) graft_image4_string_match = memmem (text_cstring_range -> cacheable_base , text_cstring_range -> size , graft_image4_string , sizeof (graft_image4_string ));
2463+
2464+ if (gKernelVersion .darwinMajor < 24 || xnu_platform () != PLATFORM_IOS ) {
2465+ graft_image4_string_match = NULL ;
2466+ root_hash_string_match = NULL ;
2467+ }
2468+
23742469#ifdef DEV_BUILD
23752470 // 15.0 beta 1 onwards, but only iOS/iPadOS
23762471 if ((livefs_string_match != NULL ) != (
@@ -2417,6 +2512,51 @@ static void kpf_cmd(const char *cmd, char *args)
24172512 }
24182513#endif
24192514
2515+ bool ipad6_ipados18 = false;
2516+ #if !defined(KPF_TEST )
2517+ char * model = dt_prop (gDeviceTree , "model" , NULL );
2518+ if (gKernelVersion .darwinMajor >= 24 &&
2519+ (strcmp (model , "iPad7,5" ) == 0 || strcmp (model , "iPad7,6" ) == 0 )) {
2520+ ipad6_ipados18 = true;
2521+ }
2522+
2523+ if (ipad6_ipados18 ) {
2524+ puts ("Fixing up bootargs" );
2525+
2526+ dt_node_t * memory_map = dt_node (gDeviceTree , "/chosen/memory-map" );
2527+ struct memmap * map = dt_alloc_memmap (memory_map , "FunnyBootArgs" );
2528+ if (!map )
2529+ {
2530+ panic ("Failed to allocate FunnyBootArgs memory map" );
2531+ }
2532+
2533+ struct boot_args * cBootArgs = (struct boot_args * )((uint64_t )gBootArgs - 0x800000000 + kCacheableView );
2534+ struct boot_args * new_BootArgs = alloc_static (0x4000 );
2535+ bzero (new_BootArgs , sizeof (struct boot_args ));
2536+ new_BootArgs -> Revision = 3 ;
2537+ new_BootArgs -> Version = 2 ;
2538+ new_BootArgs -> virtBase = cBootArgs -> virtBase ;
2539+ new_BootArgs -> physBase = cBootArgs -> physBase ;
2540+ new_BootArgs -> memSize = cBootArgs -> memSize ;
2541+ new_BootArgs -> topOfKernelData = cBootArgs -> topOfKernelData ;
2542+ memcpy (& new_BootArgs -> Video , & cBootArgs -> Video , sizeof (struct Boot_Video ));
2543+ new_BootArgs -> machineType = cBootArgs -> machineType ;
2544+ new_BootArgs -> deviceTreeLength = cBootArgs -> deviceTreeLength ;
2545+ new_BootArgs -> deviceTreeP = cBootArgs -> deviceTreeP ;
2546+ memcpy (new_BootArgs -> iOS18 .CommandLine , cBootArgs -> iOS13 .CommandLine , BOOT_LINE_LENGTH_iOS13 );
2547+ new_BootArgs -> iOS18 .bootFlags = cBootArgs -> iOS13 .bootFlags ;
2548+ new_BootArgs -> iOS18 .memSizeActual = cBootArgs -> iOS13 .memSizeActual ;
2549+ gBootArgs = (void * )(((uint64_t )new_BootArgs ) + 0x800000000 - kCacheableView );
2550+ map -> addr = ((uint64_t )new_BootArgs ) + 0x800000000 - kCacheableView ;
2551+ map -> size = 0x4000 ;
2552+
2553+ * (uint32_t * )dt_prop (dt_find (gDeviceTree , "/chosen" ), "debug-enabled" , NULL ) = 1 ;
2554+ }
2555+ #else
2556+ if (gKernelVersion .darwinMajor >= 24 && xnu_platform () == PLATFORM_IOS )
2557+ ipad6_ipados18 = true;
2558+ #endif
2559+
24202560 for (size_t i = 0 ; i < sizeof (kpf_components )/sizeof (kpf_components [0 ]); ++ i )
24212561 {
24222562 kpf_component_t * component = kpf_components [i ];
@@ -2484,7 +2624,7 @@ static void kpf_cmd(const char *cmd, char *args)
24842624 }
24852625 }
24862626
2487- kpf_apfs_patches (apfs_patchset , livefs_string_match != NULL , apfs_vfsop_mount_string_match != NULL );
2627+ kpf_apfs_patches (apfs_patchset , livefs_string_match != NULL , apfs_vfsop_mount_string_match != NULL , ipad6_ipados18 );
24882628
24892629 if (!(palera1n_flags & palerain_option_rootful ) && !(palera1n_flags & palerain_option_rootless )) {
24902630 if (livefs_string_match ) {
0 commit comments