hilda 2.0.16__py3-none-any.whl → 3.0.1__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/launch_lldb.py CHANGED
@@ -61,6 +61,33 @@ class LLDBListenerThread(Thread, ABC):
61
61
  sys.stderr.write(stderr)
62
62
  stderr = self.process.GetSTDERR(1024)
63
63
 
64
+ def _process_potential_watchpoint_event(self) -> None:
65
+ stopped_threads = self._get_stopped_threads(lldb.eStopReasonWatchpoint)
66
+ for thread in stopped_threads:
67
+ watchpoint_id = thread.GetStopReasonDataAtIndex(0)
68
+ frame = thread.GetFrameAtIndex(0)
69
+ if lldb.hilda_client is not None:
70
+ lldb.hilda_client.watchpoints._dispatch_watchpoint_callback(watchpoint_id, thread, frame)
71
+
72
+ def _get_stopped_threads(self, reason: Optional[int] = None) -> list[lldb.SBThread]:
73
+ if reason is None:
74
+ stop_reasons = [
75
+ lldb.eStopReasonSignal, lldb.eStopReasonException,
76
+ lldb.eStopReasonBreakpoint, lldb.eStopReasonWatchpoint,
77
+ lldb.eStopReasonPlanComplete, lldb.eStopReasonTrace,
78
+ ]
79
+ else:
80
+ stop_reasons = [reason]
81
+
82
+ return [thread for thread in self.process if thread.GetStopReason() in stop_reasons]
83
+
84
+ def _set_selected_thread_to_stopped_thread(self) -> None:
85
+ stopped_threads = self._get_stopped_threads()
86
+ if len(stopped_threads) < 1:
87
+ return
88
+ thread = stopped_threads[0]
89
+ self.process.SetSelectedThread(thread)
90
+
64
91
  def run(self):
65
92
  event = lldb.SBEvent()
66
93
  last_state = lldb.eStateStopped
@@ -87,18 +114,8 @@ class LLDBListenerThread(Thread, ABC):
87
114
  logger.debug('Process Continued')
88
115
  elif state == lldb.eStateStopped and last_state == lldb.eStateRunning:
89
116
  logger.debug('Process Stopped')
90
- for thread in self.process:
91
- frame = thread.GetFrameAtIndex(0)
92
- stop_reason = thread.GetStopReason()
93
- logger.debug(f'tid = {hex(thread.GetThreadID())} pc = {frame.GetPC()}')
94
- if stop_reason not in [lldb.eStopReasonSignal, lldb.eStopReasonException,
95
- lldb.eStopReasonBreakpoint,
96
- lldb.eStopReasonWatchpoint, lldb.eStopReasonPlanComplete,
97
- lldb.eStopReasonTrace,
98
- lldb.eStopReasonSignal]:
99
- continue
100
- self.process.SetSelectedThread(thread)
101
- break
117
+ self._set_selected_thread_to_stopped_thread()
118
+ self._process_potential_watchpoint_event()
102
119
 
103
120
  last_state = state
104
121
 
@@ -4,7 +4,6 @@ from collections import namedtuple
4
4
  from dataclasses import dataclass, field
5
5
  from functools import partial
6
6
  from typing import Any
7
- from uuid import uuid4
8
7
 
9
8
  from objc_types_decoder.decode import decode as decode_type
10
9
  from objc_types_decoder.decode import decode_with_tail
@@ -188,19 +187,16 @@ class Class:
188
187
  hilda.log_info('removing breakpoints')
189
188
  for bp_id, bp in list(hilda.breakpoints.items()):
190
189
  if 'group_uuid' in bp.options and bp.options.get('group_uuid', '') == options['group_uuid']:
191
- hilda.remove_hilda_breakpoint(bp_id)
190
+ hilda.breakpoints.remove(bp_id)
192
191
  captured = hilda.evaluate_expression('$arg1')
193
192
  captured = captured.objc_symbol
194
193
  hilda.captured_objects[options['name'].split(' ')[0].split('[')[1]] = captured
195
194
  hilda.cont()
196
195
 
197
- group_uuid = str(uuid4())
198
-
199
196
  for method in self.methods:
200
197
  if not method.is_class:
201
198
  # only instance methods are relevant for capturing self
