dissect.apfs 1.0.2.dev1__tar.gz → 1.1.dev1__tar.gz
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.
- {dissect_apfs-1.0.2.dev1/dissect.apfs.egg-info → dissect_apfs-1.1.dev1}/PKG-INFO +1 -1
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/apfs.py +2 -28
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/fs.py +9 -9
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_superblock.py +4 -36
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/omap.py +0 -9
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1/dissect.apfs.egg-info}/PKG-INFO +1 -1
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect.apfs.egg-info/SOURCES.txt +0 -1
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/test_apfs.py +1 -23
- dissect_apfs-1.0.2.dev1/tests/_data/corrupt.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/COPYRIGHT +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/LICENSE +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/MANIFEST.in +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/README.md +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/__init__.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/c_apfs.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/c_apfs.pyi +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/cursor.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/exception.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/__init__.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/base.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/btree.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/btree_node.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/checkpoint_map.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/efi_jumpstart.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/er_recovery_block.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/er_state.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/gbitmap.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/gbitmap_block.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/integrity_meta.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/keybag.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_fusion_wbc.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_fusion_wbc_list.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_reap_list.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_reaper.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/snap_meta_ext.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/spaceman.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/spaceman_bitmap.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/spaceman_cab.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/spaceman_cib.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/stream.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/util.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect.apfs.egg-info/dependency_links.txt +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect.apfs.egg-info/requires.txt +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect.apfs.egg-info/top_level.txt +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/pyproject.toml +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/setup.cfg +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/__init__.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/case_insensitive.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/case_insensitive_beta.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/case_sensitive.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/case_sensitive_beta.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/encrypted.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/jhfs_converted.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/jhfs_encrypted.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_data/snapshot.bin.gz +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_docs/Makefile +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_docs/__init__.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_docs/conf.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/_docs/index.rst +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/conftest.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tests/test_exception.py +0 -0
- {dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.apfs
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.dev1
|
|
4
4
|
Summary: A Dissect module implementing a parser for the APFS file system, a commonly used Apple file system
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import logging
|
|
4
|
-
import os
|
|
5
3
|
from typing import TYPE_CHECKING, BinaryIO
|
|
6
4
|
|
|
7
5
|
from dissect.apfs.c_apfs import c_apfs
|
|
@@ -13,9 +11,6 @@ if TYPE_CHECKING:
|
|
|
13
11
|
from dissect.apfs.objects.fs import FS
|
|
14
12
|
from dissect.apfs.objects.keybag import ContainerKeybag
|
|
15
13
|
|
|
16
|
-
log = logging.getLogger(__name__)
|
|
17
|
-
log.setLevel(os.getenv("DISSECT_LOG_APFS", "CRITICAL"))
|
|
18
|
-
|
|
19
14
|
|
|
20
15
|
class APFS:
|
|
21
16
|
"""Container class for APFS operations.
|
|
@@ -29,29 +24,8 @@ class APFS:
|
|
|
29
24
|
self.fh.seek(0)
|
|
30
25
|
|
|
31
26
|
self.sb = NxSuperblock.from_block(self, 0, self.fh.read(c_apfs.NX_DEFAULT_BLOCK_SIZE))
|
|
32
|
-
self.sb.
|
|
33
|
-
|
|
34
|
-
self.sbs = sorted(
|
|
35
|
-
[obj for obj in self.sb.checkpoint_objects if isinstance(obj, NxSuperblock)],
|
|
36
|
-
key=lambda obj: obj.xid,
|
|
37
|
-
reverse=True,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
# TODO: Do more accurate checkpoint traversal
|
|
41
|
-
for sb in self.sbs:
|
|
42
|
-
try:
|
|
43
|
-
sb.check()
|
|
44
|
-
sb.compare(self.sb)
|
|
45
|
-
except Exception as e:
|
|
46
|
-
log.debug("Skipping superblock xid=%d: %s", sb.xid, e)
|
|
47
|
-
continue
|
|
48
|
-
|
|
49
|
-
if not sb.omap.is_valid():
|
|
50
|
-
log.debug("Skipping superblock xid=%d: invalid OMAP", sb.xid)
|
|
51
|
-
continue
|
|
52
|
-
|
|
53
|
-
self.sb = sb
|
|
54
|
-
break
|
|
27
|
+
self.sbs = [self.sb] + [obj for obj in self.sb.checkpoint_objects if isinstance(obj, NxSuperblock)]
|
|
28
|
+
self.sb = sorted(self.sbs, key=lambda obj: obj.xid)[-1]
|
|
55
29
|
|
|
56
30
|
@property
|
|
57
31
|
def block_size(self) -> int:
|
|
@@ -792,27 +792,27 @@ class DirectoryEntry:
|
|
|
792
792
|
@cached_property
|
|
793
793
|
def type(self) -> int:
|
|
794
794
|
"""The file type of this directory entry."""
|
|
795
|
-
return
|
|
795
|
+
return self.value.flags & c_apfs.DREC_TYPE_MASK << 12
|
|
796
796
|
|
|
797
797
|
def is_dir(self) -> bool:
|
|
798
798
|
"""Return whether this directory entry is a directory."""
|
|
799
|
-
return stat.S_ISDIR(self.type)
|
|
799
|
+
return stat.S_ISDIR(self.type << 12)
|
|
800
800
|
|
|
801
801
|
def is_file(self) -> bool:
|
|
802
802
|
"""Return whether this directory entry is a regular file."""
|
|
803
|
-
return stat.S_ISREG(self.type)
|
|
803
|
+
return stat.S_ISREG(self.type << 12)
|
|
804
804
|
|
|
805
805
|
def is_symlink(self) -> bool:
|
|
806
806
|
"""Return whether this directory entry is a symbolic link."""
|
|
807
|
-
return stat.S_ISLNK(self.type)
|
|
807
|
+
return stat.S_ISLNK(self.type << 12)
|
|
808
808
|
|
|
809
809
|
def is_block_device(self) -> bool:
|
|
810
810
|
"""Return whether this directory entry is a block device."""
|
|
811
|
-
return stat.S_ISBLK(self.type)
|
|
811
|
+
return stat.S_ISBLK(self.type << 12)
|
|
812
812
|
|
|
813
813
|
def is_character_device(self) -> bool:
|
|
814
814
|
"""Return whether this directory entry is a character device."""
|
|
815
|
-
return stat.S_ISCHR(self.type)
|
|
815
|
+
return stat.S_ISCHR(self.type << 12)
|
|
816
816
|
|
|
817
817
|
def is_device(self) -> bool:
|
|
818
818
|
"""Return whether this directory entry is a device (block or character)."""
|
|
@@ -820,15 +820,15 @@ class DirectoryEntry:
|
|
|
820
820
|
|
|
821
821
|
def is_fifo(self) -> bool:
|
|
822
822
|
"""Return whether this directory entry is a FIFO."""
|
|
823
|
-
return stat.S_ISFIFO(self.type)
|
|
823
|
+
return stat.S_ISFIFO(self.type << 12)
|
|
824
824
|
|
|
825
825
|
def is_socket(self) -> bool:
|
|
826
826
|
"""Return whether this directory entry is a socket."""
|
|
827
|
-
return stat.S_ISSOCK(self.type)
|
|
827
|
+
return stat.S_ISSOCK(self.type << 12)
|
|
828
828
|
|
|
829
829
|
def is_whiteout(self) -> bool:
|
|
830
830
|
"""Return whether this directory entry is a whiteout."""
|
|
831
|
-
return stat.S_ISWHT(self.type)
|
|
831
|
+
return stat.S_ISWHT(self.type << 12)
|
|
832
832
|
|
|
833
833
|
|
|
834
834
|
class XAttr:
|
|
@@ -29,16 +29,8 @@ class NxSuperblock(Object):
|
|
|
29
29
|
__struct__ = c_apfs.nx_superblock
|
|
30
30
|
object: c_apfs.nx_superblock
|
|
31
31
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
if not self.is_valid():
|
|
35
|
-
raise Error("Invalid nx_superblock checksum")
|
|
36
|
-
|
|
37
|
-
if self.type != c_apfs.OBJECT_TYPE.NX_SUPERBLOCK:
|
|
38
|
-
raise Error("Invalid nx_superblock type")
|
|
39
|
-
|
|
40
|
-
if not self.is_ephemeral:
|
|
41
|
-
raise Error("Invalid nx_superblock storage type")
|
|
32
|
+
def __init__(self, *args, **kwargs):
|
|
33
|
+
super().__init__(*args, **kwargs)
|
|
42
34
|
|
|
43
35
|
if self.object.nx_magic.to_bytes(4, "big") != c_apfs.NX_MAGIC:
|
|
44
36
|
raise Error(
|
|
@@ -46,24 +38,6 @@ class NxSuperblock(Object):
|
|
|
46
38
|
f"(expected {c_apfs.NX_MAGIC!r}, got {self.object.nx_magic.to_bytes(4, 'big')!r})"
|
|
47
39
|
)
|
|
48
40
|
|
|
49
|
-
def compare(self, other: NxSuperblock) -> None:
|
|
50
|
-
"""Compare this superblock to another superblock."""
|
|
51
|
-
if self.header.o_xid < other.header.o_xid:
|
|
52
|
-
raise Error("Lower xid than other superblock")
|
|
53
|
-
|
|
54
|
-
for attr in (
|
|
55
|
-
"nx_uuid",
|
|
56
|
-
"nx_fusion_uuid",
|
|
57
|
-
"nx_block_size",
|
|
58
|
-
"nx_block_count",
|
|
59
|
-
"nx_xp_desc_blocks",
|
|
60
|
-
"nx_xp_data_blocks",
|
|
61
|
-
"nx_xp_desc_base",
|
|
62
|
-
"nx_xp_data_base",
|
|
63
|
-
):
|
|
64
|
-
if getattr(self.object, attr) != getattr(other.object, attr):
|
|
65
|
-
raise Error(f"Mismatch on {attr}")
|
|
66
|
-
|
|
67
41
|
@cached_property
|
|
68
42
|
def block_size(self) -> int:
|
|
69
43
|
"""The block size of the container."""
|
|
@@ -92,20 +66,14 @@ class NxSuperblock(Object):
|
|
|
92
66
|
@cached_property
|
|
93
67
|
def checkpoint_objects(self) -> list[CheckpointMap | NxSuperblock]:
|
|
94
68
|
"""All checkpoint objects in the container."""
|
|
95
|
-
|
|
96
|
-
return list(
|
|
97
|
-
_read_checkpoint_objects(self.container, self.object.nx_xp_desc_base, self.object.nx_xp_desc_blocks)
|
|
98
|
-
)
|
|
69
|
+
return list(_read_checkpoint_objects(self.container, self.object.nx_xp_desc_base, self.object.nx_xp_desc_len))
|
|
99
70
|
|
|
100
71
|
@cached_property
|
|
101
72
|
def ephemeral_objects(self) -> dict[int, Object]:
|
|
102
73
|
"""All ephemeral objects in the container."""
|
|
103
|
-
# TODO: I don't think this is correct
|
|
104
74
|
return {
|
|
105
75
|
obj.oid: obj
|
|
106
|
-
for obj in _read_checkpoint_objects(
|
|
107
|
-
self.container, self.object.nx_xp_data_base, self.object.nx_xp_data_blocks
|
|
108
|
-
)
|
|
76
|
+
for obj in _read_checkpoint_objects(self.container, self.object.nx_xp_data_base, self.object.nx_xp_data_len)
|
|
109
77
|
}
|
|
110
78
|
|
|
111
79
|
@cached_property
|
|
@@ -20,15 +20,6 @@ class ObjectMap(Object):
|
|
|
20
20
|
|
|
21
21
|
self.lookup = lru_cache(128)(self.lookup)
|
|
22
22
|
|
|
23
|
-
def is_valid(self) -> bool:
|
|
24
|
-
return (
|
|
25
|
-
super().is_valid()
|
|
26
|
-
and self.type == c_apfs.OBJECT_TYPE.OMAP
|
|
27
|
-
and self.subtype == 0
|
|
28
|
-
and self.is_physical
|
|
29
|
-
and self.oid == self.address
|
|
30
|
-
)
|
|
31
|
-
|
|
32
23
|
@cached_property
|
|
33
24
|
def btree(self) -> BTree:
|
|
34
25
|
"""The B-tree of the object map."""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.apfs
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.dev1
|
|
4
4
|
Summary: A Dissect module implementing a parser for the APFS file system, a commonly used Apple file system
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -49,7 +49,6 @@ tests/_data/case_insensitive.bin.gz
|
|
|
49
49
|
tests/_data/case_insensitive_beta.bin.gz
|
|
50
50
|
tests/_data/case_sensitive.bin.gz
|
|
51
51
|
tests/_data/case_sensitive_beta.bin.gz
|
|
52
|
-
tests/_data/corrupt.bin.gz
|
|
53
52
|
tests/_data/encrypted.bin.gz
|
|
54
53
|
tests/_data/jhfs_converted.bin.gz
|
|
55
54
|
tests/_data/jhfs_encrypted.bin.gz
|
|
@@ -6,7 +6,7 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
-
from dissect.apfs.apfs import APFS
|
|
9
|
+
from dissect.apfs.apfs import APFS
|
|
10
10
|
from dissect.apfs.c_apfs import c_apfs
|
|
11
11
|
from tests.conftest import absolute_path
|
|
12
12
|
|
|
@@ -36,11 +36,6 @@ def _assert_apfs_content(volume: FS, beta: bool) -> None:
|
|
|
36
36
|
]
|
|
37
37
|
)
|
|
38
38
|
|
|
39
|
-
# Test direntry parsing
|
|
40
|
-
assert node.listdir()["dir"].is_dir()
|
|
41
|
-
assert node.listdir()["hardlink"].is_file()
|
|
42
|
-
assert node.listdir()["symlink-dir"].is_symlink()
|
|
43
|
-
|
|
44
39
|
# Empty file
|
|
45
40
|
node = volume.get("empty")
|
|
46
41
|
assert node.name == "empty"
|
|
@@ -245,9 +240,6 @@ def _assert_apfs_content(volume: FS, beta: bool) -> None:
|
|
|
245
240
|
|
|
246
241
|
if ".HFS+ Private Directory Data\r" not in volume.get("/").listdir() and not beta:
|
|
247
242
|
# Special files
|
|
248
|
-
dirents = volume.get("dir").listdir()
|
|
249
|
-
assert dirents["blockdev"].is_block_device()
|
|
250
|
-
|
|
251
243
|
node = volume.get("dir/blockdev")
|
|
252
244
|
assert node.name == "blockdev"
|
|
253
245
|
assert node.is_block_device()
|
|
@@ -271,8 +263,6 @@ def _assert_apfs_content(volume: FS, beta: bool) -> None:
|
|
|
271
263
|
"chardev-svr4",
|
|
272
264
|
"chardev-ultrix",
|
|
273
265
|
]:
|
|
274
|
-
assert dirents[name].is_character_device()
|
|
275
|
-
|
|
276
266
|
node = volume.get(f"dir/{name}")
|
|
277
267
|
assert node.name == name
|
|
278
268
|
assert node.is_character_device()
|
|
@@ -367,15 +357,3 @@ def test_snapshots() -> None:
|
|
|
367
357
|
for i, snapshot in enumerate(volume.snapshots):
|
|
368
358
|
assert snapshot.name == f"Snapshot {i}"
|
|
369
359
|
assert snapshot.open().get("file").open().read() == f"Snapshot {i}\n".encode()
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
def test_corrupt_checkpoints(caplog: pytest.LogCaptureFixture) -> None:
|
|
373
|
-
"""Test APFS volumes with corrupt checkpoints."""
|
|
374
|
-
with gzip.open(absolute_path("_data/corrupt.bin.gz"), "rb") as fh, caplog.at_level("DEBUG", log.name):
|
|
375
|
-
container = APFS(fh)
|
|
376
|
-
|
|
377
|
-
assert container.sb.xid == 302
|
|
378
|
-
assert len(container.volumes) == 1
|
|
379
|
-
|
|
380
|
-
assert caplog.messages[0] == "Skipping superblock xid=304: invalid OMAP"
|
|
381
|
-
assert caplog.messages[1] == "Skipping superblock xid=303: Invalid nx_superblock checksum"
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect/apfs/objects/nx_fusion_wbc_list.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_apfs-1.0.2.dev1 → dissect_apfs-1.1.dev1}/dissect.apfs.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|