dissect.util 3.24.dev1__cp310-abi3-manylinux_2_28_s390x.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.

Potentially problematic release.


This version of dissect.util might be problematic. Click here for more details.

Files changed (43) hide show
  1. dissect/util/__init__.py +20 -0
  2. dissect/util/_build.py +17 -0
  3. dissect/util/_native/__init__.pyi +3 -0
  4. dissect/util/_native/compression/__init__.pyi +3 -0
  5. dissect/util/_native/compression/lz4.pyi +7 -0
  6. dissect/util/_native/compression/lzo.pyi +3 -0
  7. dissect/util/_native/hash/__init__.py +3 -0
  8. dissect/util/_native/hash/crc32c.py +2 -0
  9. dissect/util/_native.abi3.so +0 -0
  10. dissect/util/compression/__init__.py +45 -0
  11. dissect/util/compression/lz4.py +95 -0
  12. dissect/util/compression/lzbitmap.py +130 -0
  13. dissect/util/compression/lzfse.py +467 -0
  14. dissect/util/compression/lznt1.py +92 -0
  15. dissect/util/compression/lzo.py +118 -0
  16. dissect/util/compression/lzvn.py +241 -0
  17. dissect/util/compression/lzxpress.py +80 -0
  18. dissect/util/compression/lzxpress_huffman.py +184 -0
  19. dissect/util/compression/sevenbit.py +77 -0
  20. dissect/util/compression/xz.py +112 -0
  21. dissect/util/cpio.py +226 -0
  22. dissect/util/encoding/__init__.py +0 -0
  23. dissect/util/encoding/surrogateescape.py +21 -0
  24. dissect/util/exceptions.py +6 -0
  25. dissect/util/hash/__init__.py +28 -0
  26. dissect/util/hash/crc32.py +55 -0
  27. dissect/util/hash/crc32c.py +60 -0
  28. dissect/util/hash/jenkins.py +102 -0
  29. dissect/util/ldap.py +237 -0
  30. dissect/util/plist.py +156 -0
  31. dissect/util/sid.py +81 -0
  32. dissect/util/stream.py +671 -0
  33. dissect/util/tools/__init__.py +0 -0
  34. dissect/util/tools/dump_nskeyedarchiver.py +61 -0
  35. dissect/util/ts.py +295 -0
  36. dissect/util/xmemoryview.py +117 -0
  37. dissect_util-3.24.dev1.dist-info/METADATA +89 -0
  38. dissect_util-3.24.dev1.dist-info/RECORD +43 -0
  39. dissect_util-3.24.dev1.dist-info/WHEEL +5 -0
  40. dissect_util-3.24.dev1.dist-info/entry_points.txt +2 -0
  41. dissect_util-3.24.dev1.dist-info/licenses/COPYRIGHT +5 -0
  42. dissect_util-3.24.dev1.dist-info/licenses/LICENSE +201 -0
  43. dissect_util-3.24.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,61 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from typing import Any