202
- method.imp.bp(hook, group_uuid=group_uuid,
203
- name=f'-[{class_name} {method.name}]')
199
+ method.imp.bp(hook)
204
200
 
205
201
  if sync:
206
202
  self._client.cont()
@@ -22,11 +22,8 @@ def _disable_internal_error_handling() -> None:
22
22
  hilda.CFRunLoopServiceMachPort_while_ea = int(hilda.file_symbol(eval(while_ea)))
23
23
  elif instruction.GetMnemonic(hilda.target) in ('brk', 'ud2'):
24
24
  symbol = hilda.symbol(instruction.addr.GetLoadAddress(hilda.target))
25
- symbol.bp(
26
- _CFRunLoopServiceMachPort_hook,
27
- forced=True,
28
- name=f'__CFRunLoopServiceMachPort-brk-{int(symbol - hilda.symbols.__CFRunLoopServiceMachPort)}'
29
- )
25
+ description = f'__CFRunLoopServiceMachPort-brk-{int(symbol - hilda.symbols.__CFRunLoopServiceMachPort)}'
26
+ symbol.bp(_CFRunLoopServiceMachPort_hook, guarded=True, description=description)
30
27
 
31
28
  if hilda.arch == 'x86_64h':
32
29
  return
@@ -1,7 +1,8 @@
1
1
  import logging
2
2
 
3
+ import inquirer3
3
4
  from construct import Array, CString, Hex, If, Int32ub, Int32ul, Int64ul, Pointer, Struct, Tell, this
4
- from humanfriendly import prompts
5
+ from inquirer3 import List
5
6
 
6
7
  from hilda.lldb_importer import lldb
7
8
  from hilda.snippets.macho.image_info import ImageInfo, dyld_image_info_t
@@ -104,9 +105,11 @@ class AllImageInfos:
104
105
 
105
106
  @staticmethod
106
107
  def __select_specific_image(images):
107
- logging.info('Multiple images were found with that prefix.\nPlease select one')
108
- print([f"{image.file_path}" for image in images])
109
- selected_image_path = prompts.prompt_for_choice([f"{image.file_path}" for image in images])
108
+ image_list = [image.file_path for image in images]
109
+ logging.info('Multiple images were found with that prefix.\n'
110
+ 'Please select one:\n'
111
+ f'{image_list}')
112
+ selected_image_path = inquirer3.prompt(List('selected_image_path', image_list))['selected_image_path']
110
113
  for image in images:
111
114
  if image.file_path == selected_image_path:
112
115
  return image
hilda/symbol.py CHANGED
@@ -145,6 +145,9 @@ class Symbol(int):
145
145
  def monitor(self, **args):
146
146
  return self._client.monitor(self, **args)
147
147
 
148
+ def watch(self, **args):
149
+ return self._client.watchpoints.add(self, **args)
150
+
148
151
  def bp(self, callback=None, **args):
149
152
  return self._client.bp(self, callback, **args)
150
153
 
