dissect.target 3.19.dev24__py3-none-any.whl → 3.19.dev25__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.
- dissect/target/plugins/filesystem/ntfs/mft.py +78 -17
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/RECORD +8 -8
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/top_level.txt +0 -0
| @@ -1,9 +1,10 @@ | |
| 1 1 | 
             
            import logging
         | 
| 2 | 
            -
            from typing import Callable
         | 
| 2 | 
            +
            from typing import Callable, Iterator
         | 
| 3 3 |  | 
| 4 4 | 
             
            from dissect.ntfs.attr import Attribute
         | 
| 5 5 | 
             
            from dissect.ntfs.c_ntfs import FILE_RECORD_SEGMENT_IN_USE
         | 
| 6 6 | 
             
            from dissect.ntfs.mft import MftRecord
         | 
| 7 | 
            +
            from flow.record import Record
         | 
| 7 8 | 
             
            from flow.record.fieldtypes import windows_path
         | 
| 8 9 |  | 
| 9 10 | 
             
            from dissect.target.exceptions import UnsupportedPluginError
         | 
| @@ -53,7 +54,6 @@ FilesystemStdRecord = TargetRecordDescriptor( | |
| 53 54 | 
             
                ],
         | 
| 54 55 | 
             
            )
         | 
| 55 56 |  | 
| 56 | 
            -
             | 
| 57 57 | 
             
            FilesystemFilenameCompactRecord = TargetRecordDescriptor(
         | 
| 58 58 | 
             
                "filesystem/ntfs/mft/filename/compact",
         | 
| 59 59 | 
             
                [
         | 
| @@ -90,6 +90,21 @@ FilesystemFilenameRecord = TargetRecordDescriptor( | |
| 90 90 | 
             
                ],
         | 
| 91 91 | 
             
            )
         | 
| 92 92 |  | 
| 93 | 
            +
            FilesystemMACBRecord = TargetRecordDescriptor(
         | 
| 94 | 
            +
                "filesystem/ntfs/mft/macb",
         | 
| 95 | 
            +
                [
         | 
| 96 | 
            +
                    ("datetime", "ts"),
         | 
| 97 | 
            +
                    ("string", "macb"),
         | 
| 98 | 
            +
                    ("uint32", "filename_index"),
         | 
| 99 | 
            +
                    ("uint32", "segment"),
         | 
| 100 | 
            +
                    ("path", "path"),
         | 
| 101 | 
            +
                    ("string", "owner"),
         | 
| 102 | 
            +
                    ("filesize", "filesize"),
         | 
| 103 | 
            +
                    ("boolean", "resident"),
         | 
| 104 | 
            +
                    ("boolean", "inuse"),
         | 
| 105 | 
            +
                    ("string", "volume_uuid"),
         | 
| 106 | 
            +
                ],
         | 
| 107 | 
            +
            )
         | 
| 93 108 |  | 
| 94 109 | 
             
            RECORD_TYPES = {
         | 
| 95 110 | 
             
                InformationType.STANDARD_INFORMATION: FilesystemStdRecord,
         | 
| @@ -118,7 +133,12 @@ class MftPlugin(Plugin): | |
| 118 133 | 
             
                    ]
         | 
| 119 134 | 
             
                )
         | 
| 120 135 | 
             
                @arg("--compact", action="store_true", help="compacts the MFT entry timestamps into a single record")
         | 
| 121 | 
            -
                 | 
| 136 | 
            +
                @arg(
         | 
| 137 | 
            +
                    "--macb",
         | 
| 138 | 
            +
                    action="store_true",
         | 
| 139 | 
            +
                    help="compacts the MFT entry timestamps into aggregated records with MACB bitfield",
         | 
| 140 | 
            +
                )
         | 
| 141 | 
            +
                def mft(self, compact: bool = False, macb: bool = False):
         | 
| 122 142 | 
             
                    """Return the MFT records of all NTFS filesystems.
         | 
| 123 143 |  | 
| 124 144 | 
             
                    The Master File Table (MFT) contains primarily metadata about every file and folder on a NFTS filesystem.
         | 
| @@ -133,10 +153,19 @@ class MftPlugin(Plugin): | |
| 133 153 | 
             
                        - https://docs.microsoft.com/en-us/windows/win32/fileio/master-file-table
         | 
| 134 154 | 
             
                    """
         | 