5
+
6
+ from dissect.util.plist import NSKeyedArchiver, NSObject
7
+
8
+
9
+ def main() -> None:
10
+ parser = argparse.ArgumentParser()
11
+ parser.add_argument("file", type=argparse.FileType("rb"), help="NSKeyedArchiver plist file to dump")
12
+ args = parser.parse_args()
13
+
14
+ with args.file as fh:
15
+ try:
16
+ obj = NSKeyedArchiver(fh)
17
+ except ValueError as e:
18
+ parser.exit(str(e))
19
+
20
+ print(obj)
21
+ print_object(obj.top)
22
+
23
+
24
+ def print_object(obj: Any, indent: int = 0, seen: set | None = None) -> None:
25
+ if seen is None:
26
+ seen = set()
27
+
28
+ try:
29
+ if obj in seen:
30
+ print(fmt(f"Recursive -> {obj}", indent))
31
+ return
32
+ except Exception:
33
+ pass
34
+
35
+ if isinstance(obj, list):
36
+ for i, v in enumerate(obj):
37
+ print(fmt(f"[{i}]:", indent))
38
+ print_object(v, indent + 1, seen)
39
+
40
+ elif isinstance(obj, dict | NSObject):
41
+ if isinstance(obj, NSObject):
42
+ print(fmt(obj, indent))
43
+ try:
44
+ seen.add(obj)
45
+ except TypeError:
46
+ pass
47
+
48
+ for k in sorted(obj.keys()):
49
+ print(fmt(f"{k}:", indent + 1))
50
+ print_object(obj[k], indent + 2, seen)
51
+
52
+ else:
53
+ print(fmt(obj, indent))
54
+
55
+
56
+ def fmt(obj: Any, indent: int) -> str:
57
+ return f"{' ' * (indent * 4)}{obj}"
58
+
59
+
60
+ if __name__ == "__main__":
61
+ main()
dissect/util/ts.py ADDED
@@ -0,0 +1,295 @@
1
+ from __future__ import annotations
2
+
3
+ import struct
4
+ from datetime import datetime, timedelta, timezone
5
+
6
+ # Python on Windows and WASM (Emscripten) have problems calculating timestamps before 1970 (Unix epoch)
7
+ # Calculating relatively from the epoch is required on these platforms
8
+ # This method is slower, so we split the implementation between Windows, WASM and other platforms
9
+ # This used to be a platform comparison, but that was not reliable enough, so ducktype it instead
10
+ try:
11
+ datetime.fromtimestamp(-6969696969, tz=timezone.utc)
12
+
13
+ def _calculate_timestamp(ts: float) -> datetime:
14
+ """Calculate timestamps normally."""
15
+ return datetime.fromtimestamp(ts, tz=timezone.utc)
16
+ except (OSError, OverflowError):
17
+ _EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc)
18
+
19
+ def _calculate_timestamp(ts: float) -> datetime:
20
+ """Calculate timestamps relative from Unix epoch."""
21
+ return _EPOCH + timedelta(seconds=ts)
22
+
23
+
24
+ def now() -> datetime:
25
+ """Return an aware datetime object of the current time in UTC."""
26
+ return datetime.now(timezone.utc)
27
+
28
+
29
+ def unix_now() -> int:
30
+ """Return a Unix timestamp of the current time."""
31
+ return to_unix(now())
32
+
33
+
34
+ def unix_now_ms() -> int:
35
+ """Return a Unix millisecond timestamp of the current time."""
36
+ return to_unix_ms(now())
37
+
38
+
39
+ def unix_now_us() -> int:
40
+ """Return a Unix microsecond timestamp of the current time."""
41
+ return to_unix_us(now())
42
+
43
+
44
+ def unix_now_ns() -> int:
45
+ """Return a Unix nanosecond timestamp of the current time."""
46
+ return to_unix_ns(now())
47
+
48
+
49
+ def to_unix(dt: datetime) -> int:
50
+ """Converts datetime objects into Unix timestamps.
51
+
52
+ This is a convenience method.
53
+
54
+ Args:
55
+ dt: The datetime object.
56
+
57
+ Returns:
58
+ Unix timestamp from the passed datetime object.
59
+ """
60
+ return int(dt.timestamp())
61
+
62
+
63
+ def to_unix_ms(dt: datetime) -> int:
64
+ """Converts datetime objects into Unix millisecond timestamps.
65
+
66
+ This is a convenience method.
67
+
68
+ Args:
69
+ dt: The datetime object.
70
+
71
+ Returns:
72
+ Unix millisecond timestamp from the passed datetime object.
73
+ """
74
+ return int(dt.timestamp() * 1e3)
75
+
76
+
77
+ def to_unix_us(dt: datetime) -> int:
78
+ """Converts datetime objects into Unix microsecond timestamps.
79
+
80
+ This is a convenience method.
81
+
82
+ Args:
83
+ dt: The datetime object.
84
+
85
+ Returns:
86
+ Unix microsecond timestamp from the passed datetime object.
87
+ """
88
+ return int(dt.timestamp() * 1e6)
89
+
90
+
91
+ def to_unix_ns(dt: datetime) -> int:
92
+ """Converts datetime objects into Unix nanosecond timestamps.
93
+
94
+ This is a convenience method.
95
+
96
+ Args:
97
+ dt: The datetime object.
98
+
99
+ Returns:
100
+ Unix nanosecond timestamp from the passed datetime object.
101
+ """
102
+ return to_unix_us(dt) * 1000
103
+
104
+
105
+ def from_unix(ts: float) -> datetime:
106
+ """Converts Unix timestamps to aware datetime objects in UTC.
107
+
108
+ This is a convenience method.
109
+
110
+ Args:
111
+ ts: The Unix timestamp.
112
+
113
+ Returns:
114
+ Datetime object from the passed timestamp.
115
+ """
116
+ return _calculate_timestamp(ts)
117
+
118
+
119
+ def from_unix_ms(ts: float) -> datetime:
120
+ """Converts Unix timestamps in milliseconds to aware datetime objects in UTC.
121
+
122
+ Args:
123
+ ts: The Unix timestamp in milliseconds.
124
+
125
+ Returns:
126
+ Datetime object from the passed timestamp.
127
+ """
128
+ return from_unix(float(ts) * 1e-3)
129
+
130
+
131
+ def from_unix_us(ts: float) -> datetime:
132
+ """Converts Unix timestamps in microseconds to aware datetime objects in UTC.
133
+
134
+ Args:
135
+ ts: The Unix timestamp in microseconds.
136
+
137
+ Returns:
138
+ Datetime object from the passed timestamp.
139
+ """
140
+ return from_unix(float(ts) * 1e-6)
141
+
142
+
143
+ def from_unix_ns(ts: float) -> datetime:
144
+ """Converts Unix timestamps in nanoseconds to aware datetime objects in UTC.
145
+
146
+ Args:
147
+ ts: The Unix timestamp in nanoseconds.
148
+
149
+ Returns:
150
+ Datetime object from the passed timestamp.
151
+ """
152
+ return from_unix(float(ts) * 1e-9)
153
+
154
+
155
+ def xfstimestamp(seconds: int, nano: int) -> datetime:
156
+ """Converts XFS timestamps to aware datetime objects in UTC.
157
+
158
+ Args:
159
+ seconds: The XFS timestamp seconds component
160
+ nano: The XFS timestamp nano seconds component
161
+ Returns:
162
+ Datetime object from the passed timestamp.
163
+ """
164
+ return _calculate_timestamp(float(seconds) + (1e-9 * nano))
165
+
166
+
167
+ ufstimestamp = xfstimestamp
168
+
169
+
170
+ def wintimestamp(ts: int | tuple[int, int]) -> datetime:
171
+ """Converts Windows ``FILETIME`` timestamps to aware datetime objects in UTC.
172
+
173
+ Args:
174
+ ts: The Windows timestamp integer or a tuple of integers (``dwLowDateTime``, ``dwHighDateTime``)
175
+
176
+ Returns:
177
+ Datetime object from the passed timestamp.
178
+
179
+ Resources:
180
+ - https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
181
+ """
182
+ if isinstance(ts, tuple):
183
+ if len(ts) != 2:
184
+ raise ValueError(f"Expected (dwLowDateTime, dwHighDateTime) tuple but got {ts!r}")
185
+ ts = (ts[1] << 32) + ts[0]
186
+
187
+ return _calculate_timestamp(float(ts) * 1e-7 - 11_644_473_600) # Thanks FireEye
188
+
189
+
190
+ def oatimestamp(ts: float) -> datetime:
191
+ """Converts OLE Automation timestamps to aware datetime objects in UTC.
192
+
193
+ Args:
194
+ ts: The OLE Automation timestamp.
195
+
196
+ Returns:
197
+ Datetime object from the passed timestamp.
198
+ """
199
+ if not isinstance(ts, float):
200
+ # Convert from int to float
201
+ (ts,) = struct.unpack("<d", struct.pack("<Q", ts & 0xFFFFFFFFFFFFFFFF))
202
+ return _calculate_timestamp((ts - 25569) * 86400)
203
+
204
+
205
+ def webkittimestamp(ts: int) -> datetime:
206
+ """Converts WebKit timestamps to aware datetime objects in UTC.
207
+
208
+ Args:
209
+ ts: The WebKit timestamp.
210
+
211
+ Returns:
212
+ Datetime object from the passed timestamp.
213
+ """
214
+ return _calculate_timestamp(float(ts) * 1e-6 - 11644473600)
215
+
216
+
217
+ def cocoatimestamp(ts: int) -> datetime:
218
+ """Converts Apple Cocoa Core Data timestamps to aware datetime objects in UTC.
219
+
220
+ Args:
221
+ ts: The Apple Cocoa Core Data timestamp.
222
+
223
+ Returns:
224
+ Datetime object from the passed timestamp.
225
+ """
226
+ return _calculate_timestamp(float(ts) + 978307200)
227
+
228
+
229
+ def uuid1timestamp(ts: int) -> datetime:
230
+ """Converts UUID version 1 timestamps to aware datetime objects in UTC.
231
+
232
+ UUID v1 timestamps have an epoch of 1582-10-15 00:00:00.
233
+
234
+ Args:
235
+ ts: The UUID version 1 timestamp
236
+
237
+ Returns:
238
+ Datetime object from the passed timestamp.
239
+ """
240
+ return _calculate_timestamp(float(ts) * 1e-7 - 12219292800)
241
+
242
+
243
+ DOS_EPOCH_YEAR = 1980
244
+
245
+
246
+ def dostimestamp(ts: int, centiseconds: int = 0, swap: bool = False) -> datetime:
247
+ """Converts MS-DOS timestamps to naive datetime objects.
248
+
249
+ MS-DOS timestamps are recorded in local time, so we leave it up to the caller to add optional timezone information.
250
+
251
+ References:
252
+ - https://web.archive.org/web/20180311003959/http://www.vsft.com/hal/dostime.htm
253
+
254
+ Args:
255
+ ts: MS-DOS timestamp
256
+ centiseconds: Optional ExFAT centisecond offset. Yes centisecond...
257
+ swap: Optional swap flag if date and time bytes are swapped.
258
+
259
+ Returns:
260
+ Datetime object from the passed timestamp.
261
+ """
262
+ # MS-DOS Date Time Format is actually 2 UINT16_T's first 16 bits are the time, second 16 bits are date
263
+ # the year is an offset of the MS-DOS epoch year, which is 1980
264
+
265
+ if swap:
266
+ year = ((ts >> 9) & 0x7F) + DOS_EPOCH_YEAR
267
+ month = (ts >> 5) & 0x0F
268
+ day = ts & 0x1F
269
+
270
+ hours = (ts >> 27) & 0x1F
271
+ minutes = (ts >> 21) & 0x3F
272
+ seconds = ((ts >> 16) & 0x1F) * 2
273
+ else: # non-swapped way
274
+ year = ((ts >> 25) & 0x7F) + DOS_EPOCH_YEAR
275
+ month = (ts >> 21) & 0x0F
276
+ day = (ts >> 16) & 0x1F
277
+
278
+ hours = (ts >> 11) & 0x1F
279
+ minutes = (ts >> 5) & 0x3F
280
+ seconds = (ts & 0x1F) * 2
281
+
282
+ # Note that according to the standard, centiseconds can be at most 199, so
283
+ # extra_seconds will be at most 1.
284
+ extra_seconds, centiseconds = divmod(centiseconds, 100)
285
+ microseconds = centiseconds * 10000
286
+
287
+ return datetime( # noqa: DTZ001
288
+ year,
289
+ month or 1,
290
+ day or 1,
291
+ hours,
292
+ minutes,
293
+ seconds + extra_seconds,
294
+ microseconds,
295
+ )
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ import struct
4
+ import sys
5
+ from typing import TYPE_CHECKING, Any
6
+
7
+ if TYPE_CHECKING:
8
+ from collections.abc import Iterator
9
+
10
+
11
+ def xmemoryview(view: bytes, format: str) -> memoryview | _xmemoryview:
12
+ """Cast a memoryview to the specified format, including endianness.
13
+
14
+ The regular ``memoryview.cast()`` method only supports host endianness. While that should be fine 99% of the time
15
+ (most of the world runs on little endian systems), we'd rather it be fine 100% of the time. This utility method
16
+ ensures that by transparently converting between endianness if it doesn't match the host endianness.
17
+
18
+ If the host endianness matches the requested endianness, this simply returns a regular ``memoryview.cast()``.
19
+
20
+ See ``memoryview.cast()`` for more details on what that actually does.
21
+
22
+ Args:
23
+ view: The bytes object or memoryview to cast.
24
+ format: The format to cast to in ``struct`` format syntax.
25
+
26
+ Raises:
27
+ ValueError: If the format is invalid.
28
+ TypeError: If the view is of an invalid type.
29
+ """
30
+ if len(format) != 2:
31
+ raise ValueError("Invalid format specification")
32
+
33
+ if isinstance(view, bytes | bytearray):
34
+ view = memoryview(view)
35
+
36
+ if not isinstance(view, memoryview):
37
+ raise TypeError("view must be a memoryview, bytes or bytearray object")
38
+
39
+ endian = format[0]
40
+ view = view.cast(format[1])
41
+
42
+ if (
43
+ endian in ("@", "=")
44
+ or (sys.byteorder == "little" and endian == "<")
45
+ or (sys.byteorder == "big" and endian in (">", "!"))
46
+ ):
47
+ # Native endianness, don't need to do anything
48
+ return view
49
+
50
+ # Non-native endianness
51
+ return _xmemoryview(view, format)
52
+
53
+
54
+ class _xmemoryview: # noqa: N801
55
+ """Wrapper for memoryview that converts between host and a different destination endianness.
56
+
57
+ Args:
58
+ view: The (already casted) memoryview to wrap.
59
+ format: The format to convert to.
60
+ """
61
+
62
+ def __init__(self, view: memoryview, format: str):
63
+ self._format = format
64
+
65
+ fmt = format[1]
66
+ self._view = view
67
+ self._struct_frm = struct.Struct(f"={fmt}")
68
+ self._struct_to = struct.Struct(format)
69
+
70
+ def tolist(self) -> list[int]:
71
+ return self._convert_from_native(self._view.tolist())
72
+
73
+ def _convert_from_native(self, value: list[int] | int) -> int:
74
+ if isinstance(value, list):
75
+ endian = self._format[0]
76
+ fmt = self._format[1]
77
+ pck = f"{len(value)}{fmt}"
78
+ return list(struct.unpack(f"{endian}{pck}", struct.pack(f"={pck}", *value)))
79
+ return self._struct_to.unpack(self._struct_frm.pack(value))[0]
80
+
81
+ def _convert_to_native(self, value: list[int] | int) -> int:
82
+ if isinstance(value, list):
83
+ endian = self._format[0]
84
+ fmt = self._format[1]
85
+ pck = f"{len(value)}{fmt}"
86
+ return list(struct.unpack(f"={pck}", struct.pack(f"{endian}{pck}", *value)))
87
+ return self._struct_frm.unpack(self._struct_to.pack(value))[0]
88
+
89
+ def __getitem__(self, idx: int | slice) -> int | bytes:
90
+ value = self._view[idx]
91
+ if isinstance(idx, int):
92
+ return self._convert_from_native(value)
93
+ if isinstance(idx, slice):
94
+ return _xmemoryview(self._view[idx], self._format)
95
+
96
+ raise TypeError("Invalid index type")
97
+
98
+ def __setitem__(self, idx: int | slice, value: list[int] | int) -> None:
99
+ if isinstance(idx, int | slice):
100
+ self._view[idx] = self._convert_to_native(value)
101
+ else:
102
+ raise TypeError("Invalid index type")
103
+
104
+ def __len__(self) -> int:
105
+ return len(self._view)
106
+
107
+ def __eq__(self, other: memoryview | _xmemoryview) -> bool:
108
+ if isinstance(other, _xmemoryview):
109
+ other = other._view
110
+ return self._view.__eq__(other)
111
+
112
+ def __iter__(self) -> Iterator[int]:
113
+ for value in self._view:
114
+ yield self._convert_from_native(value)
115
+
116
+ def __getattr__(self, attr: str) -> Any:
117
+ return getattr(self._view, attr)
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: dissect.util
3
+ Version: 3.24.dev1
4
+ Summary: A Dissect module implementing various utility functions for the other Dissect modules
5
+ Author-email: Dissect Team <dissect@fox-it.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: homepage, https://dissect.tools
8
+ Project-URL: documentation, https://docs.dissect.tools/en/latest/projects/dissect.util
9
+ Project-URL: repository, https://github.com/fox-it/dissect.util
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Information Technology
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Internet :: Log Analysis
17
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
+ Classifier: Topic :: Security
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.10.0
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ License-File: COPYRIGHT
24
+ Dynamic: license-file
25
+
26
+ # dissect.util
27
+
28
+ A Dissect module implementing various utility functions for the other Dissect modules. For more information, please see
29
+ [the documentation](https://docs.dissect.tools/en/latest/projects/dissect.util/index.html).
30
+
31
+ ## Requirements
32
+
33
+ This project is part of the Dissect framework and requires Python.
34
+
35
+ Information on the supported Python versions can be found in the Getting Started section of [the documentation](https://docs.dissect.tools/en/latest/index.html#getting-started).
36
+
37
+ ## Installation
38
+
39
+ `dissect.util` is available on [PyPI](https://pypi.org/project/dissect.util/).
40
+
41
+ ```bash
42
+ pip install dissect.util
43
+ ```
44
+
45
+ `dissect.util` includes both a pure Python implementation as well as a faster native Rust implementation of the LZ4 and LZO decompression algorithms.
46
+ Pre-build wheels are available for most common platforms and the native implementation will automatically be used.
47
+ In the rare case that a pre-build wheel is not available, the pure Python implementation will automatically be used instead.
48
+ If you wish to build your own wheel in the case a pre-build one is not available for your platform, you can do so by running the following command:
49
+
50
+ ```bash
51
+ tox -e build-native
52
+ ```
53
+
54
+ Note that you'll need to bring your own Rust toolchain for the target platform you wish to build a wheel for. For example, using [rustup](https://rustup.rs).
55
+
56
+ ## Build and test instructions
57
+
58
+ This project uses `tox` to build source and wheel distributions. Run the following command from the root folder to build
59
+ these:
60
+
61
+ ```bash
62
+ tox -e build
63
+ ```
64
+
65
+ The build artifacts can be found in the `dist/` directory.
66
+
67
+ `tox` is also used to run linting and unit tests in a self-contained environment. To run both linting and unit tests
68
+ using the default installed Python version, run:
69
+
70
+ ```bash
71
+ tox
72
+ ```
73
+
74
+ For a more elaborate explanation on how to build and test the project, please see [the
75
+ documentation](https://docs.dissect.tools/en/latest/contributing/tooling.html).
76
+
77
+ ## Contributing
78
+
79
+ The Dissect project encourages any contribution to the codebase. To make your contribution fit into the project, please
80
+ refer to [the development guide](https://docs.dissect.tools/en/latest/contributing/developing.html).
81
+
82
+ ## Copyright and license
83
+
84
+ Dissect is released as open source by Fox-IT (<https://www.fox-it.com>) part of NCC Group Plc
85
+ (<https://www.nccgroup.com>).
86
+
87
+ Developed by the Dissect Team (<dissect@fox-it.com>) and made available at <https://github.com/fox-it/dissect>.
88
+
89
+ License terms: Apache License 2.0 (<https://www.apache.org/licenses/LICENSE-2.0>). For more information, see the LICENSE file.
@@ -0,0 +1,43 @@
1
+ dissect/util/__init__.py,sha256=XtK2Uyo6seLbMNm8mGXFsDUkFOemeCWl8MENC0VjRYA,301
2
+ dissect/util/_build.py,sha256=jSs4jBKGYemptGYeuDYlI64ovIHfm8giMPsLJuEid9o,625
3
+ dissect/util/_native.abi3.so,sha256=TIrUPZXhfxYQCD0H6GcozBCGGIe-3fGa1WMCbnXgiRs,546792
4
+ dissect/util/cpio.py,sha256=epeCGfqeCglP1VVFjKvupzuSvI1DPjZdkgbGAo1R8-8,7576
5
+ dissect/util/exceptions.py,sha256=vkoy9zXcx8U6K4prI5Cqu1mFndizIeIihAfR6DDj44Q,75
6
+ dissect/util/ldap.py,sha256=gykOupKh_MqtcXBGyYfhs7Ye3gYdxc9rhtngbXexeKo,7364
7
+ dissect/util/plist.py,sha256=cuOP1GQLpF2qC71jYGBXVxCWSWwi3LL92sHbn4AEBaA,4551
8
+ dissect/util/sid.py,sha256=ijrNQ9u1NFTOq1-Pr0m1dbS7kDOnYBq5EjzrdpD5Lss,2598
9
+ dissect/util/stream.py,sha256=M7H2Fg6tQtqhaVVaAkOpve7cbHdzW_g4tGOt6cZx_EA,23113
10
+ dissect/util/ts.py,sha256=YqVjHFREnNhwTnR3ap7zv6MOUybo-U74LrhBLA2BpCc,8203
11
+ dissect/util/xmemoryview.py,sha256=nTNLbb2Cuzjj_BKEmveGTBT314VnV084rkteKBVxw5c,4085
12
+ dissect/util/_native/__init__.pyi,sha256=aJkXNIvWI6oiXHluvksHddJ2y_sSz9r94oMp-ogyRIg,86
13
+ dissect/util/_native/compression/__init__.pyi,sha256=GjdgmQQBe-vxGBD1x6g3pzoqbFiYesD7vz3BcK1NGfQ,80
14
+ dissect/util/_native/compression/lz4.pyi,sha256=AGMzCY0GwYC7NwN9KIQOyveftuG5_qEGCt1gXREZ4VM,177
15
+ dissect/util/_native/compression/lzo.pyi,sha256=IdW_7Izgsmm213vRe-69qSeHFHCD3xwx-XMORPtQgPY,120
16
+ dissect/util/_native/hash/__init__.py,sha256=MdStvZya1AO2ct-qgL633RGcLdmJmQiXOVlpoHQe-7Y,67
17
+ dissect/util/_native/hash/crc32c.py,sha256=6BEBv5XK2ih_qxFnpCP0EjEZCbA_y-ppSgrjThBWViY,98
18
+ dissect/util/compression/__init__.py,sha256=EAr73iW2x8lGLJzNn2NQlboiTzTPrUus7WPF0pxlW_k,1281
19
+ dissect/util/compression/lz4.py,sha256=3Tki0-fcNsnvv9xhE-JpLU0d0-yW0JbtKt6OEAGsc6c,2751
20
+ dissect/util/compression/lzbitmap.py,sha256=2vC3TJe-uYiFKOetOAL5W5uu6gjvHbQZ9u92AftlNpE,4500
21
+ dissect/util/compression/lzfse.py,sha256=1jJd_UuyEzGi48_JVNzlgGf_SGyArnfM-qvUv_WRpgM,16105
22
+ dissect/util/compression/lznt1.py,sha256=nBzy86iWRb5c-JXESuClZPme5CJ6RJIory31YWGKbE4,2683
23
+ dissect/util/compression/lzo.py,sha256=CbSwR9vmVHjCLCfRejeyDmynoD1K4Cj7rKAh6bC7G_M,3747
24
+ dissect/util/compression/lzvn.py,sha256=zCWJKFov9Nydw7VKq8ZBUNtuuGA6n11lQTFVafrLsqg,7967
25
+ dissect/util/compression/lzxpress.py,sha256=8AFgRLgBC8OsadwMW8IaOFvRl-FM6jAYvmxBpQnvd8Q,2484
26
+ dissect/util/compression/lzxpress_huffman.py,sha256=f4yTN0khE_Qz5aZNPMWLYnokxnjAaccXE-YO4HZEXFI,4683
27
+ dissect/util/compression/sevenbit.py,sha256=7s-Lolnk8MpuspxrOowz723-PrJxcABTQ3gZgjKonU8,1510
28
+ dissect/util/compression/xz.py,sha256=q39QYsELg8B5_-HrRWGZqnVc1FGHWKH_Qpqf1qqrnDM,3779
29
+ dissect/util/encoding/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ dissect/util/encoding/surrogateescape.py,sha256=nDxpdapJlfsWyACSEYWfX2SfiyqtDXqVFxfdJAY9LbU,492
31
+ dissect/util/hash/__init__.py,sha256=p2PBbUfYJf4iOiYsR9Ckr-yhJLVOfmz_YH5ruEW9ACU,739
32
+ dissect/util/hash/crc32.py,sha256=TqgnhzFrz-udI0YpTmquL-q-Y1dpsNXpvVHHe9FFlhc,1980
33
+ dissect/util/hash/crc32c.py,sha256=ncXaXxEVxVomOnF4y0Do_lOXlB-qzXsqS-SDNq4Gels,3918
34
+ dissect/util/hash/jenkins.py,sha256=QYgEy9heN-IEirfTcdyi6s0U2jm9n7XuXl_3D_OmOQQ,3527
35
+ dissect/util/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ dissect/util/tools/dump_nskeyedarchiver.py,sha256=ZMSM4TPL8pRn685tX3SAKackgE6EFr2bExPU6Lm8jWk,1454
37
+ dissect_util-3.24.dev1.dist-info/METADATA,sha256=va0ZpqHWnXg_9QWn4Bu0ZeAo_ZnCudq_6a__uYmyUpo,3614
38
+ dissect_util-3.24.dev1.dist-info/WHEEL,sha256=px5T1J9XAfSdBpeclJIAejY1VWE0Yel45SLqElovz2c,111
39
+ dissect_util-3.24.dev1.dist-info/entry_points.txt,sha256=3mwSDD1MUdj0nnTcl2qYFMeu6KYMTycUQS0rlp5CQHI,86
40
+ dissect_util-3.24.dev1.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
41
+ dissect_util-3.24.dev1.dist-info/RECORD,,
42
+ dissect_util-3.24.dev1.dist-info/licenses/COPYRIGHT,sha256=I5uKS6nwQl9xC2xgk-8jvw0gNrpFhvZC7FDTALpj18k,313
43
+ dissect_util-3.24.dev1.dist-info/licenses/LICENSE,sha256=PhUqiw6jAh2KbBdVRPBq_hfAvfcTBin7nZ3CK7NQbTM,11341
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp310-abi3-manylinux_2_28_s390x
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ dump-nskeyedarchiver = dissect.util.tools.dump_nskeyedarchiver:main
@@ -0,0 +1,5 @@
1
+ Dissect is released as open source by Fox-IT (https://www.fox-it.com) part of NCC Group Plc (https://www.nccgroup.com)
2
+
3
+ Developed by the Dissect Team (dissect@fox-it.com) and made available at https://github.com/fox-it/dissect.util
4
+
5
+ License terms: Apache License 2.0 (https://www.apache.org/licenses/LICENSE-2.0)