hilda/watchpoints.py ADDED
@@ -0,0 +1,237 @@
1
+ from typing import Callable, Generator, Optional, Union
2
+
3
+ from hilda.lldb_importer import lldb
4
+
5
+
6
+ class HildaWatchpoint:
7
+ """
8
+ Hilda's class representing an LLDB watchpoint, with some optional additional properties
9
+ """
10
+
11
+ def __init__(self, hilda, lldb_watchpoint: lldb.SBWatchpoint, where: Optional[int] = None) -> None:
12
+ """
13
+ Initialize a watchpoint list.
14
+
15
+ :param hilda.hilda_client.HildaClient hilda: Hilda client
16
+ """
17
+ self._hilda = hilda
18
+ self._where = where
19
+ self._callback = None
20
+
21
+ # Actual watchpoint from LLDB API
22
+ self.lldb_watchpoint = lldb_watchpoint
23
+
24
+ @property
25
+ def where(self) -> Optional[int]:
26
+ """
27
+ A value identifying where the watchpoint was set (when it was created).
28
+
29
+ It could be either an address (int) or a Hilda symbol object (Symbol, that inherits from int).
30
+ """
31
+ return self._where
32
+
33
+ @property
34
+ def id(self) -> int:
35
+ """ A number identifying the watchpoint. """
36
+ return self.lldb_watchpoint.GetID()
37
+
38
+ @property
39
+ def callback(self) -> Optional[Callable]:
40
+ """
41
+ A callback that will be executed when the watchpoint is hit.
42
+
43
+ Note that unless the callback explicitly continues (by calling `cont()`), the program will not continue.
44
+ The callback will be invoked as callback(hilda, *args), where hilda is the 'HildaClient'.
45
+ """
46
+ return self._callback
47
+
48
+ @callback.setter
49
+ def callback(self, callback: Optional[Callable]) -> None:
50
+ self._callback = callback
51
+
52
+ @property
53
+ def condition(self) -> Optional[str]:
54
+ """
55
+ An LLDB expression to make this a conditional watchpoint.
56
+ """
57
+ return self.lldb_watchpoint.GetCondition()
58
+
59
+ @condition.setter
60
+ def condition(self, condition: Optional[str]) -> None:
61
+ self.lldb_watchpoint.SetCondition(condition)
62
+
63
+ def __repr__(self) -> str:
64
+ return f'<{self.__class__.__name__} LLDB:{self.lldb_watchpoint} CALLBACK:{self.callback}>'
65
+
66
+ def __str__(self) -> str:
67
+ return repr(self)
68
+
69
+ def remove(self) -> None:
70
+ """
71
+ Remove the watchpoint.
72
+ """
73
+ self._hilda.watchpoints.remove(self)
74
+
75
+
76
+ class WatchpointList:
77
+ """
78
+ Manager for `HildaWatchpoint` objects, each one wrapping another native LLDB watchpoint.
79
+ """
80
+
81
+ def __init__(self, hilda) -> None:
82
+ """
83
+ Initialize a watchpoint list.
84
+
85
+ :param hilda.hilda_client.HildaClient hilda: Hilda client
86
+ """
87
+ self._hilda = hilda
88
+ self._watchpoints = {}
89
+
90
+ def __contains__(self, id_or_wp: Union[int, HildaWatchpoint]) -> bool:
91
+ return self.get(id_or_wp) is not None
92
+
93
+ def __iter__(self) -> Generator[HildaWatchpoint, None, None]:
94
+ for wp in self._hilda.target.watchpoint_iter():
95
+ yield self[wp.GetID()]
96
+
97
+ def __len__(self) -> int:
98
+ return self._hilda.target.GetNumWatchpoints()
99
+
100
+ def __getitem__(self, id_or_wp: Union[int, HildaWatchpoint]) -> HildaWatchpoint:
101
+ """
102
+ Get a watchpoint by ID (or the watchpoint itself, though it usually makes little sense)
103
+
104
+ :param id_or_wp: Watchpoint's ID (or the watchpoint itself)
105
+ """
106
+ wp = self.get(id_or_wp)
107
+ if wp is None:
108
+ raise KeyError(id_or_wp)
109
+
110
+ return wp
111
+
112
+ def __delitem__(self, id_or_wp: Union[int, HildaWatchpoint]):
113
+ """
114
+ Remove a watchpoint.
115
+
116
+ :param id_or_wp: Watchpoint's ID (or the watchpoint itself)
117
+ """
118
+ self.remove(id_or_wp)
119
+
120
+ def __repr__(self) -> str:
121
+ return repr(dict(self.items()))
122
+
123
+ def __str__(self) -> str:
124
+ return repr(self)
125
+
126
+ def get(self, id_or_wp: Union[int, HildaWatchpoint]) -> Optional[HildaWatchpoint]:
127
+ """
128
+ Get a watchpoint by ID or the watchpoint itself.
129
+
130
+ :param id_or_wp: Watchpoint's ID (or the watchpoint itself)
131
+ :return: `HildaWatchpoint` is one exists, or `None` otherwise
132
+ """
133
+
134
+ if isinstance(id_or_wp, int):
135
+ wp = self._hilda.target.FindWatchpointByID(id_or_wp)
136
+ elif isinstance(id_or_wp, HildaWatchpoint):
137
+ wp = id_or_wp.lldb_watchpoint
138
+ else:
139
+ raise KeyError(f'Watchpoint "{id_or_wp}" could not be found')
140
+
141
+ if not wp.IsValid():
142
+ return None
143
+
144
+ wp_id = wp.GetID()
145
+ if wp_id not in self._watchpoints:
146
+ self._hilda.log_debug(f'Found a watchpoint added outside of the Hilda API {wp}')
147
+ self._watchpoints[wp_id] = HildaWatchpoint(self._hilda, wp)
148
+
149
+ return self._watchpoints[wp_id]
150
+
151
+ def add(self, where: int, size: int = 8, read: bool = True, write: bool = True,
152
+ callback: Optional[Callable] = None, condition: str = None) -> HildaWatchpoint:
153
+ """
154
+ Add a watchpoint.
155
+
156
+ :param where: The address of the watchpoint.
157
+ :param size: The size of the watchpoint (the address span to watch).
158
+ :param read: The watchpoint should monitor reads from memory in the specified address (and size).
159
+ :param write: The watchpoint should monitor writes to memory in the specified address (and size).
160
+ :param callback: A callback that will be executed when the watchpoint is hit.
161
+ Note that unless the callback explicitly continues (by calling cont()), the program will not continue.
162
+ The callback will be invoked as callback(hilda, *args), where hilda is the 'HildaClient'.
163
+ :param condition: An LLDB expression to make this a conditional watchpoint.
164
+ :return: The new watchpoint
165
+ """
166
+
167
+ error = lldb.SBError()
168
+ wp = self._hilda.target.WatchAddress(where, size, read, write, error)
169
+ if not wp.IsValid():
170
+ raise Exception(f'Failed to create watchpoint at {where} ({error})')
171
+
172
+ wp = HildaWatchpoint(self._hilda, wp, where)
173
+ wp.callback = callback
174
+ wp.condition = condition
175
+
176
+ self._watchpoints[wp.id] = wp
177
+
178
+ self._hilda.log_info(f'Watchpoint #{wp.id} has been set')
179
+ return wp
180
+
181
+ def remove(self, id_or_wp: Union[int, HildaWatchpoint]) -> None:
182
+ """
183
+ Remove a watchpoint.
184
+
185
+ :param id_or_wp: Watchpoint's ID (or the watchpoint itself)
186
+ """
187
+ wp = self[id_or_wp]
188
+ watchpoint_id = wp.id
189
+ self._hilda.target.DeleteWatchpoint(watchpoint_id)
190
+ self._hilda.log_debug(f'Watchpoint #{watchpoint_id} has been removed')
191
+
192
+ def clear(self) -> None:
193
+ """
194
+ Remove all watchpoints
195
+ """
196
+ for wp in list(self):
197
+ self.remove(wp)
198
+
199
+ def show(self) -> None:
200
+ """ Show existing watchpoints. """
201
+ for wp in self:
202
+ message = f'🚨 Watchpoint #{wp.id}'
203
+
204
+ if wp.where is not None:
205
+ message += f'\n\tWhere: {wp.where}'
206
+
207
+ self._hilda.log_info(message)
208
+
209
+ def items(self) -> Generator[tuple[int, HildaWatchpoint], None, None]:
210
+ """
211
+ Get a watchpoint ID and watchpoint object tuple for every watchpoint.
212
+ """
213
+ return ((wp.id, wp) for wp in self)
214
+
215
+ def keys(self) -> Generator[int, None, None]:
216
+ """
217
+ Get the watchpoint ID for every watchpoint.
218
+ """
219
+ return (wp.id for wp in self)
220
+
221
+ def values(self) -> Generator[HildaWatchpoint, None, None]:
222
+ """
223
+ Get the watchpoint object for every watchpoint.
224
+ """
225
+ return (wp for wp in self)
226
+
227
+ def _dispatch_watchpoint_callback(self, watchpoint_id: int, _, frame) -> None:
228
+ """
229
+ Route the watchpoint callback the specific watchpoint callback.
230
+ """
231
+ self._hilda._bp_frame = frame
232
+ try:
233
+ callback = self[watchpoint_id].callback
234
+ if callback is not None:
235
+ callback(self._hilda, frame, None, self[watchpoint_id])
236
+ finally:
237
+ self._hilda._bp_frame = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: hilda
3
- Version: 2.0.16
3
+ Version: 3.0.1
4
4
  Summary: LLDB wrapped and empowered by iPython's features