| 135 155 |  | 
| 136 | 
            -
                     | 
| 156 | 
            +
                    record_formatter = formatter
         | 
| 157 | 
            +
             | 
| 158 | 
            +
                    def noaggr(records: list[Record]) -> Iterator[Record]:
         | 
| 159 | 
            +
                        yield from records
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    aggr = noaggr
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                    if compact and macb:
         | 
| 164 | 
            +
                        raise ValueError("--macb and --compact are mutually exclusive")
         | 
| 165 | 
            +
                    elif compact:
         | 
| 137 166 | 
             
                        record_formatter = compacted_formatter
         | 
| 138 | 
            -
                     | 
| 139 | 
            -
                         | 
| 167 | 
            +
                    elif macb:
         | 
| 168 | 
            +
                        aggr = macb_aggr
         | 
| 140 169 |  | 
| 141 170 | 
             
                    for fs in self.target.filesystems:
         | 
| 142 171 | 
             
                        if fs.__type__ != "ntfs":
         | 
| @@ -167,17 +196,19 @@ class MftPlugin(Plugin): | |
| 167 196 |  | 
| 168 197 | 
             
                                    for path in record.full_paths():
         | 
| 169 198 | 
             
                                        path = f"{drive_letter}{path}"
         | 
| 170 | 
            -
                                        yield from  | 
| 171 | 
            -
                                             | 
| 172 | 
            -
             | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 176 | 
            -
             | 
| 177 | 
            -
             | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 180 | 
            -
             | 
| 199 | 
            +
                                        yield from aggr(
         | 
| 200 | 
            +
                                            self.mft_records(
         | 
| 201 | 
            +
                                                drive_letter=drive_letter,
         | 
| 202 | 
            +
                                                record=record,
         | 
| 203 | 
            +
                                                segment=record.segment,
         | 
| 204 | 
            +
                                                path=path,
         | 
| 205 | 
            +
                                                owner=owner,
         | 
| 206 | 
            +
                                                size=size,
         | 
| 207 | 
            +
                                                resident=resident,
         | 
| 208 | 
            +
                                                inuse=inuse,
         | 
| 209 | 
            +
                                                volume_uuid=volume_uuid,
         | 
| 210 | 
            +
                                                record_formatter=record_formatter,
         | 
| 211 | 
            +
                                            )
         | 
| 181 212 | 
             
                                        )
         | 
| 182 213 | 
             
                                except Exception as e:
         | 
| 183 214 | 
             
                                    self.target.log.warning("An error occured parsing MFT segment %d: %s", record.segment, str(e))
         | 
| @@ -275,3 +306,33 @@ def formatter(attr: Attribute, record_type: InformationType, **kwargs): | |
| 275 306 | 
             
                    ("A", attr.last_access_time),
         | 
| 276 307 | 
             
                ]:
         | 
| 277 308 | 
             
                    yield record_desc(ts=timestamp, ts_type=type, **kwargs)
         | 
| 309 | 
            +
             | 
| 310 | 
            +
             | 
| 311 | 
            +
            def macb_aggr(records: list[Record]) -> Iterator[Record]:
         | 
| 312 | 
            +
                def macb_set(bitfield, index, letter):
         | 
| 313 | 
            +
                    return bitfield[:index] + letter + bitfield[index + 1 :]
         | 
| 314 | 
            +
             | 
| 315 | 
            +
                macbs = []
         | 
| 316 | 
            +
                for record in records:
         | 
| 317 | 
            +
                    found = False
         | 
| 318 | 
            +
             | 
| 319 | 
            +
                    offset_std = int(record._desc.name == "filesystem/ntfs/mft/std") * 5
         | 
| 320 | 
            +
                    offset_ads = (int(record.ads) * 10) if offset_std == 0 else 0
         | 
| 321 | 
            +
             | 
| 322 | 
            +
                    field = "MACB".find(record.ts_type) + offset_std + offset_ads
         | 
| 323 | 
            +
                    for macb in macbs:
         | 
| 324 | 
            +
                        if macb.ts == record.ts:
         | 
| 325 | 
            +
                            macb.macb = macb_set(macb.macb, field, record.ts_type)
         | 
| 326 | 
            +
                            found = True
         | 
| 327 | 
            +
                            break
         | 
| 328 | 
            +
             | 
