Skip to content

Commit

Permalink
CFRunLoopServiceMachPort_hooks: Improve disable_mach_msg_errors to …
Browse files Browse the repository at this point in the history
…generic solution
  • Loading branch information
netanelc305 committed Jul 5, 2023
1 parent 7bbb53c commit d588f56
Showing 1 changed file with 35 additions and 36 deletions.
71 changes: 35 additions & 36 deletions hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,44 @@
import lldb

from hilda.exceptions import SymbolAbsentError


def _CFRunLoopServiceMachPort_hook(hilda, *args):
"""
:param hilda.hilda_client.HildaClient hilda:
def disable_mach_msg_errors() -> None:
"""
hilda.jump(hilda.CFRunLoopServiceMachPort_while_ea)
hilda.cont()
Remove the timeout validation from __CFRunLoopServiceMachPort. This is done by patching the mach_msg_timeout_t
parameter (4rd one) to MACH_MSG_TIMEOUT_NONE. On arm the parameter passes on `x3` register.
__int64 __fastcall __CFRunLoopServiceMachPort(
mach_port_name_t a1,
mach_msg_header_t **a2,
mach_port_t *a3,
mach_msg_timeout_t a4,
voucher_mach_msg_state_t *a5,
id *a6)
def disable_mach_msg_errors() -> None:
"""
Disable the error check inside the CFRunLoopServiceMachPort from the mach_msg syscall.
This is used to debug slow handling of mach messages.
CoreFoundation:__text:0000000186E5012C ___CFRunLoopServiceMachPort
CoreFoundation:__text:0000000186E5012C SUB SP, SP, #0x70
CoreFoundation:__text:0000000186E50130 STP X28, X27, [SP,#0x60+var_50]
CoreFoundation:__text:0000000186E50134 STP X26, X25, [SP,#0x60+var_40]
CoreFoundation:__text:0000000186E50138 STP X24, X23, [SP,#0x60+var_30]
CoreFoundation:__text:0000000186E5013C STP X22, X21, [SP,#0x60+var_20]
CoreFoundation:__text:0000000186E50140 STP X20, X19, [SP,#0x60+var_10]
CoreFoundation:__text:0000000186E50144 STP X29, X30, [SP,#0x60+var_s0]
CoreFoundation:__text:0000000186E50148 ADD X29, SP, #0x60
CoreFoundation:__text:0000000186E5014C MOV X21, X5
CoreFoundation:__text:0000000186E50150 MOV X22, X4
CoreFoundation:__text:0000000186E50154 MOV X23, X3 <-------- Timeout parameter
"""
hilda = lldb.hilda_client
with hilda.stopped():
instructions = hilda.symbols.__CFRunLoopServiceMachPort.disass(2000, should_print=False)
while_ea = None
for instruction in instructions:
if (while_ea is None) and instruction.DoesBranch():
# Beginning of the `while(true) { ... }`
while_ea = instruction.GetOperands(hilda.target)
hilda.CFRunLoopServiceMachPort_while_ea = int(hilda.file_symbol(eval(while_ea)))
elif instruction.GetMnemonic(hilda.target) in ('brk', 'ud2'):
symbol = hilda.symbol(instruction.addr.GetLoadAddress(hilda.target))
symbol.bp(
_CFRunLoopServiceMachPort_hook,
forced=True,
name=f'__CFRunLoopServiceMachPort-brk-{int(symbol - hilda.symbols.__CFRunLoopServiceMachPort)}'
)
if hilda.arch == 'x86_64h':
return

# on iOS 16.x, will need to also patch this one
try:
handle_error = hilda.symbols['__CFRunLoopServiceMachPort.cold.1']
except SymbolAbsentError:
return

for instruction in handle_error.disass(2000, should_print=False):
if instruction.GetMnemonic(hilda.target) in ('brk', 'ud2'):
# mov x0, x0
hilda.symbol(instruction.addr.GetLoadAddress(hilda.target)).poke(b'\xe0\x03\x00\xaa')
with hilda.stopped():
for inst in hilda.symbols.__CFRunLoopServiceMachPort.disass(200, should_print=False):
mnemonic = inst.GetMnemonic(hilda.target)
operands = inst.GetOperands(hilda.target)
if mnemonic != 'mov' or not operands.endswith('x3'):
continue
addr = inst.GetAddress()
file_addr = addr.GetFileAddress()
new_inst = f'{mnemonic} {operands.replace("x3", "0")}'
hilda.file_symbol(file_addr).poke_text(new_inst)
break

0 comments on commit d588f56

Please sign in to comment.