5
5
  Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>, netanel cohen <netanelc305@protonmail.com>
6
6
  Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>, netanel cohen <netanelc305@protonmail.com>
@@ -52,6 +52,7 @@ Requires-Dist: pymobiledevice3
52
52
  Requires-Dist: keystone-engine
53
53
  Requires-Dist: tabulate
54
54
  Requires-Dist: inquirer3
55
+ Requires-Dist: traitlets
55
56
  Provides-Extra: test
56
57
  Requires-Dist: pytest; extra == "test"
57
58
 
@@ -162,7 +163,7 @@ Have a nice flight ✈️! Starting an IPython shell...
162
163
  Here is a gist of methods you can access from `p`:
163
164
 
164
165
  - `hd`
165
- - Print an hexdump of given buffer
166
+ - Print a hexdump of given buffer
166
167
  - `lsof`
167
168
  - Get dictionary of all open FDs
168
169
  - `bt`
@@ -209,7 +210,7 @@ Here is a gist of methods you can access from `p`:
209
210
  - Simulate a call to an objc selector
210
211
  - `call`
211
212
  - Call function at given address with given parameters
212
- - `monitor`
213
+ - `monitor` or `breakpoints.add_monitor`
213
214
  - Monitor every time a given address is called
214
215
 
215
216
  The following options are available:
