hilda 0.1.2__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
hilda/hilda_client.py CHANGED
@@ -9,19 +9,21 @@ import os
9
9
  import pickle
10
10
  import textwrap
11
11
  import time
12
+ import typing
12
13
  from collections import namedtuple
13
14
  from contextlib import contextmanager, suppress
14
15
  from datetime import datetime, timezone
15
- from functools import partial
16
+ from functools import cached_property, partial
16
17
  from pathlib import Path
17
- from typing import Union
18
+ from typing import List, Optional, Union
18
19
 
19
- import IPython
20
20
  import docstring_parser
21
21
  import hexdump
22
+ import IPython
22
23
  import lldb
23
24
  from humanfriendly import prompts
24
25
  from humanfriendly.terminal.html import html_to_ansi
26
+ from keystone import KS_ARCH_ARM64, KS_ARCH_X86, KS_MODE_64, KS_MODE_LITTLE_ENDIAN, Ks
25
27
  from pygments import highlight
26
28
  from pygments.formatters import TerminalTrueColorFormatter
27
29
  from pygments.lexers import XmlLexer
@@ -29,14 +31,17 @@ from tqdm import tqdm
29
31
  from traitlets.config import Config
30
32
 
31
33
  from hilda import objective_c_class
32
- from hilda.command import command, CommandsMeta
33
- from hilda.exceptions import *
34
+ from hilda.command import CommandsMeta, command
35
+ from hilda.exceptions import AccessingMemoryError, AccessingRegisterError, AddingLldbSymbolError, \
36
+ BrokenLocalSymbolsJarError, ConvertingFromNSObjectError, ConvertingToNsObjectError, CreatingObjectiveCSymbolError, \
37
+ DisableJetsamMemoryChecksError, EvaluatingExpressionError, HildaException, SymbolAbsentError
38
+ from hilda.launch_lldb import disable_logs # noqa: F401
34
39
  from hilda.objective_c_symbol import ObjectiveCSymbol
35
40
  from hilda.registers import Registers
36
41
  from hilda.snippets.mach import CFRunLoopServiceMachPort_hooks
37
42
  from hilda.symbol import Symbol
38
43
  from hilda.symbols_jar import SymbolsJar
39
- from hilda.launch_lldb import disable_logs
44
+ from hilda.ui.ui_manager import UiManager
40
45
 
41
46
  IsaMagic = namedtuple('IsaMagic', 'mask value')