| 329 | 
            +
                    if found:
         | 
| 330 | 
            +
                        continue
         | 
| 331 | 
            +
             | 
| 332 | 
            +
                    macb = FilesystemMACBRecord.init_from_record(record)
         | 
| 333 | 
            +
                    macb.macb = "..../..../...."
         | 
| 334 | 
            +
                    macb.macb = macb_set(macb.macb, field, record.ts_type)
         | 
| 335 | 
            +
             | 
| 336 | 
            +
                    macbs.append(macb)
         | 
| 337 | 
            +
             | 
| 338 | 
            +
                yield from macbs
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: dissect.target
         | 
| 3 | 
            -
            Version: 3.19. | 
| 3 | 
            +
            Version: 3.19.dev25
         | 
| 4 4 | 
             
            Summary: This module ties all other Dissect modules together, it provides a programming API and command line tools which allow easy access to various data sources inside disk images or file collections (a.k.a. targets)
         | 
| 5 5 | 
             
            Author-email: Dissect Team <dissect@fox-it.com>
         | 
| 6 6 | 
             
            License: Affero General Public License v3
         | 
| @@ -166,7 +166,7 @@ dissect/target/plugins/filesystem/resolver.py,sha256=HfyASUFV4F9uD-yFXilFpPTORAs | |
| 166 166 | 
             
            dissect/target/plugins/filesystem/walkfs.py,sha256=e8HEZcV5Wiua26FGWL3xgiQ_PIhcNvGI5KCdsAx2Nmo,2298
         | 
| 167 167 | 
             
            dissect/target/plugins/filesystem/yara.py,sha256=JdWqbqDBhKrht3fTroqX7NpBU9khEQUWyMcDgLv2l2g,6686
         | 
| 168 168 | 
             
            dissect/target/plugins/filesystem/ntfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 169 | 
            -
            dissect/target/plugins/filesystem/ntfs/mft.py,sha256= | 
| 169 | 
            +
            dissect/target/plugins/filesystem/ntfs/mft.py,sha256=2ibCLJA7yUrZshFSPKdjoNt3TpfwTtk-DaErghe91CM,11445
         | 
| 170 170 | 
             
            dissect/target/plugins/filesystem/ntfs/mft_timeline.py,sha256=vvNFAZbr7s3X2OTYf4ES_L6-XsouTXcTymfxnHfZ1Rw,6791
         | 
| 171 171 | 
             
            dissect/target/plugins/filesystem/ntfs/usnjrnl.py,sha256=uiT1ipmcAo__6VIUi8R_vvIu22vdnjMACKwLSAbzYjs,3704
         | 
| 172 172 | 
             
            dissect/target/plugins/filesystem/ntfs/utils.py,sha256=xG7Lgw9NX4tDDrZVRm0vycFVJTOM7j-HrjqzDh0f4uA,3136
         | 
| @@ -346,10 +346,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z | |
| 346 346 | 
             
            dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
         | 
| 347 347 | 
             
            dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
         | 
| 348 348 | 
             
            dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
         | 
| 349 | 
            -
            dissect.target-3.19. | 
| 350 | 
            -
            dissect.target-3.19. | 
| 351 | 
            -
            dissect.target-3.19. | 
| 352 | 
            -
            dissect.target-3.19. | 
| 353 | 
            -
            dissect.target-3.19. | 
| 354 | 
            -
            dissect.target-3.19. | 
| 355 | 
            -
            dissect.target-3.19. | 
| 349 | 
            +
            dissect.target-3.19.dev25.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
         | 
| 350 | 
            +
            dissect.target-3.19.dev25.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
         | 
| 351 | 
            +
            dissect.target-3.19.dev25.dist-info/METADATA,sha256=7Zg79geLIProzjOZaFpDxr0Zfurfq0EgleNkmo8sI5E,12719
         | 
| 352 | 
            +
            dissect.target-3.19.dev25.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
         | 
| 353 | 
            +
            dissect.target-3.19.dev25.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
         | 
| 354 | 
            +
            dissect.target-3.19.dev25.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
         | 
| 355 | 
            +
            dissect.target-3.19.dev25.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
    
        {dissect.target-3.19.dev24.dist-info → dissect.target-3.19.dev25.dist-info}/entry_points.txt
    RENAMED
    
    | 
            File without changes
         | 
| 
            File without changes
         |