@@ -254,10 +255,10 @@ Here is a gist of methods you can access from `p`:
254
255
  - Step into current instruction.
255
256
  - `step_over`
256
257
  - Step over current instruction.
257
- - `remove_all_hilda_breakpoints`
258
- - Remove all breakpoints created by Hilda
259
- - `remove_hilda_breakpoint`
260
- - Remove a single breakpoint placed by Hilda
258
+ - `breakpoints.clear`
259
+ - Remove all breakpoints
260
+ - `breakpoints.remove`
261
+ - Remove a single breakpoint
261
262
  - `force_return`
262
263
  - Prematurely return from a stack frame, short-circuiting exection of newer frames and optionally
263
264
  yielding a specified value.
@@ -265,14 +266,10 @@ Here is a gist of methods you can access from `p`:
265
266
  - Print information about currently running mapped process.
266
267
  - `print_proc_entitlements`
267
268
  - Get the plist embedded inside the process' __LINKEDIT section.
268
- - `bp`
269
+ - `bp` or `breakpoints.add`
269
270
  - Add a breakpoint
270
- - `show_hilda_breakpoints`
271
- - Show existing breakpoints created by Hilda.
272
- - `save`
273
- - Save loaded symbols map (for loading later using the load() command)
274
- - `load`
275
- - Load an existing symbols map (previously saved by the save() command)
271
+ - `breakpoints.show`
272
+ - Show existing breakpoints
276
273
  - `po`
277
274
  - Print given object using LLDB's po command
278
275
  Can also run big chunks of native code:
