mirror of
https://github.com/Lakr233/vphone-cli.git
synced 2026-04-05 13:09:06 +08:00
Included commits: - f8a54b8 Update JB kernel patch research notes Refresh and revalidate jailbreak kernel-patcher documentation and runtime-verification notes. Key updates: re-analyzed B13 (patch_bsd_init_auth) and retargeted recommended site to the FSIOC_KERNEL_ROOTAUTH return check in bsd_init rather than the old ldr/cbz/bl heuristic; clarified preferred NOP-of-CBNZ vs forcing ioctl return. Reworked C21 (patch_cred_label_update_execve) to preserve AMFI exec-time flow and instead clear restrictive csflags in a success-tail trampoline; disabled in default schedule until boot validation. Documented that C23 (patch_hook_cred_label_update_execve) was mis-targeting the wrapper (sub_FFFFFE00093D2CE4) instead of the real hook body (_hook_cred_label_update_execve), explaining boot failures and recommending retargeting. Noted syscallmask and vm_fault matcher problems (patch_syscallmask_apply_to_proc historical hit targeted _profile_syscallmask_destroy; patch_vm_fault_enter_prepare matcher resolves to pmap_lock_phys_page path), and updated the runtime-verification summary with follow-up findings and which methods are temporarily commented out/disabled in the default KernelJBPatcher schedule pending staged re-validation. - 6ebac65 fix: patch_bsd_init_auth - 5b224d3 fix: patch_io_secure_bsd_root - e6806bf docs: update patch notes - 0d89c5c Retarget vm_fault_enter_prepare jailbreak patch - 6b9d79b Rework C21 late-exit cred_label patch - ece8cc0 Clean C21 mov matcher encodings - ad2ea7c enabled fixed patch_cred_label_update_execve - c37b6b1 Rebuild syscallmask C22 patch - 363dd7a Rebuild JB C23 as faithful upstream trampoline - 129e648 Disable IOUC MACF; rebuild kcall10 & C22 docs Re-evaluate and rework several JB kernel patches and docs: mark patch_iouc_failed_macf as reverted/disabled (repo-local, over-broad early-return) and replace its patcher with a no-op implementation to emit zero writes by default; update research notes to explain the reanalysis and rationale. Rebuild patch_kcall10: replace the historical 10-arg design with an ABI-correct syscall-439 cave (target + 7 args -> uint64 return), add a new cave builder and munge32 reuse logic in the kcall10 patcher, and enable the method in KernelJBPatcher group. Clarify syscallmask (C22) semantics in docs: upstream C22 is an all-ones-mask retarget (not a NULL install) and keep the rebuilt all-ones wrapper as the authoritative baseline. Misc: minor refactors and helper additions (chained-pointer helpers, cave size/constants, validation and dry-run safeguards) to improve correctness and alignment with IDA/runtime verification. - e1b2365 Rebuild kcall10 as ABI-correct syscall cave - 23090d0 fix patch_iouc_failed_macf - 0056be2 Normalize formatting in research docs Apply whitespace and formatting cleanup across research markdown files for consistency and readability. Adjust table alignment and spacing in 00_patch_comparison_all_variants.md, normalize list/indentation spacing in patch_bsd_init_auth.md and patch_syscallmask_apply_to_proc.md, and add/clean blank lines and minor spacing in patch_kcall10.md. These are non-functional documentation changes only.
107 lines
4.1 KiB
Python
107 lines
4.1 KiB
Python
"""Mixin: KernelJBPatchIoucmacfMixin."""
|
|
|
|
|
|
class KernelJBPatchIoucmacfMixin:
|
|
def patch_iouc_failed_macf(self):
|
|
"""Bypass the narrow IOUC MACF deny branch after mac_iokit_check_open.
|
|
|
|
Upstream-equivalent design goal:
|
|
- keep the large IOUserClient open/setup path intact
|
|
- keep entitlement/default-locking/sandbox-resolver flow intact
|
|
- only force the post-MACF gate onto the allow path
|
|
|
|
Local validated shape in `sub_FFFFFE000825B0C0`:
|
|
- `BL <macf_aggregator>`
|
|
- `CBZ W0, <allow>`
|
|
- later `ADRL X0, "IOUC %s failed MACF in process %s\n"`
|
|
|
|
Patch action:
|
|
- replace that `CBZ W0, <allow>` with unconditional `B <allow>`
|
|
"""
|
|
self._log("\n[JB] IOUC MACF gate: branch-level deny bypass")
|
|
|
|
fail_macf_str = self.find_string(b"IOUC %s failed MACF in process %s")
|
|
if fail_macf_str < 0:
|
|
self._log(" [-] IOUC failed-MACF format string not found")
|
|
return False
|
|
|
|
refs = self.find_string_refs(fail_macf_str, *self.kern_text)
|
|
if not refs:
|
|
self._log(" [-] no xrefs for IOUC failed-MACF format string")
|
|
return False
|
|
|
|
def _has_macf_aggregator_shape(callee_off):
|
|
callee_end = self._find_func_end(callee_off, 0x400)
|
|
saw_slot_load = False
|
|
saw_indirect_call = False
|
|
for off in range(callee_off, callee_end, 4):
|
|
d = self._disas_at(off)
|
|
if not d:
|
|
continue
|
|
ins = d[0]
|
|
op = ins.op_str.replace(" ", "").lower()
|
|
if ins.mnemonic == "ldr" and ",#0x9e8]" in op and op.startswith("x10,[x10"):
|
|
saw_slot_load = True
|
|
if ins.mnemonic in ("blraa", "blrab", "blr") and op.startswith("x10"):
|
|
saw_indirect_call = True
|
|
if saw_slot_load and saw_indirect_call:
|
|
return True
|
|
return False
|
|
|
|
for adrp_off, _, _ in refs:
|
|
func_start = self.find_function_start(adrp_off)
|
|
if func_start < 0:
|
|
continue
|
|
func_end = self._find_func_end(func_start, 0x2000)
|
|
|
|
for off in range(max(func_start, adrp_off - 0x120), min(func_end, adrp_off + 4), 4):
|
|
d0 = self._disas_at(off)
|
|
d1 = self._disas_at(off + 4)
|
|
if not d0 or not d1:
|
|
continue
|
|
i0 = d0[0]
|
|
i1 = d1[0]
|
|
if i0.mnemonic != "bl" or i1.mnemonic != "cbz":
|
|
continue
|
|
if not i1.op_str.replace(" ", "").startswith("w0,"):
|
|
continue
|
|
|
|
bl_target = self._is_bl(off)
|
|
if bl_target < 0 or not _has_macf_aggregator_shape(bl_target):
|
|
continue
|
|
|
|
if len(i1.operands) < 2:
|
|
continue
|
|
allow_target = getattr(i1.operands[-1], 'imm', -1)
|
|
if not (off < allow_target < func_end):
|
|
continue
|
|
|
|
fail_log_adrp = None
|
|
for probe in range(off + 8, min(func_end, off + 0x80), 4):
|
|
d = self._disas_at(probe)
|
|
if not d:
|
|
continue
|
|
ins = d[0]
|
|
if ins.mnemonic == "adrp" and probe == adrp_off:
|
|
fail_log_adrp = probe
|
|
break
|
|
if fail_log_adrp is None:
|
|
continue
|
|
|
|
patch_bytes = self._encode_b(off + 4, allow_target)
|
|
if not patch_bytes:
|
|
continue
|
|
|
|
self._log(
|
|
f" [+] IOUC MACF gate fn=0x{func_start:X}, bl=0x{off:X}, cbz=0x{off + 4:X}, allow=0x{allow_target:X}"
|
|
)
|
|
self.emit(
|
|
off + 4,
|
|
patch_bytes,
|
|
f"b #0x{allow_target - (off + 4):X} [IOUC MACF deny → allow]",
|
|
)
|
|
return True
|
|
|
|
self._log(" [-] narrow IOUC MACF deny branch not found")
|
|
return False
|