42
47
  ISA_MAGICS = [
@@ -77,7 +82,8 @@ class HildaClient(metaclass=CommandsMeta):
77
82
  self.breakpoints = {}
78
83
  self.captured_objects = {}
79
84
  self.registers = Registers(self)
80
-
85
+ self.arch = self.target.GetTriple().split('-')[0]
86
+ self.ui_manager = UiManager(self)
81
87
  # should unwind the stack on errors. change this to False in order to debug self-made calls
82
88
  # within hilda
83
89
  self._evaluation_unwind_on_error = True
@@ -117,16 +123,22 @@ class HildaClient(metaclass=CommandsMeta):
117
123
  return {int(k): v for k, v in result.items()}
118
124
 
119
125
  @command()
120
- def bt(self):
126
+ def bt(self, should_print=True, depth: Optional[int] = None) -> List:
121
127
  """ Print an improved backtrace. """
128
+ backtrace = []
122
129
  for i, frame in enumerate(self.thread.frames):
130
+ if i == depth:
131
+ break
123
132
  row = ''
124
133
  row += html_to_ansi(f'<span style="color: cyan">0x{frame.addr.GetFileAddress():x}</span> ')
125
134
  row += str(frame)
126
135
  if i == 0:
127
136
  # first line
128
137
  row += ' 👈'
129
- print(row)
138
+ backtrace.append([f'0x{frame.addr.file_addr:016x}', frame])
139
+ if should_print:
140
+ print(row)
141
+ return backtrace
130
142
 
131
143
  @command()
132
144
  def disable_jetsam_memory_checks(self):
@@ -238,6 +250,16 @@ class HildaClient(metaclass=CommandsMeta):
238
250
 
239
251
  return retval
240
252
 
253
+ @command()
254
+ def poke_text(self, address: int, code: str) -> int:
255
+ """
256
+ Write instructions to address.
257
+ :param address:
258
+ :param code:
259
+ """
260
+ bytecode, count = self._ks.asm(code, as_bytes=True)
261
+ return self.poke(address, bytecode)
262
+
241
263
  @command()
242
264
  def peek(self, address, size: int) -> bytes:
243
265
  """
@@ -258,28 +280,13 @@ class HildaClient(metaclass=CommandsMeta):
258
280
  return retval
259
281
 
260
282
  @command()
261
- def peek_str(self, address, encoding=None):
283
+ def peek_str(self, address: Symbol) -> str:
262
284
  """
263
285
  Peek a buffer till null termination
264
286
  :param address:
265
- :param encoding: character encoding. if None, bytes is returned
266
287
  :return:
267
288
  """
268
- if hasattr(self.symbols, 'strlen'):
269
- # always prefer using native strlen
270
- buf = self.peek(address, self.symbols.strlen(address))
271
- else:
272
- buf = self.peek(address, 1)
273
- while buf[-1] != 0:
274
- buf += self.peek(address + len(buf), 1)
275
-
276
- # remove null terminator
277
- buf = buf[:-1]
278
-
279
- if encoding is not None:
280
- buf = str(buf, encoding)
281
-
282
- return buf
289
+ return address.po('char *')[1:-1] # strip the ""
283
290
 
284
291
  @command()
285
292
  def stop(self):
@@ -322,15 +329,16 @@ class HildaClient(metaclass=CommandsMeta):
322
329
  self.log_critical('failed to detach')
323
330
 
324
331
  @command()
325
- def disass(self, address, buf, should_print=True) -> lldb.SBInstructionList:
332
+ def disass(self, address, buf, flavor='intel', should_print=True) -> lldb.SBInstructionList:
326
333
  """
327
334
  Print disassembly from a given address
335
+ :param flavor:
328
336
  :param address:
329
337
  :param buf:
330
338
  :param should_print:
331
339
  :return:
332
340
  """
333
- inst = self.target.GetInstructions(lldb.SBAddress(address, self.target), buf)
341
+ inst = self.target.GetInstructionsWithFlavor(lldb.SBAddress(address, self.target), flavor, buf)
334
342
  if should_print:
335
343
  print(inst)
336
344
  return inst
@@ -515,12 +523,16 @@ class HildaClient(metaclass=CommandsMeta):
515
523
  """ Step into current instruction. """
516
524
  with self.sync_mode():
517
525
  self.thread.StepInto()
526
+ if self.ui_manager.active:
527
+ self.ui_manager.show()
518
528
 
519
529
  @command()
520
530
  def step_over(self):
521
531
  """ Step over current instruction. """
522
532
  with self.sync_mode():
523
533
  self.thread.StepOver()
534
+ if self.ui_manager.active:
535
+ self.ui_manager.show()
524
536
 
525
537
  @command()
526
538
  def remove_all_hilda_breakpoints(self, remove_forced=False):
@@ -608,7 +620,7 @@ class HildaClient(metaclass=CommandsMeta):
608
620
 
609
621
  def bp_callback_router(self, frame, bp_loc, *_):
610
622
  """
611
- Route the breakpoint callback the the specific breakpoint callback.
623
+ Route the breakpoint callback the specific breakpoint callback.
612
624
  :param lldb.SBFrame frame: LLDB Frame object.
613
625
  :param lldb.SBBreakpointLocation bp_loc: LLDB Breakpoint location object.
614
626
  """
@@ -902,13 +914,13 @@ class HildaClient(metaclass=CommandsMeta):
902
914
 
903
915
  if is_running:
904
916
  self.stop()
905
- time.sleep(1)
917
+ time.sleep(interval)
906
918
 
907
919
  try:
908
920
  yield
909
921
  finally:
910
922
  if is_running:
911
- time.sleep(1)
923
+ time.sleep(interval)
912
924
  self.cont()
913
925
 
914
926
  @contextmanager
@@ -1009,7 +1021,7 @@ class HildaClient(metaclass=CommandsMeta):
1009
1021
 
1010
1022
  return value
1011
1023
 
1012
- def interactive(self):
1024
+ def interactive(self, additional_namespace: typing.Mapping = None):
1013
1025
  """ Start an interactive Hilda shell """
1014
1026
  if not self._dynamic_env_loaded:
1015
1027
  self.init_dynamic_environment()
@@ -1025,6 +1037,8 @@ class HildaClient(metaclass=CommandsMeta):
1025
1037
  ]
1026
1038
  namespace = globals()
1027
1039
  namespace.update(locals())
1040
+ if additional_namespace is not None:
1041
+ namespace.update(additional_namespace)
1028
1042
 
1029
1043
  IPython.start_ipython(config=c, user_ns=namespace)
1030
1044
 
@@ -1116,12 +1130,11 @@ class HildaClient(metaclass=CommandsMeta):
1116
1130
  raise NotImplementedError('cannot serialize argument')
1117
1131
  return args_conv
1118
1132
 
1119
- @staticmethod
1120
- def _generate_call_expression(address, params):
1133
+ def _generate_call_expression(self, address, params):
1121
1134
  args_type = ','.join(['intptr_t'] * len(params))
1122
1135
  args_conv = ','.join(params)
1123
1136
 
1124
- if self.target.modules[0].triple.split('-')[0] == 'arm64e':
1137
+ if self.arch == 'arm64e':
1125
1138
  address = f'ptrauth_sign_unauthenticated((void *){address}, ptrauth_key_asia, 0)'
1126
1139
 
1127
1140
  return f'((intptr_t(*)({args_type}))({address}))({args_conv})'
@@ -1178,3 +1191,10 @@ class HildaClient(metaclass=CommandsMeta):
1178
1191
  return formatters[fmt](value)
1179
1192
  else:
1180
1193
  return f'{value:x} (unsupported format)'
1194
+
1195
+ @cached_property
1196
+ def _ks(self) -> Ks:
1197
+ platforms = {'arm64': Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN),
1198
+ 'arm64e': Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN),
1199
+ 'x86_64h': Ks(KS_ARCH_X86, KS_MODE_64)}
1200
+ return platforms.get(self.arch)
hilda/launch_lldb.py CHANGED
@@ -67,6 +67,26 @@ def bare():
67
67
  execute(f'lldb --one-line "{commands}"')
68
68
 
69
69
 
70
+ @cli.command('attach')
71
+ @click.option('-n', '--name', help='process name to attach')
72
+ @click.option('-p', '--pid', type=click.INT, help='pid to attach')
73
+ def attach(name: str, pid: int):
74
+ """ Attach to given process and start an lldb shell """
75
+ # connect local LLDB client
76
+ commands = []
77
+ if name is not None:
78
+ commands.append(f'process attach -n {name}')
79
+ elif pid is not None:
80
+ commands.append(f'process attach -p {pid}')
81
+ else:
82
+ print('missing either process name or pid for attaching')
83
+ return
84
+
85
+ commands.append(f'command script import {os.path.join(Path(__file__).resolve().parent, "lldb_entrypoint.py")}')
86
+ commands = '\n'.join(commands)
87
+ execute(f'lldb --one-line "{commands}"')
88
+
89
+
70
90
  if __name__ == '__main__':
71
91
  disable_logs()
72
92
  cli()
hilda/lldb_entrypoint.py CHANGED
@@ -15,7 +15,9 @@ lldb.hilda_client = None
15
15
  def hilda(debugger, command, result, internal_dict):
16
16
  if lldb.hilda_client is None:
17
17
  lldb.hilda_client = HildaClient(debugger)
18
- lldb.hilda_client.interactive()
18
+
19
+ additional_namespace = {'ui': lldb.hilda_client.ui_manager}
20
+ lldb.hilda_client.interactive(additional_namespace=additional_namespace)
19
21
 
20
22
 
21
23
  def __lldb_init_module(debugger, internal_dict):
@@ -7,13 +7,14 @@ from functools import partial
7
7
  from pathlib import Path
8
8
  from uuid import uuid4
9
9
 
10
+ from objc_types_decoder.decode import decode as decode_type
11
+ from objc_types_decoder.decode import decode_with_tail
10
12
  from pygments import highlight
11
13
  from pygments.formatters import TerminalTrueColorFormatter
12
14
  from pygments.lexers import ObjectiveCLexer
13
- from objc_types_decoder.decode import decode as decode_type, decode_with_tail
14
15
 
15
- from hilda.symbols_jar import SymbolsJar
16
16
  from hilda.exceptions import GettingObjectiveCClassError
17
+ from hilda.symbols_jar import SymbolsJar
17
18
 
18
19
  Ivar = namedtuple('Ivar', 'name type_ offset')
19
20
  Property = namedtuple('Property', 'name attributes')
@@ -5,15 +5,15 @@ from dataclasses import dataclass
5
5
  from functools import partial
6
6
  from pathlib import Path
7
7
 
8
+ from objc_types_decoder.decode import decode as decode_type
8
9
  from pygments import highlight
9
10
  from pygments.formatters import TerminalTrueColorFormatter
10
11
  from pygments.lexers import ObjectiveCLexer
11
- from objc_types_decoder.decode import decode as decode_type
12
12
 
13
13
  from hilda.exceptions import HildaException
14
- from hilda.objective_c_class import Class, convert_encoded_property_attributes, Method, Property
15
- from hilda.symbols_jar import SymbolsJar
14
+ from hilda.objective_c_class import Class, Method, Property, convert_encoded_property_attributes
16
15
  from hilda.symbol import Symbol
16
+ from hilda.symbols_jar import SymbolsJar
17
17
 
18
18
 
19
19
  class SettingIvarError(HildaException):
@@ -0,0 +1,26 @@
1
+ import lldb
2
+
3
+ _FILENAME = '/tmp/hilda-keylog.txt'
4
+
5
+
6
+ def _ssl_log_secret_bp(hilda, *args):
7
+ label = hilda.registers.x1.peek_str()
8
+ secret = hilda.registers.x2.peek(hilda.registers.x3).hex()
9
+ random = (hilda.registers.x0[6] + 48).peek(32).hex()
10
+ print(f'ssl_log_secret\n'
11
+ f' label: {label}\n'
12
+ f' secret: {secret}\n'
13
+ f' random: {random}\n'
14
+ f'---\n')
15
+ with open(_FILENAME, 'a') as f:
16
+ f.write(f'{label} {random} {secret}\n')
17
+ hilda.cont()
18
+
19
+
20
+ def start_keylog(filename: str = None) -> None:
21
+ global _FILENAME
22
+
23
+ if filename is not None:
24
+ _FILENAME = filename
25
+ hilda_client = lldb.hilda_client
26
+ hilda_client.symbols._ZN4bssl14ssl_log_secretEPK6ssl_stPKcNS_4SpanIKhEE.bp(_ssl_log_secret_bp)
hilda/snippets/dyld.py CHANGED
@@ -1,6 +1,5 @@
1
- from cached_property import cached_property
2
-
3
1
  import lldb
2
+ from cached_property import cached_property
4
3
 
5
4
  from hilda.snippets.macho.all_image_infos import AllImageInfos
6
5
  from hilda.snippets.syslog import open_syslog_socket
@@ -1,11 +1,53 @@
1
1
  import lldb
2
- from keystone import Ks, KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN
3
2
 
3
+ from hilda.exceptions import SymbolAbsentError
4
4
 
5
- def disable_mach_msg_errors():
5
+
6
+ def _CFRunLoopServiceMachPort_hook(hilda, *args):
7
+ """
8
+ :param hilda.hilda_client.HildaClient hilda:
9
+ """
10
+ hilda.jump(hilda.CFRunLoopServiceMachPort_while_ea)
11
+ hilda.cont()
12
+
13
+
14
+ def _disable_internal_error_handling() -> None:
15
+ hilda = lldb.hilda_client
16
+ with hilda.stopped():
17
+ instructions = hilda.symbols.__CFRunLoopServiceMachPort.disass(2000, should_print=False)
18
+ while_ea = None
19
+ for instruction in instructions:
20
+ if (while_ea is None) and instruction.DoesBranch():
21
+ # Beginning of the `while(true) { ... }`
22
+ while_ea = instruction.GetOperands(hilda.target)
23
+ hilda.CFRunLoopServiceMachPort_while_ea = int(hilda.file_symbol(eval(while_ea)))
24
+ elif instruction.GetMnemonic(hilda.target) in ('brk', 'ud2'):
25
+ symbol = hilda.symbol(instruction.addr.GetLoadAddress(hilda.target))
26
+ symbol.bp(
27
+ _CFRunLoopServiceMachPort_hook,
28
+ forced=True,
29
+ name=f'__CFRunLoopServiceMachPort-brk-{int(symbol - hilda.symbols.__CFRunLoopServiceMachPort)}'
30
+ )
31
+
32
+ if hilda.arch == 'x86_64h':
33
+ return
34
+
35
+ # on iOS 16.x, will need to also patch this one
36
+ try:
37
+ handle_error = hilda.symbols['__CFRunLoopServiceMachPort.cold.1']
38
+ except SymbolAbsentError:
39
+ return
40
+
41
+ for instruction in handle_error.disass(2000, should_print=False):
42
+ if instruction.GetMnemonic(hilda.target) in ('brk', 'ud2'):
43
+ # mov x0, x0
44
+ hilda.symbol(instruction.addr.GetLoadAddress(hilda.target)).poke(b'\xe0\x03\x00\xaa')
45
+
46
+
47
+ def _disable_mach_msg_timeout() -> None:
6
48
  """
7
- Disable mach_msg syscall timeout CFRunLoopServiceMachPort. `__CFRunLoopServiceMachPort` receives
8
- `mach_msg_timeout_t` parameter, the parameter passes on `x3` register. We set timeout = MACH_MSG_TIMEOUT_NONE.
49
+ Remove the timeout validation from __CFRunLoopServiceMachPort. This is done by patching the mach_msg_timeout_t
50
+ parameter (4rd one) to MACH_MSG_TIMEOUT_NONE. On arm the parameter passes on `x3` register.
9
51
 
10
52
  __int64 __fastcall __CFRunLoopServiceMachPort(
11
53
  mach_port_name_t a1,
@@ -29,15 +71,22 @@ def disable_mach_msg_errors():
29
71
  CoreFoundation:__text:0000000186E50154 MOV X23, X3 <-------- Timeout parameter
30
72
  """
31
73
  hilda = lldb.hilda_client
32
- ks = Ks(KS_ARCH_ARM64, KS_MODE_LITTLE_ENDIAN)
74
+ if hilda.arch == 'x86_64h':
75
+ return
76
+
33
77
  with hilda.stopped():
34
78
  for inst in hilda.symbols.__CFRunLoopServiceMachPort.disass(200, should_print=False):
35
79
  mnemonic = inst.GetMnemonic(hilda.target)
36
- operands = inst.GetOperands(hilda.target).replace(' ', '')
37
- if mnemonic != 'mov' or ',x3' not in operands:
80
+ operands = inst.GetOperands(hilda.target)
81
+ if mnemonic != 'mov' or not operands.endswith('x3'):
38
82
  continue
39
83
  addr = inst.GetAddress()
40
84
  file_addr = addr.GetFileAddress()
41
- encoding, _ = ks.asm(f'{mnemonic} {operands.replace("x3", "0")}')
42
- hilda.file_symbol(file_addr).poke(bytearray(encoding))
85
+ new_inst = f'{mnemonic} {operands.replace("x3", "0")}'
86
+ hilda.file_symbol(file_addr).poke_text(new_inst)
43
87
  break
88
+
89
+
90
+ def disable_mach_msg_errors() -> None:
91
+ _disable_mach_msg_timeout()
92
+ _disable_internal_error_handling()
@@ -1,10 +1,10 @@
1
1
  import logging
2
2
 
3
3
  import lldb
4
- from construct import Struct, Tell, Int32ul, Pointer, this, Array, Int32ub, CString, If, Int64ul, Hex
4
+ from construct import Array, CString, Hex, If, Int32ub, Int32ul, Int64ul, Pointer, Struct, Tell, this
5
5
  from humanfriendly import prompts
6
6
 
7
- from hilda.snippets.macho.image_info import dyld_image_info_t, ImageInfo
7
+ from hilda.snippets.macho.image_info import ImageInfo, dyld_image_info_t
8
8
  from hilda.snippets.macho.macho import mach_header_t
9
9
  from hilda.snippets.uuid import uuid_t
10
10
  from hilda.symbol import SymbolFormatField
@@ -1,4 +1,4 @@
1
- from construct import BitStruct, Octet, BitsInteger
1
+ from construct import BitsInteger, BitStruct, Octet
2
2
 
3
3
  version_t = BitStruct(
4
4
  'major' / BitsInteger(16),
@@ -1,5 +1,5 @@
1
1
  import lldb
2
- from construct import Pointer, this, CString, Int64ul, Struct, If
2
+ from construct import CString, If, Int64ul, Pointer, Struct, this
3
3
 
4
4
  from hilda.snippets.macho.macho import mach_header_t
5
5
  from hilda.snippets.macho.macho_load_commands import LoadCommands
@@ -1,4 +1,5 @@
1
- from construct import Int32ul, Struct, Hex, this, Tell, LazyArray, Computed
1
+ from construct import Computed, Hex, Int32ul, LazyArray, Struct, Tell, this
2
+
2
3
  from hilda.snippets.macho.macho_load_commands import LOAD_COMMAND_TYPE, load_command_t
3
4
 
4
5
 
@@ -1,7 +1,6 @@
1
1
  import lldb
2
-
3
- from construct import Hex, Int32ul, Pointer, PaddedString, Int64ul, this, Enum, Struct, Tell, Switch, Bytes, Seek, \
4
- Array, Int8ul
2
+ from construct import Array, Bytes, Enum, Hex, Int8ul, Int32ul, Int64ul, PaddedString, Pointer, Seek, Struct, Switch, \
3
+ Tell, this
5
4
 
6
5
  from hilda.snippets.macho.apple_version import version_t
7
6
  from hilda.symbol import SymbolFormatField
@@ -35,9 +35,7 @@ TLV_MAP = {
35
35
  }
36
36
 
37
37
 
38
- def TLV8CopyCoalesced_bp(hilda, *args):
39
- src = hilda.registers.x0
40
- end = hilda.registers.x1
38
+ def _TLV8CopyCoalesced_bp(hilda, *args):
41
39
  type_ = hilda.registers.x2
42
40
  out_len = hilda.registers.x3
43
41
  out_len.item_size = 4
@@ -56,7 +54,7 @@ def TLV8CopyCoalesced_bp(hilda, *args):
56
54
  hilda.cont()
57
55
 
58
56
 
59
- def TLV8BufferAppend_bp(hilda, *args):
57
+ def _TLV8BufferAppend_bp(hilda, *args):
60
58
  buffer = hilda.registers.x0
61
59
  type_ = hilda.registers.x1
62
60
  buffer = hilda.registers.x2
@@ -68,9 +66,7 @@ def TLV8BufferAppend_bp(hilda, *args):
68
66
  hilda.cont()
69
67
 
70
68
 
71
- def SRPClientStart_libsrp_bp(hilda, *args):
72
- client = hilda.registers.x0
73
- params = hilda.registers.x1
69
+ def _SRPClientStart_libsrp_bp(hilda, *args):
74
70
  username = hilda.registers.x2
75
71
  username_len = hilda.registers.x3
76
72
  password = hilda.registers.x4
@@ -91,8 +87,7 @@ def SRPClientStart_libsrp_bp(hilda, *args):
91
87
  hilda.cont()
92
88
 
93
89
 
94
- def cced25519_sign_bp(hilda, *args):
95
- digest_info = hilda.registers.x0
90
+ def _cced25519_sign_bp(hilda, *args):
96
91
  sig = hilda.registers.x1
97
92
  len = hilda.registers.x2
98
93
  msg = hilda.registers.x3
@@ -109,8 +104,7 @@ def cced25519_sign_bp(hilda, *args):
109
104
  hilda.cont()
110
105
 
111
106
 
112
- def cced25519_verify_bp(hilda, *args):
113
- digest_info = hilda.registers.x0
107
+ def _cced25519_verify_bp(hilda, *args):
114
108
  sig = hilda.registers.x3
115
109
  len = hilda.registers.x1
116
110
  msg = hilda.registers.x2
@@ -125,7 +119,7 @@ def cced25519_verify_bp(hilda, *args):
125
119
  hilda.cont()
126
120
 
127
121
 
128
- def CryptoHKDF_bp(hilda, *args):
122
+ def _CryptoHKDF_bp(hilda, *args):
129
123
  descriptor = hilda.registers.x0
130
124
  key = hilda.registers.x1.peek(hilda.registers.x2)
131
125
  salt = hilda.registers.x3
@@ -177,14 +171,14 @@ def _chacha20_poly1305_decrypt_all_bp(hilda, *args):
177
171
  def monitor_crypto_functions() -> None:
178
172
  hilda_client = lldb.hilda_client
179
173
 
180
- hilda_client.symbols.TLV8CopyCoalesced.bp(TLV8CopyCoalesced_bp)
181
- hilda_client.symbols.TLV8BufferAppend.bp(TLV8BufferAppend_bp)
182
- hilda_client.symbols.SRPClientStart_libsrp.bp(SRPClientStart_libsrp_bp)
174
+ hilda_client.symbols.TLV8CopyCoalesced.bp(_TLV8CopyCoalesced_bp)
175
+ hilda_client.symbols.TLV8BufferAppend.bp(_TLV8BufferAppend_bp)
176
+ hilda_client.symbols.SRPClientStart_libsrp.bp(_SRPClientStart_libsrp_bp)
183
177
  hilda_client.symbols.SRPClientVerify_libsrp.monitor()
184
178
  hilda_client.symbols.SRPServerStart_libsrp.monitor()
185
179
  hilda_client.symbols.SRPServerVerify_libsrp.monitor()
186
- hilda_client.symbols.cced25519_sign.bp(cced25519_sign_bp)
187
- hilda_client.symbols.cced25519_verify.bp(cced25519_verify_bp)
188
- hilda_client.symbols.CryptoHKDF.bp(CryptoHKDF_bp)
180
+ hilda_client.symbols.cced25519_sign.bp(_cced25519_sign_bp)
181
+ hilda_client.symbols.cced25519_verify.bp(_cced25519_verify_bp)
182
+ hilda_client.symbols.CryptoHKDF.bp(_CryptoHKDF_bp)
189
183
  hilda_client.symbols._chacha20_poly1305_encrypt_all.bp(_chacha20_poly1305_encrypt_all_bp)
190
184
  hilda_client.symbols._chacha20_poly1305_decrypt_all.bp(_chacha20_poly1305_decrypt_all_bp)
hilda/snippets/uuid.py CHANGED
@@ -1,4 +1,4 @@
1
- from construct import Struct, Int64ul, Int32ul, Int8ul, Array
1
+ from construct import Array, Int8ul, Int32ul, Int64ul, Struct
2
2
 
3
3
  uuid_t = Struct(
4
4
  'time_low' / Int64ul,
hilda/snippets/xpc.py CHANGED
@@ -54,6 +54,15 @@ def from_xpc_object(address: int):
54
54
  return lldb.hilda_client.from_ns(f'_CFXPCCreateCFObjectFromXPCObject({address})')
55
55
 
56
56
 
57
+ def disable_transaction_exit():
58
+ """
59
+ xpc_transaction_exit_clean will kill the process when transaction is done.
60
+ By patching this function the process will stay alive.
61
+ """
62
+ hilda = lldb.hilda_client
63
+ hilda.symbols.xpc_transaction_exit_clean.poke_text('ret')
64
+
65
+
57
66
  def to_xpc_object(obj: object):
58
67
  """
59
68
  Convert python object to XPC object.
hilda/symbol.py CHANGED
@@ -1,7 +1,8 @@
1
- from construct import FormatField
2
- from contextlib import contextmanager
3
- import struct
4
1
  import os
2
+ import struct
3
+ from contextlib import contextmanager
4
+
5
+ from construct import FormatField
5
6
 
6
7
  from hilda.objective_c_class import Class
7
8
 
@@ -119,8 +120,11 @@ class Symbol(int):
119
120
  def poke(self, buf):
120
121
  return self._client.poke(self, buf)
121
122
 
122
- def peek_str(self, encoding=None):
123
- return self._client.peek_str(self, encoding)
123
+ def poke_text(self, code: str) -> int:
124
+ return self._client.poke_text(self, code)
125
+
126
+ def peek_str(self):
127
+ return self._client.peek_str(self)
124
128
 
125
129
  def monitor(self, **args):
126
130
  return self._client.monitor(self, **args)
hilda/symbols_jar.py CHANGED
@@ -2,7 +2,7 @@ from contextlib import suppress
2
2
 
3
3
  import lldb
4
4
 
5
- from hilda.exceptions import SymbolAbsentError, AddingLldbSymbolError
5
+ from hilda.exceptions import AddingLldbSymbolError, SymbolAbsentError
6
6
 
7
7
 
8
8
  class SymbolsJar(dict):
hilda/ui/colors.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "title": "green",
3
+ "address": "bright_blue",
4
+ "regs_title": "green",
5
+ "regs_name": "cyan",
6
+ "regs_value": "white",
7
+ "mnemonic": "white",
8
+ "operands": "white",
9
+ "basename": "yellow",
10
+ "stack_offset": "white",
11
+ "stack_data": "white",
12
+ "diff": "red"
13
+ }