@@ -326,6 +323,9 @@ Sometimes accessing the [Python API](#python-api) can be tiring, so we added som
326
323
 
327
324
  #### Key-bindings
328
325
 
326
+ - **F1**: Show banner help message
327
+ - **F2**: Show process state UI
328
+ - **F3**: Toggle stdout/stderr enablement
329
329
  - **F7**: Step Into
330
330
  - **F8**: Step Over
331
331
  - **F9**: Continue
@@ -531,7 +531,7 @@ s.bp(scripted_breakpoint)
531
531
  p.bp('symbol_name')
532
532
 
533
533
  # In case you need to specify a specific library it's loaded from
534
- p.bp('symbol_name', module_name='ModuleName')
534
+ p.bp(('symbol_name', 'ModuleName'))
535
535
  ```
536
536
 
537
537
  #### Globalized symbols
@@ -3,22 +3,24 @@ gifs/ui.png,sha256=iaRwNZ9qVWUkUe2TJb_6VPsTu--7HrElA2duWiyZ-Oc,131
3
3
  gifs/xpc_print_message.gif,sha256=i5S8Y9bJm9n-NtOipFTAC8_jUR4uZCM4sOap_ccJX0k,939935
4
4
  hilda/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  hilda/__main__.py,sha256=KWRqvukK4wraxCMtvH5nO25mFXLO5aWXa7z_VfAtbO8,90
6
- hilda/_version.py,sha256=Rj6OwV2GJpyCTs0m5bHo9CElWBJTCnmOdBSPUYg9oj4,413
6
+ hilda/_version.py,sha256=LoHm4tYT8EC9S2qaIOxZkFh7b3UUZ5jNAQr7bVyLo6Q,511
7
+ hilda/breakpoints.py,sha256=ZVszQf4WtRgjM2JAn8E-b-Ve6kzVg5VwvTHv5_wGjwQ,19198
7
8
  hilda/cli.py,sha256=PCjrI7GrERIrZCODJYmPt6eyl-nPYZviTS8fBG3oIjM,3618
8
9
  hilda/common.py,sha256=El-ih7cvCv9PJ5OWb1jkCbh4GuaRD6gqlrFC5gyY-TE,498
9
10
  hilda/exceptions.py,sha256=8L1OvOqns4O4ieiH4YlrMbZkk_PvuyCq4UyqFAodkF8,2042
10
11
  hilda/hilda_ascii_art.html,sha256=-9YCjAKdGbjtdd6uoKrxkkcJq7j16r4dGka2bZ27b4o,120119
11
- hilda/hilda_client.py,sha256=jJ1vKtvSM1Hfx9Hbtr2coRqQnpctuBtBXy1HTXEa-RI,48293
12
- hilda/launch_lldb.py,sha256=gU1iJmxuH7w5HV_cy1igv-JageyQn2dmqSxx8vkpY0k,8033
12
+ hilda/hilda_client.py,sha256=phSwiI3XfuLzMXlUw7-irbZbEgi7sEpDz2w7EGUUhf0,38897
13
+ hilda/launch_lldb.py,sha256=-lmxif-w53oeTCea6ZHLiYHChkMpdDDO_zgTFWpAU6E,8597
13
14
  hilda/lldb_entrypoint.py,sha256=vTiClzfiTtjorlxEfIsI-W657KEGobx74qDhaZ8nPhM,1007
14
15
  hilda/lldb_importer.py,sha256=TCGpAWwiBuyNRsbgcYawiqm35t8XQLCJwoOfEqyBeik,526
15
- hilda/objective_c_class.py,sha256=arIgABZxqsLyo9Q6kyw-Sujm5j-89QUOjS0njjBcGo8,11716
16
+ hilda/objective_c_class.py,sha256=AFGXFDkYUoHf_LVS6GJSyvMsIIYIviLx0PCa-f4pCT8,11561
16
17
  hilda/objective_c_symbol.py,sha256=lIZHef5iZe3AeUsK0uIsDtFnzSM-Ad6i2wfdj9DwLUM,8269
17
18
  hilda/registers.py,sha256=-9kk1MuKnWlJ0Z8zZ2RPV9nGRDtX1GXhCSkEvfnCktA,848
18
- hilda/symbol.py,sha256=yv8s0vQ6Z0ZoROeVE4RVaW0LFCyACZnFgp0QC6j05nI,7535
19
+ hilda/symbol.py,sha256=UIDmnNq1tx1uORqgRNaO_gfW2y17mhyy4cz83UVFhcc,7623
19
20
  hilda/symbols_jar.py,sha256=Vqdv6iH92P6aSfcz5XiR0FbNRqKuUu48mi-GxvPr32w,6504
21
+ hilda/watchpoints.py,sha256=j5wLEORXUkxeamjI2F61QXRrSXcGsbs4XTmN1UEa_A4,7895
20
22
  hilda/ipython_extensions/events.py,sha256=w_4V8FoJJMarWArEE8uzb2UXk1mqfslmI7XCyVb_XuE,1976
21
- hilda/ipython_extensions/keybindings.py,sha256=Ai9wHCla6HhgZGGxc0UEOCYODcavyef_zzUC9A9GcTE,1081
23
+ hilda/ipython_extensions/keybindings.py,sha256=W_Cnh8lG5yVdK5x0A-4UeyBsoJBufbYl54Mqrbo8OwM,1922
22
24
  hilda/ipython_extensions/magics.py,sha256=ULb63-OyIaWwvSfwRvEG_65ibaI2RTxeX8yPJK8pbc0,1300
23
25
  hilda/objective_c/from_ns_to_json.m,sha256=5Ddl0UJLQXlDYwR_yjE4yZk1aOsJGxoy1oRnhZHPrTw,2847
24
26
  hilda/objective_c/get_objectivec_class_by_module.m,sha256=DC8S8XaWsQSOJZWVWhATr98SZQobA3MmclLsBJGZTcU,704
@@ -36,10 +38,10 @@ hilda/snippets/remotepairingd.py,sha256=w7SYctpKw3B56ZP26n4Ap5_hz6VmZiUbe8CrTmZ1
36
38
  hilda/snippets/syslog.py,sha256=8qhYHKTElzWifqYAwt72iQ57wf1n0F_au2Vl2L8NPOc,294
37
39
  hilda/snippets/uuid.py,sha256=ttw-rq2Wshm7UMZXd5uYP37bi8G_ZE4XcXJbsYIgp1c,273
38
40
  hilda/snippets/xpc.py,sha256=Z0e4b1lIScZg7fsSwGK43v363qp25fdzYcc7ajJsyhU,3960
39
- hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py,sha256=gAJD0Qi2w0IxkPnHMbF5webODwot9PPChMRHVNQ6zSg,4230
41
+ hilda/snippets/mach/CFRunLoopServiceMachPort_hooks.py,sha256=8e6184bcRhqSDqXyDu-jnIXDbdw-mnP15J4MgNBKyg4,4202
40
42
  hilda/snippets/mach/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
43
  hilda/snippets/macho/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
- hilda/snippets/macho/all_image_infos.py,sha256=HdaFHhOM_AoXX_YTo9L7eEoX5MvMLTw4DZ_JZiTjdAs,4780
44
+ hilda/snippets/macho/all_image_infos.py,sha256=dwuf4vhewP1EvtcCa65IIVqWyDeFYxoBcqygpWK2INw,4866
43
45
  hilda/snippets/macho/apple_version.py,sha256=TTaqZKMviXJoU1o3OYeUskmxSkhVhh3UG1VbdJ6N-LE,148
44
46
  hilda/snippets/macho/image_info.py,sha256=Onu6u61TwFOwAfENpZIQA9N-Ba3b_M0gr8r6THNdIR4,1605
45
47
  hilda/snippets/macho/macho.py,sha256=X4NQZkO7VCcIMNuPs25ukiBrHM5Kj3UPMJzzeILfuyg,839
@@ -47,9 +49,9 @@ hilda/snippets/macho/macho_load_commands.py,sha256=vUWfFM2H6o8dMglXV7rHgh-EMTzS0
47
49
  hilda/ui/colors.json,sha256=f-ITquY3IInQreviTy23JfmxfJrGM1_MivACf1GKGqM,262
48
50
  hilda/ui/ui_manager.py,sha256=BmzI1sBx0PYCQDlB9Al7wsTEAMJxaJ7NW0DS4C7g5-0,2265
49
51
  hilda/ui/views.py,sha256=bzClOgKirKYs6nhsNRXpkGNIg3oIOmFb659GLWrlTdo,7792
50
- hilda-2.0.16.dist-info/LICENSE,sha256=M-LVJ0AFAYB82eueyl8brh-QLPe-iLNVgbCi79-3TDo,1078
51
- hilda-2.0.16.dist-info/METADATA,sha256=yVyahVngw47NUOFArDj4dv7Libn2F9uO1VvtCPIcNYA,23420
52
- hilda-2.0.16.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
53
- hilda-2.0.16.dist-info/entry_points.txt,sha256=9n3O3j6V3XnVR_GcFqCWNgRAbalfukTSW2WvghsLVmA,46
54
- hilda-2.0.16.dist-info/top_level.txt,sha256=TVD7l1WkE1noT866YqPFhiQnjYCYZM5Xz54v_3EYpnI,11
55
- hilda-2.0.16.dist-info/RECORD,,
52
+ hilda-3.0.1.dist-info/LICENSE,sha256=M-LVJ0AFAYB82eueyl8brh-QLPe-iLNVgbCi79-3TDo,1078
53
+ hilda-3.0.1.dist-info/METADATA,sha256=S0GZw7zb-oTZXZGaW_zD_eBq0ba3EaA6Zs3OSZAI3qI,23354
54
+ hilda-3.0.1.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
55
+ hilda-3.0.1.dist-info/entry_points.txt,sha256=9n3O3j6V3XnVR_GcFqCWNgRAbalfukTSW2WvghsLVmA,46
56
+ hilda-3.0.1.dist-info/top_level.txt,sha256=TVD7l1WkE1noT866YqPFhiQnjYCYZM5Xz54v_3EYpnI,11
57
+ hilda-3.0.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5