hilda 2.0.14__py3-none-any.whl → 2.0.16__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/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.0.14'
16
- __version_tuple__ = version_tuple = (2, 0, 14)
15
+ __version__ = version = '2.0.16'
16
+ __version_tuple__ = version_tuple = (2, 0, 16)
hilda/hilda_client.py CHANGED
@@ -356,6 +356,15 @@ class HildaClient:
356
356
  """
357
357
  return address.po('char *')[1:-1] # strip the ""
358
358
 
359
+ @stop_is_needed
360
+ def peek_std_str(self, address: Symbol) -> str:
361
+ """
362
+ Peek a std::string
363
+ :param address: Address to read the std::string from
364
+ :return: Python string
365
+ """
366
+ return self._std_string(address)
367
+
359
368
  def stop(self, *args) -> None:
360
369
  """ Stop process. """
361
370
  self.debugger.SetAsync(False)
@@ -1200,7 +1209,7 @@ class HildaClient:
1200
1209
  return f'((intptr_t(*)({args_type}))({address}))({args_conv})'
1201
1210
 
1202
1211
  @staticmethod
1203
- def _std_string(value):
1212
+ def _std_string(value: Symbol) -> str:
1204
1213
  if struct.unpack("b", (value + 23).peek(1))[0] >= 0:
1205
1214
  return value.peek_str()
1206
1215
  else:
hilda/launch_lldb.py CHANGED
@@ -167,7 +167,7 @@ class LLDBLaunch(LLDBListenerThread):
167
167
  # Launch(SBTarget self, SBListener listener, char const ** argv, char const ** envp,
168
168
  # char const * stdin_path, char const * stdout_path, char const * stderr_path, char const * working_directory,
169
169
  # uint32_t launch_flags, bool stop_at_entry, SBError error) -> SBProcess
170
- logger.debug(f'Lunching process {self.exec_path}')
170
+ logger.debug(f'Launching process {self.exec_path}')
171
171
  return self.target.Launch(self.listener, self.argv, self.envp,
172
172
  self.stdin, self.stdout, self.stderr, self.working_directory,
173
173
  self.flags, True,
@@ -0,0 +1,285 @@
1
+ from construct import Array, BitsInteger, BitStruct, Bytes, Enum, Flag, Hex, Int32ul, Int64ul, Padding, Struct, Tell
2
+
3
+ from hilda.lldb_importer import lldb
4
+ from hilda.symbol import SymbolFormatField
5
+
6
+ malloc_zone_t = Struct(
7
+ 'RESERVED_1_CFALLOCATOR' / Hex(Int64ul),
8
+ 'RESERVED_2_CFALLOCATOR' / Hex(Int64ul),
9
+ 'size' / SymbolFormatField(lldb.hilda_client),
10
+ 'malloc' / SymbolFormatField(lldb.hilda_client),
11
+ 'calloc' / SymbolFormatField(lldb.hilda_client),
12
+ 'valloc' / SymbolFormatField(lldb.hilda_client),
13
+ 'free' / SymbolFormatField(lldb.hilda_client),
14
+ 'realloc' / SymbolFormatField(lldb.hilda_client),
15
+ 'destroy' / SymbolFormatField(lldb.hilda_client),
16
+ 'zone_name' / SymbolFormatField(lldb.hilda_client),
17
+ 'batch_malloc' / SymbolFormatField(lldb.hilda_client),
18
+ 'batch_free' / SymbolFormatField(lldb.hilda_client),
19
+ 'introspect' / SymbolFormatField(lldb.hilda_client),
20
+ 'version' / SymbolFormatField(lldb.hilda_client),
21
+ 'memalign' / SymbolFormatField(lldb.hilda_client),
22
+ 'free_definite_size' / SymbolFormatField(lldb.hilda_client),
23
+ 'pressure_relief' / SymbolFormatField(lldb.hilda_client),
24
+ 'claimed_address' / SymbolFormatField(lldb.hilda_client),
25
+ 'try_free_default' / SymbolFormatField(lldb.hilda_client),
26
+ 'malloc_with_options' / SymbolFormatField(lldb.hilda_client),
27
+ 'malloc_type_malloc' / SymbolFormatField(lldb.hilda_client),
28
+ 'malloc_type_calloc' / SymbolFormatField(lldb.hilda_client),
29
+ 'malloc_type_realloc' / SymbolFormatField(lldb.hilda_client),
30
+ 'malloc_type_memalign' / SymbolFormatField(lldb.hilda_client),
31
+ 'malloc_type_malloc_with_options' / SymbolFormatField(lldb.hilda_client),
32
+ )
33
+
34
+ nanov2_statistics_t = Struct(
35
+ 'allocated_regions' / Hex(Int32ul),
36
+ 'region_addresses_clhashes' / Hex(Int32ul),
37
+ # 'size_class_statistics' / Array(16, nanov2_size_class_statistics)
38
+ )
39
+
40
+ nanozonev2_s = Struct(
41
+ 'address' / Tell,
42
+ 'basic_zone' / malloc_zone_t,
43
+ # pad used to mprotect the first page
44
+ Padding(0x4000 - malloc_zone_t.sizeof()+32),
45
+ # metadata of arena blocks
46
+ 'current_block' / Hex(Int64ul),
47
+ # current_block_lock omitted
48
+ Padding(0x2fd4),
49
+ 'delegate_allocations' / Hex(Int32ul),
50
+ 'debug_flags' / Hex(Int64ul),
51
+ 'aslr_cookie' / Hex(Int64ul),
52
+ 'aslr_cookie_aligned' / Hex(Int64ul),
53
+ 'slot_freelist_cookies' / Hex(Int64ul),
54
+ 'helper_zone' / Hex(Int64ul),
55
+ 'block_lock' / Hex(Int32ul),
56
+ 'regions_lock' / Hex(Int32ul),
57
+ 'first_region_base_ptr' / Hex(Int64ul),
58
+ 'current_region_next_arena' / Hex(Int64ul),
59
+ 'madvise_lock' / Hex(Int64ul),
60
+ 'nanov2_statistics_t' / nanov2_statistics_t
61
+ )
62
+
63
+ nanov2_size_class_statistics = Struct(
64
+ 'total_allocations' / Hex(Int64ul),
65
+ 'total_frees' / Hex(Int64ul),
66
+ 'madvised_blocks' / Hex(Int64ul),
67
+ 'madvise_races' / Hex(Int64ul),
68
+ )
69
+
70
+
71
+ class NanoV2Zone:
72
+
73
+ def __init__(self, nanov2_base_addr, helper_zone_ptr):
74
+ self.nanov2_base_addr = nanov2_base_addr
75
+ self.nanov2_struct = nanozonev2_s.parse_stream(self.nanov2_base_addr)
76
+ if not self._sanity_check(helper_zone_ptr):
77
+ self.nanov2_struct = None
78
+
79
+ def _sanity_check(self, helper_zone_ptr):
80
+ return helper_zone_ptr == int(str(self.nanov2_struct.helper_zone), 16)
81
+
82
+ def get_nanov2_struct(self):
83
+ return self.nanov2_struct
84
+
85
+
86
+ class NanoV2Arena:
87
+ # You would have to iterate for 64 times to dump everything. But not going to dump 64MB...
88
+ # Found at nanov2_malloc.c
89
+ size_per_slot = [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256]
90
+ blocks_per_size = [2, 10, 11, 10, 5, 3, 3, 4, 3, 2, 2, 2, 2, 2, 1, 2]
91
+ slots_per_size = [1024, 512, 341, 256, 204, 170, 146, 128, 113, 102, 93, 85, 78, 73, 68, 64]
92
+
93
+ def __init__(self, arena_base_addr):
94
+ self.nanov2_arena_struct = Struct(
95
+ # Note that this only parses 1 CPU memblock (1MB). Modify it to be 64.
96
+ *[\
97
+ f"blocks_{idx}" / Array(self.blocks_per_size[idx], \
98
+ Struct('content' / \
99
+ Array(self.slots_per_size[idx], \
100
+ Struct('Q' / Bytes(self.size_per_slot[idx]) \
101
+ )\
102
+ )\
103
+ ))\
104
+ for idx in range(len(self.blocks_per_size))\
105
+ ]
106
+ )
107
+ self.arena_struct = self.nanov2_arena_struct.parse_stream(arena_base_addr)
108
+
109
+ def get_arena_struct(self):
110
+ return self.arena_struct
111
+
112
+
113
+ class NanoV2ArenaMetadataBlock:
114
+ # This is used by libmalloc to store the metadata of the arena blocks which is used during allocations.
115
+ # It is a matrix because we have a list of block sizes * CPU_NUMBER.
116
+
117
+ NEXT_SLOT = Enum(BitsInteger(11),
118
+ SLOT_NULL=0,
119
+ SLOT_GUARD=0x7fa,
120
+ SLOT_BUMP=0x7fb,
121
+ SLOT_FULL=0x7fc,
122
+ SLOT_CAN_MADVISE=0x7fd,
123
+ SLOT_MADVISING=0x7fe,
124
+ SLOT_MADVISED=0x7ff
125
+ )
126
+
127
+ block_meta_t = BitStruct(
128
+ 'in_use' / Flag,
129
+ 'gen_count' / Hex(BitsInteger(10)),
130
+ 'free_count' / Hex(BitsInteger(10)),
131
+ 'next_slot' / NEXT_SLOT,
132
+ )
133
+
134
+ def __init__(self, curr_block_addr):
135
+ self.nanov2_arena_metablock_t = Struct(
136
+ # We can't directly parse the block_meta with the CStruct.
137
+ # It has to be Int32ul first because BitStruct does not handle unalignment properly.
138
+ "arena_block_meta" / Array(4096, Hex(Int32ul))
139
+ )
140
+ self.curr_block_addr = curr_block_addr
141
+ self.arena_metadata_block = self.nanov2_arena_metablock_t.parse_stream(curr_block_addr)
142
+
143
+ def dump_arena_metadata_block(self):
144
+ block_idx = 0
145
+ for meta_block in self.arena_metadata_block.arena_block_meta:
146
+ hex_meta_contents = str(meta_block)[2:]
147
+ block_meta_struct = self.block_meta_t.parse(bytes.fromhex(hex_meta_contents))
148
+ if block_meta_struct.in_use:
149
+ print(f"Arena block index {block_idx} (CPU {int(block_idx / 64) - 1}): next: {block_meta_struct.next_slot}")
150
+ block_idx = block_idx + 1
151
+
152
+
153
+ RACK_TYPE = Enum(Int32ul,
154
+ RACK_TYPE_NONE=0,
155
+ RACK_TYPE_TINY=1,
156
+ RACK_TYPE_SMALL=2,
157
+ RACK_TYPE_MEDIUM=3
158
+ )
159
+
160
+ region_hash_generation_t = Struct(
161
+ 'num_regions_allocated' / Hex(Int64ul),
162
+ 'num_regions_allocated_shift' / Hex(Int64ul),
163
+ 'hashed_regions_ptr' / Hex(Int64ul),
164
+ 'nextgen_ptr' / Hex(Int64ul),
165
+ )
166
+
167
+ rack_s = Struct(
168
+ # Keep in mind this struct is MALLOC_CACHE_ALIGN(128) aligned.
169
+ 'address' / Tell,
170
+ 'region_lock' / Hex(Int32ul),
171
+ 'type' / RACK_TYPE,
172
+ 'num_regions' / Hex(Int64ul),
173
+ 'num_regions_dealloc' / Hex(Int64ul),
174
+ 'region_generation_ptr' / Hex(Int64ul),
175
+ 'rg' / Array(2, region_hash_generation_t),
176
+ 'initial_regions' / Array(64, Hex(Int64ul)),
177
+ 'num_magazines' / Hex(Int32ul),
178
+ 'num_magazines_mask' / Hex(Int32ul),
179
+ 'num_magazines_mask_shift' / Hex(Int32ul),
180
+ 'debug_flags' / Hex(Int32ul),
181
+ 'magazines' / Hex(Int64ul),
182
+ 'cookie' / Hex(Int64ul),
183
+ 'last_madvise' / Hex(Int64ul),
184
+ )
185
+
186
+ szone_t = Struct(
187
+ 'address' / Tell,
188
+ 'basic_zone' / malloc_zone_t,
189
+ # it seems like the offset is 0x4068 from the start of the basic_zone to the tiny rack
190
+ Padding(0x4000 - malloc_zone_t.sizeof() + 0x68),
191
+ 'cpu_id_key' / Hex(Int64ul),
192
+ 'debug_flags' / Hex(Int64ul),
193
+ 'log_address' / Hex(Int64ul),
194
+ 'tiny_rack' / rack_s,
195
+ Padding(0x78),
196
+ 'small_rack' / rack_s,
197
+ Padding(0x78),
198
+ 'medium_rack' / rack_s,
199
+ 'large_szone_lock' / Hex(Int32ul),
200
+ 'num_large_objects_in_use' / Hex(Int32ul),
201
+ 'num_large_entries' / Hex(Int32ul),
202
+ 'large_entries' / Hex(Int64ul),
203
+ 'num_bytes_in_large_objects' / Hex(Int64ul),
204
+ # for macOS, CONFIG_LARGE_CACHE is True. For iOS is False (TODO)
205
+ )
206
+
207
+
208
+ class HelperZone:
209
+ def __init__(self, helper_zone_ptr):
210
+ self.szone_struct = szone_t.parse_stream(helper_zone_ptr)
211
+
212
+ def get_helper_zone(self):
213
+ return self.szone_struct
214
+
215
+
216
+ def _get_nanov2_zone():
217
+ hilda = lldb.hilda_client
218
+ default_nanozone_ptr = hilda.symbols.malloc_zones[0][0]
219
+ # we need the helper_zone_ptr to perform a sanity check on the parsing.
220
+ helper_zone_ptr = hilda.symbols.malloc_zones[0][1]
221
+ return NanoV2Zone(default_nanozone_ptr, helper_zone_ptr)
222
+
223
+
224
+ def dump_helper_zone():
225
+ hilda = lldb.hilda_client
226
+ helper_zone_ptr = hilda.symbols.malloc_zones[0][1]
227
+ helper_zone = HelperZone(helper_zone_ptr)
228
+ print(helper_zone.get_helper_zone())
229
+
230
+
231
+ def dump_nanov2_zone():
232
+ nano_zone_class = _get_nanov2_zone()
233
+ print(nano_zone_class.get_nanov2_struct())
234
+
235
+
236
+ def dump_used_arena():
237
+ """
238
+ Arena first block is the metadata
239
+ Afterwards, arena consists of 64 logical blocks (1 per each CPU) that each of them is 1MB.
240
+ Each CPU mem block is -> blocks_per_size = [2,10,11,10,5,3,3,4,3,2,2,2,2,2,1,2] -> 64 blocks
241
+ Something like this:
242
+
243
+ (remember, 1 block is 16k)
244
+ ----------------------------------
245
+ ARENA_METADATA_BLOCK - 16K
246
+ ----------------------------------
247
+ (it is inline, this arrow is not a ptr. just drawing purposes.)
248
+ CPU_0_MEM_BLOCK - 1MB -----------> | BLOCK_16 * 2
249
+ BLOCK_32 * 10
250
+ BLOCK_48 * 11
251
+ .... (check blocks_per_size)
252
+ ----------------------------------
253
+ CPU_1_MEM_BLOCK - 1MB
254
+ ----------------------------------
255
+ CPU_X_MEM_BLOCK - 1MB (There are up to 64!)
256
+ ----------------------------------
257
+
258
+ Which makes an arena 64CPU mem blocks * 1 mb = 64mb + arena metadata block = 65mb.
259
+ A region consists of 8 arenas which results in 64mb * 8 = 512mb (no metadata accounted)
260
+ """
261
+
262
+ # Note there can be up to NANOV2_ARENAS_PER_REGION arenas (8). We will only dump 1 of them.
263
+ hilda = lldb.hilda_client
264
+ nano_zone_class = _get_nanov2_zone()
265
+ # arena base addr is always 0x0000600000000000 + aslr_cookie_enabled + 0x4000 (first block is the arena metablock)
266
+ first_region_base_ptr_int = int(str(nano_zone_class.get_nanov2_struct().first_region_base_ptr), 16)
267
+ aslr_cookie_aligned_int = int(str(nano_zone_class.get_nanov2_struct().aslr_cookie_aligned), 16)
268
+ arena_addr = first_region_base_ptr_int + aslr_cookie_aligned_int + 0x4000
269
+ nanov2_arena_struct = NanoV2Arena(hilda.symbol(arena_addr))
270
+ with open('/tmp/arena_contents.txt', 'w') as arena_dump_file:
271
+ print("Dumping 1MB of arena (CPU_0 mem block) contents into /tmp/arena_contents.txt.")
272
+ arena_dump_file.write(str(nanov2_arena_struct.get_arena_struct()))
273
+
274
+
275
+ def dump_nanov2_block_metadata():
276
+ # The metadata block is the first logical block in the arena. Arena metadata is at arena_addr + aslr_cookie_aligned
277
+ hilda = lldb.hilda_client
278
+ nano_zone_class = _get_nanov2_zone()
279
+ first_region_base_ptr_int = int(str(nano_zone_class.get_nanov2_struct().first_region_base_ptr), 16)
280
+ aslr_cookie_aligned_int = int(str(nano_zone_class.get_nanov2_struct().aslr_cookie_aligned), 16)
281
+ metadata_addr = first_region_base_ptr_int + aslr_cookie_aligned_int
282
+ print(f"Arena metadata can be found at {metadata_addr:x}")
283
+ current_block_symbol = hilda.symbol(metadata_addr)
284
+ meta_block_class = NanoV2ArenaMetadataBlock(current_block_symbol)
285
+ meta_block_class.dump_arena_metadata_block()
hilda/symbol.py CHANGED
@@ -139,6 +139,9 @@ class Symbol(int):
139
139
  def peek_str(self) -> str:
140
140
  return self._client.peek_str(self)
141
141
 
142
+ def peek_std_str(self) -> str:
143
+ return self._client.peek_std_str(self)
144
+
142
145
  def monitor(self, **args):
143
146
  return self._client.monitor(self, **args)
144
147
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: hilda
3
- Version: 2.0.14
3
+ Version: 2.0.16
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>
@@ -41,12 +41,12 @@ Requires-Python: >=3.9
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
43
  Requires-Dist: tqdm
44
- Requires-Dist: docstring-parser
44
+ Requires-Dist: docstring_parser
45
45
  Requires-Dist: coloredlogs
46
46
  Requires-Dist: hexdump
47
47
  Requires-Dist: ipython
48
48
  Requires-Dist: click
49
- Requires-Dist: objc-types-decoder
49
+ Requires-Dist: objc_types_decoder
50
50
  Requires-Dist: construct
51
51
  Requires-Dist: pymobiledevice3
52
52
  Requires-Dist: keystone-engine
@@ -185,6 +185,8 @@ Here is a gist of methods you can access from `p`:
185
185
  - Read data at given address
186
186
  - `peek_str`
187
187
  - Peek a buffer till null termination
188
+ - `peek_std_str`
189
+ - Peek a `std::string`
188
190
  - `stop`
189
191
  - Stop process.
190
192
  - `cont`
@@ -3,19 +3,19 @@ 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=m1KQwr9BxzbCkMceuLAJj8OgCTUeNFGjPpEMFS8xjSA,413
6
+ hilda/_version.py,sha256=Rj6OwV2GJpyCTs0m5bHo9CElWBJTCnmOdBSPUYg9oj4,413
7
7
  hilda/cli.py,sha256=PCjrI7GrERIrZCODJYmPt6eyl-nPYZviTS8fBG3oIjM,3618
8
8
  hilda/common.py,sha256=El-ih7cvCv9PJ5OWb1jkCbh4GuaRD6gqlrFC5gyY-TE,498
9
9
  hilda/exceptions.py,sha256=8L1OvOqns4O4ieiH4YlrMbZkk_PvuyCq4UyqFAodkF8,2042
10
10
  hilda/hilda_ascii_art.html,sha256=-9YCjAKdGbjtdd6uoKrxkkcJq7j16r4dGka2bZ27b4o,120119
11
- hilda/hilda_client.py,sha256=7HCMl1zColMaqBwyZJ4AY8J1ON7wqEhN7ALhF8qcSlg,48021
12
- hilda/launch_lldb.py,sha256=SKUdUDvFn5riARHzlRScAztgn4zz0piqgdaAdA2drHs,8032
11
+ hilda/hilda_client.py,sha256=jJ1vKtvSM1Hfx9Hbtr2coRqQnpctuBtBXy1HTXEa-RI,48293
12
+ hilda/launch_lldb.py,sha256=gU1iJmxuH7w5HV_cy1igv-JageyQn2dmqSxx8vkpY0k,8033
13
13
  hilda/lldb_entrypoint.py,sha256=vTiClzfiTtjorlxEfIsI-W657KEGobx74qDhaZ8nPhM,1007
14
14
  hilda/lldb_importer.py,sha256=TCGpAWwiBuyNRsbgcYawiqm35t8XQLCJwoOfEqyBeik,526
15
15
  hilda/objective_c_class.py,sha256=arIgABZxqsLyo9Q6kyw-Sujm5j-89QUOjS0njjBcGo8,11716
16
16
  hilda/objective_c_symbol.py,sha256=lIZHef5iZe3AeUsK0uIsDtFnzSM-Ad6i2wfdj9DwLUM,8269
17
17
  hilda/registers.py,sha256=-9kk1MuKnWlJ0Z8zZ2RPV9nGRDtX1GXhCSkEvfnCktA,848
18
- hilda/symbol.py,sha256=4309OwrnA7JQA3V3lfR_u8NAEdjkU6cEca9lxwioX3U,7452
18
+ hilda/symbol.py,sha256=yv8s0vQ6Z0ZoROeVE4RVaW0LFCyACZnFgp0QC6j05nI,7535
19
19
  hilda/symbols_jar.py,sha256=Vqdv6iH92P6aSfcz5XiR0FbNRqKuUu48mi-GxvPr32w,6504
20
20
  hilda/ipython_extensions/events.py,sha256=w_4V8FoJJMarWArEE8uzb2UXk1mqfslmI7XCyVb_XuE,1976
21
21
  hilda/ipython_extensions/keybindings.py,sha256=Ai9wHCla6HhgZGGxc0UEOCYODcavyef_zzUC9A9GcTE,1081
@@ -31,6 +31,7 @@ hilda/snippets/boringssl.py,sha256=0mby7PRhmrfbEKc5nCTWALG5O7VoPk4473UiZOdnpdA,7
31
31
  hilda/snippets/collections.py,sha256=8UlJKKLV9ba1IUe9G6qAGZzweeHVVgj_HDf0QUYOTWs,417
32
32
  hilda/snippets/dyld.py,sha256=cTasVlew2doJGI10XwOFBSEXf-RpVRok-ngFTfMy6QA,2186
33
33
  hilda/snippets/fs_utils.py,sha256=lxznKJiV_60RZmGORqHm18-ACCf4VOpNC5rveh0kemc,422
34
+ hilda/snippets/libmalloc.py,sha256=2HL7GESDRjV9R3Hz1Yafu5bJ87_kYNi64MPpHr8wW_g,11674
34
35
  hilda/snippets/remotepairingd.py,sha256=w7SYctpKw3B56ZP26n4Ap5_hz6VmZiUbe8CrTmZ1JWI,5849
35
36
  hilda/snippets/syslog.py,sha256=8qhYHKTElzWifqYAwt72iQ57wf1n0F_au2Vl2L8NPOc,294
36
37
  hilda/snippets/uuid.py,sha256=ttw-rq2Wshm7UMZXd5uYP37bi8G_ZE4XcXJbsYIgp1c,273
@@ -46,9 +47,9 @@ hilda/snippets/macho/macho_load_commands.py,sha256=vUWfFM2H6o8dMglXV7rHgh-EMTzS0
46
47
  hilda/ui/colors.json,sha256=f-ITquY3IInQreviTy23JfmxfJrGM1_MivACf1GKGqM,262
47
48
  hilda/ui/ui_manager.py,sha256=BmzI1sBx0PYCQDlB9Al7wsTEAMJxaJ7NW0DS4C7g5-0,2265
48
49
  hilda/ui/views.py,sha256=bzClOgKirKYs6nhsNRXpkGNIg3oIOmFb659GLWrlTdo,7792
49
- hilda-2.0.14.dist-info/LICENSE,sha256=M-LVJ0AFAYB82eueyl8brh-QLPe-iLNVgbCi79-3TDo,1078
50
- hilda-2.0.14.dist-info/METADATA,sha256=N_-aSr6ezU8eTTyYzq2UgYbqlwMKaAj3r_bV55Zefgg,23378
51
- hilda-2.0.14.dist-info/WHEEL,sha256=OVMc5UfuAQiSplgO0_WdW7vXVGAt9Hdd6qtN4HotdyA,91
52
- hilda-2.0.14.dist-info/entry_points.txt,sha256=9n3O3j6V3XnVR_GcFqCWNgRAbalfukTSW2WvghsLVmA,46
53
- hilda-2.0.14.dist-info/top_level.txt,sha256=TVD7l1WkE1noT866YqPFhiQnjYCYZM5Xz54v_3EYpnI,11
54
- hilda-2.0.14.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.2.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5