dissect.target 3.19.dev37__py3-none-any.whl → 3.19.dev39__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/filesystems/zip.py +81 -46
- dissect/target/helpers/record.py +37 -0
- dissect/target/plugins/general/network.py +82 -0
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/RECORD +10 -9
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/top_level.txt +0 -0
| @@ -4,16 +4,21 @@ import logging | |
| 4 4 | 
             
            import stat
         | 
| 5 5 | 
             
            import zipfile
         | 
| 6 6 | 
             
            from datetime import datetime, timezone
         | 
| 7 | 
            -
            from typing import BinaryIO,  | 
| 7 | 
            +
            from typing import BinaryIO, Iterator
         | 
| 8 8 |  | 
| 9 9 | 
             
            from dissect.util.stream import BufferedStream
         | 
| 10 10 |  | 
| 11 | 
            -
            from dissect.target.exceptions import  | 
| 11 | 
            +
            from dissect.target.exceptions import (
         | 
| 12 | 
            +
                FileNotFoundError,
         | 
| 13 | 
            +
                FilesystemError,
         | 
| 14 | 
            +
                IsADirectoryError,
         | 
| 15 | 
            +
                NotADirectoryError,
         | 
| 16 | 
            +
                NotASymlinkError,
         | 
| 17 | 
            +
            )
         | 
| 12 18 | 
             
            from dissect.target.filesystem import (
         | 
| 13 19 | 
             
                Filesystem,
         | 
| 14 20 | 
             
                FilesystemEntry,
         | 
| 15 21 | 
             
                VirtualDirectory,
         | 
| 16 | 
            -
                VirtualFile,
         | 
| 17 22 | 
             
                VirtualFilesystem,
         | 
| 18 23 | 
             
            )
         | 
| 19 24 | 
             
            from dissect.target.helpers import fsutil
         | 
| @@ -33,7 +38,7 @@ class ZipFilesystem(Filesystem): | |
| 33 38 | 
             
                def __init__(
         | 
| 34 39 | 
             
                    self,
         | 
| 35 40 | 
             
                    fh: BinaryIO,
         | 
| 36 | 
            -
                    base:  | 
| 41 | 
            +
                    base: str | None = None,
         | 
| 37 42 | 
             
                    *args,
         | 
| 38 43 | 
             
                    **kwargs,
         | 
| 39 44 | 
             
                ):
         | 
| @@ -52,12 +57,7 @@ class ZipFilesystem(Filesystem): | |
| 52 57 | 
             
                            continue
         | 
| 53 58 |  | 
| 54 59 | 
             
                        rel_name = fsutil.normpath(mname[len(self.base) :], alt_separator=self.alt_separator)
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                        # NOTE: Normally we would check here if the member is a symlink or not
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                        entry_cls = ZipFilesystemDirectoryEntry if member.is_dir() else ZipFilesystemEntry
         | 
| 59 | 
            -
                        file_entry = entry_cls(self, rel_name, member)
         | 
| 60 | 
            -
                        self._fs.map_file_entry(rel_name, file_entry)
         | 
| 60 | 
            +
                        self._fs.map_file_entry(rel_name, ZipFilesystemEntry(self, rel_name, member))
         | 
| 61 61 |  | 
| 62 62 | 
             
                @staticmethod
         | 
| 63 63 | 
             
                def _detect(fh: BinaryIO) -> bool:
         | 
| @@ -69,60 +69,95 @@ class ZipFilesystem(Filesystem): | |
| 69 69 | 
             
                    return self._fs.get(path, relentry=relentry)
         | 
| 70 70 |  | 
| 71 71 |  | 
| 72 | 
            -
             | 
| 72 | 
            +
            # Note: We subclass from VirtualDirectory because VirtualFilesystem is currently only compatible with VirtualDirectory
         | 
| 73 | 
            +
            # Subclass from VirtualDirectory so we get that compatibility for free, and override the rest to do our own thing
         | 
| 74 | 
            +
            class ZipFilesystemEntry(VirtualDirectory):
         | 
| 75 | 
            +
                fs: ZipFilesystem
         | 
| 76 | 
            +
                entry: zipfile.ZipInfo
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                def __init__(self, fs: ZipFilesystem, path: str, entry: zipfile.ZipInfo):
         | 
| 79 | 
            +
                    super().__init__(fs, path)
         | 
| 80 | 
            +
                    self.entry = entry
         | 
| 81 | 
            +
             | 
| 73 82 | 
             
                def open(self) -> BinaryIO:
         | 
| 74 | 
            -
                     | 
| 83 | 
            +
                    if self.is_dir():
         | 
| 84 | 
            +
                        raise IsADirectoryError(self.path)
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    if self.is_symlink():
         | 
| 87 | 
            +
                        return self._resolve().open()
         | 
| 88 | 
            +
             | 
| 75 89 | 
             
                    try:
         | 
| 76 90 | 
             
                        return BufferedStream(self.fs.zip.open(self.entry), size=self.entry.file_size)
         | 
| 77 91 | 
             
                    except Exception:
         | 
| 78 | 
            -
                        raise FileNotFoundError()
         | 
| 92 | 
            +
                        raise FileNotFoundError(self.path)
         | 
| 79 93 |  | 
| 80 | 
            -
                def  | 
| 81 | 
            -
                     | 
| 82 | 
            -
             | 
| 94 | 
            +
                def iterdir(self) -> Iterator[str]:
         | 
| 95 | 
            +
                    if not self.is_dir():
         | 
| 96 | 
            +
                        raise NotADirectoryError(self.path)
         | 
| 83 97 |  | 
| 84 | 
            -
             | 
| 85 | 
            -
                     | 
| 86 | 
            -
             | 
| 98 | 
            +
                    entry = self._resolve()
         | 
| 99 | 
            +
                    if isinstance(entry, ZipFilesystemEntry):
         | 
| 100 | 
            +
                        yield from super(ZipFilesystemEntry, entry).iterdir()
         | 
| 101 | 
            +
                    else:
         | 
| 102 | 
            +
                        yield from entry.iterdir()
         | 
| 87 103 |  | 
| 88 | 
            -
                def  | 
| 89 | 
            -
                     | 
| 90 | 
            -
             | 
| 104 | 
            +
                def scandir(self) -> Iterator[FilesystemEntry]:
         | 
| 105 | 
            +
                    if not self.is_dir():
         | 
| 106 | 
            +
                        raise NotADirectoryError(self.path)
         | 
| 91 107 |  | 
| 92 | 
            -
             | 
| 93 | 
            -
                     | 
| 94 | 
            -
             | 
| 95 | 
            -
                     | 
| 96 | 
            -
                         | 
| 97 | 
            -
                            stat.S_IFREG | 0o777,
         | 
| 98 | 
            -
                            self.entry.header_offset,
         | 
| 99 | 
            -
                            id(self.fs),
         | 
| 100 | 
            -
                            1,
         | 
| 101 | 
            -
                            0,
         | 
| 102 | 
            -
                            0,
         | 
| 103 | 
            -
                            self.entry.file_size,
         | 
| 104 | 
            -
                            0,
         | 
| 105 | 
            -
                            datetime(*self.entry.date_time, tzinfo=timezone.utc).timestamp(),
         | 
| 106 | 
            -
                            0,
         | 
| 107 | 
            -
                        ]
         | 
| 108 | 
            -
                    )
         | 
| 108 | 
            +
                    entry = self._resolve()
         | 
| 109 | 
            +
                    if isinstance(entry, ZipFilesystemEntry):
         | 
| 110 | 
            +
                        yield from super(ZipFilesystemEntry, entry).scandir()
         | 
| 111 | 
            +
                    else:
         | 
| 112 | 
            +
                        yield from entry.scandir()
         | 
| 109 113 |  | 
| 114 | 
            +
                def is_dir(self, follow_symlinks: bool = True) -> bool:
         | 
| 115 | 
            +
                    try:
         | 
| 116 | 
            +
                        entry = self._resolve(follow_symlinks=follow_symlinks)
         | 
| 117 | 
            +
                    except FilesystemError:
         | 
| 118 | 
            +
                        return False
         | 
| 110 119 |  | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
                     | 
| 114 | 
            -
             | 
| 120 | 
            +
                    if isinstance(entry, ZipFilesystemEntry):
         | 
| 121 | 
            +
                        return entry.entry.is_dir()
         | 
| 122 | 
            +
                    return isinstance(entry, VirtualDirectory)
         | 
| 123 | 
            +
             | 
| 124 | 
            +
                def is_file(self, follow_symlinks: bool = True) -> bool:
         | 
| 125 | 
            +
                    try:
         | 
| 126 | 
            +
                        entry = self._resolve(follow_symlinks=follow_symlinks)
         | 
| 127 | 
            +
                    except FilesystemError:
         | 
| 128 | 
            +
                        return False
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                    if isinstance(entry, ZipFilesystemEntry):
         | 
| 131 | 
            +
                        return not entry.entry.is_dir()
         | 
| 132 | 
            +
                    return False
         | 
| 133 | 
            +
             | 
| 134 | 
            +
                def is_symlink(self) -> bool:
         | 
| 135 | 
            +
                    return stat.S_ISLNK(self.entry.external_attr >> 16)
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                def readlink(self) -> str:
         | 
| 138 | 
            +
                    if not self.is_symlink():
         | 
| 139 | 
            +
                        raise NotASymlinkError()
         | 
| 140 | 
            +
                    return self.fs.zip.open(self.entry).read().decode()
         | 
| 141 | 
            +
             | 
| 142 | 
            +
                def readlink_ext(self) -> FilesystemEntry:
         | 
| 143 | 
            +
                    return FilesystemEntry.readlink_ext(self)
         | 
| 115 144 |  | 
| 116 145 | 
             
                def stat(self, follow_symlinks: bool = True) -> fsutil.stat_result:
         | 
| 117 | 
            -
                     | 
| 118 | 
            -
                    return self.lstat()
         | 
| 146 | 
            +
                    return self._resolve(follow_symlinks=follow_symlinks).lstat()
         | 
| 119 147 |  | 
| 120 148 | 
             
                def lstat(self) -> fsutil.stat_result:
         | 
| 121 149 | 
             
                    """Return the stat information of the given path, without resolving links."""
         | 
| 122 150 | 
             
                    # ['mode', 'addr', 'dev', 'nlink', 'uid', 'gid', 'size', 'atime', 'mtime', 'ctime']
         | 
| 151 | 
            +
                    mode = self.entry.external_attr >> 16
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                    if self.entry.is_dir() and not stat.S_ISDIR(mode):
         | 
| 154 | 
            +
                        mode = stat.S_IFDIR | mode
         | 
| 155 | 
            +
                    elif not self.entry.is_dir() and not stat.S_ISREG(mode):
         | 
| 156 | 
            +
                        mode = stat.S_IFREG | mode
         | 
| 157 | 
            +
             | 
| 123 158 | 
             
                    return fsutil.stat_result(
         | 
| 124 159 | 
             
                        [
         | 
| 125 | 
            -
                             | 
| 160 | 
            +
                            mode,
         | 
| 126 161 | 
             
                            self.entry.header_offset,
         | 
| 127 162 | 
             
                            id(self.fs),
         | 
| 128 163 | 
             
                            1,
         | 
    
        dissect/target/helpers/record.py
    CHANGED
    
    | @@ -142,3 +142,40 @@ EmptyRecord = RecordDescriptor( | |
| 142 142 | 
             
                "empty",
         | 
| 143 143 | 
             
                [],
         | 
| 144 144 | 
             
            )
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            COMMON_INTERFACE_ELEMENTS = [
         | 
| 147 | 
            +
                ("string", "name"),
         | 
| 148 | 
            +
                ("string", "type"),
         | 
| 149 | 
            +
                ("boolean", "enabled"),
         | 
| 150 | 
            +
                ("string", "mac"),
         | 
| 151 | 
            +
                ("net.ipaddress[]", "dns"),
         | 
| 152 | 
            +
                ("net.ipaddress[]", "ip"),
         | 
| 153 | 
            +
                ("net.ipaddress[]", "gateway"),
         | 
| 154 | 
            +
                ("string", "source"),
         | 
| 155 | 
            +
            ]
         | 
| 156 | 
            +
             | 
| 157 | 
            +
             | 
| 158 | 
            +
            UnixInterfaceRecord = TargetRecordDescriptor(
         | 
| 159 | 
            +
                "unix/network/interface",
         | 
| 160 | 
            +
                COMMON_INTERFACE_ELEMENTS,
         | 
| 161 | 
            +
            )
         | 
| 162 | 
            +
             | 
| 163 | 
            +
            WindowsInterfaceRecord = TargetRecordDescriptor(
         | 
| 164 | 
            +
                "windows/network/interface",
         | 
| 165 | 
            +
                [
         | 
| 166 | 
            +
                    *COMMON_INTERFACE_ELEMENTS,
         | 
| 167 | 
            +
                    ("varint", "vlan"),
         | 
| 168 | 
            +
                    ("string", "metric"),
         | 
| 169 | 
            +
                    ("datetime", "last_connected"),
         | 
| 170 | 
            +
                ],
         | 
| 171 | 
            +
            )
         | 
| 172 | 
            +
             | 
| 173 | 
            +
            MacInterfaceRecord = TargetRecordDescriptor(
         | 
| 174 | 
            +
                "macos/network/interface",
         | 
| 175 | 
            +
                [
         | 
| 176 | 
            +
                    *COMMON_INTERFACE_ELEMENTS,
         | 
| 177 | 
            +
                    ("varint", "vlan"),
         | 
| 178 | 
            +
                    ("string", "proxy"),
         | 
| 179 | 
            +
                    ("varint", "interface_service_order"),
         | 
| 180 | 
            +
                ],
         | 
| 181 | 
            +
            )
         | 
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            from __future__ import annotations
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            from typing import Any, Iterator, Union
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            from flow.record.fieldtypes.net import IPAddress, IPNetwork
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            from dissect.target.helpers.record import (
         | 
| 8 | 
            +
                MacInterfaceRecord,
         | 
| 9 | 
            +
                UnixInterfaceRecord,
         | 
| 10 | 
            +
                WindowsInterfaceRecord,
         | 
| 11 | 
            +
            )
         | 
| 12 | 
            +
            from dissect.target.plugin import Plugin, export, internal
         | 
| 13 | 
            +
            from dissect.target.target import Target
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            InterfaceRecord = Union[UnixInterfaceRecord, WindowsInterfaceRecord, MacInterfaceRecord]
         | 
| 16 | 
            +
             | 
| 17 | 
            +
             | 
| 18 | 
            +
            class NetworkPlugin(Plugin):
         | 
| 19 | 
            +
                __namespace__ = "network"
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def __init__(self, target: Target):
         | 
| 22 | 
            +
                    super().__init__(target)
         | 
| 23 | 
            +
                    self._interface_list: list[InterfaceRecord] | None = None
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def check_compatible(self) -> None:
         | 
| 26 | 
            +
                    pass
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def _interfaces(self) -> Iterator[InterfaceRecord]:
         | 
| 29 | 
            +
                    yield from ()
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def _get_record_type(self, field_name: str) -> Iterator[Any]:
         | 
| 32 | 
            +
                    for record in self.interfaces():
         | 
| 33 | 
            +
                        if (output := getattr(record, field_name, None)) is None:
         | 
| 34 | 
            +
                            continue
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                        if isinstance(output, list):
         | 
| 37 | 
            +
                            yield from output
         | 
| 38 | 
            +
                        else:
         | 
| 39 | 
            +
                            yield output
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                @export(record=InterfaceRecord)
         | 
| 42 | 
            +
                def interfaces(self) -> Iterator[InterfaceRecord]:
         | 
| 43 | 
            +
                    # Only search for the interfaces once
         | 
| 44 | 
            +
                    if self._interface_list is None:
         | 
| 45 | 
            +
                        self._interface_list = list(self._interfaces())
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                    yield from self._interface_list
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                @export
         | 
| 50 | 
            +
                def ips(self) -> list[IPAddress]:
         | 
| 51 | 
            +
                    return list(self._get_record_type("ip"))
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                @export
         | 
| 54 | 
            +
                def gateways(self) -> list[IPAddress]:
         | 
| 55 | 
            +
                    return list(self._get_record_type("gateway"))
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                @export
         | 
| 58 | 
            +
                def macs(self) -> list[str]:
         | 
| 59 | 
            +
                    return list(self._get_record_type("mac"))
         | 
| 60 | 
            +
             | 
| 61 | 
            +
                @export
         | 
| 62 | 
            +
                def dns(self) -> list[str]:
         | 
| 63 | 
            +
                    return list(self._get_record_type("dns"))
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                @internal
         | 
| 66 | 
            +
                def with_ip(self, ip_addr: str) -> Iterator[InterfaceRecord]:
         | 
| 67 | 
            +
                    for interface in self.interfaces():
         | 
| 68 | 
            +
                        if ip_addr in interface.ip:
         | 
| 69 | 
            +
                            yield interface
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                @internal
         | 
| 72 | 
            +
                def with_mac(self, mac: str) -> Iterator[InterfaceRecord]:
         | 
| 73 | 
            +
                    for interface in self.interfaces():
         | 
| 74 | 
            +
                        if interface.mac == mac:
         | 
| 75 | 
            +
                            yield interface
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                @internal
         | 
| 78 | 
            +
                def in_cidr(self, cidr: str) -> Iterator[InterfaceRecord]:
         | 
| 79 | 
            +
                    cidr = IPNetwork(cidr)
         | 
| 80 | 
            +
                    for interface in self.interfaces():
         | 
| 81 | 
            +
                        if any(ip_addr in cidr for ip_addr in interface.ip):
         | 
| 82 | 
            +
                            yield interface
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: dissect.target
         | 
| 3 | 
            -
            Version: 3.19. | 
| 3 | 
            +
            Version: 3.19.dev39
         | 
| 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
         | 
| @@ -42,7 +42,7 @@ dissect/target/filesystems/tar.py,sha256=kQNhcEDPX005svse039OeR2AGSDigGuGz2AKoVr | |
| 42 42 | 
             
            dissect/target/filesystems/vmfs.py,sha256=sRtYBUAKTKcHrjCXqpFJ8GIVU-ERjqxhB2zXBndtcXU,4955
         | 
| 43 43 | 
             
            dissect/target/filesystems/vmtar.py,sha256=LlKWkTIuLemQmG9yGqL7980uC_AOL77_GWhbJc_grSk,804
         | 
| 44 44 | 
             
            dissect/target/filesystems/xfs.py,sha256=kIyFGKYlyFYC7H3jaEv-lNKtBW4ZkD92H0WpfGcr1ww,4498
         | 
| 45 | 
            -
            dissect/target/filesystems/zip.py,sha256= | 
| 45 | 
            +
            dissect/target/filesystems/zip.py,sha256=BeNj23DOYfWuTm5V1V419ViJiMfBrO1VA5gP6rljwXs,5467
         | 
| 46 46 | 
             
            dissect/target/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 47 47 | 
             
            dissect/target/helpers/cache.py,sha256=TXlJBdFRz6V9zKs903am4Yawr0maYw5kZY0RqklDQJM,8568
         | 
| 48 48 | 
             
            dissect/target/helpers/config.py,sha256=RMHnIuKJHINHiLrvKN3EyA0jFA1o6-pbeaycG8Pgrp8,2596
         | 
| @@ -61,7 +61,7 @@ dissect/target/helpers/mui.py,sha256=i-7XoHbu4WO2fYapK9yGAMW04rFlgRispknc1KQIS5Q | |
| 61 61 | 
             
            dissect/target/helpers/network_managers.py,sha256=ByBSe2K3c8hgQC6dokcf-hHdmPcD8PmrOj0xs1C3yhs,25743
         | 
| 62 62 | 
             
            dissect/target/helpers/polypath.py,sha256=h8p7m_OCNiQljGwoZh5Aflr9H2ot6CZr6WKq1OSw58o,2175
         | 
| 63 63 | 
             
            dissect/target/helpers/protobuf.py,sha256=b4DsnqrRLrefcDjx7rQno-_LBcwtJXxuKf5RdOegzfE,1537
         | 
| 64 | 
            -
            dissect/target/helpers/record.py,sha256= | 
| 64 | 
            +
            dissect/target/helpers/record.py,sha256=zwqEnFSgxgX6JdhhF4zycMMZK09crCTWWEFzRxZSuC8,5658
         | 
| 65 65 | 
             
            dissect/target/helpers/record_modifier.py,sha256=3I_rC5jqvl0TsW3V8OQ6Dltz_D8J4PU1uhhzbJGKm9c,3245
         | 
| 66 66 | 
             
            dissect/target/helpers/regutil.py,sha256=kX-sSZbW8Qkg29Dn_9zYbaQrwLumrr4Y8zJ1EhHXIAM,27337
         | 
| 67 67 | 
             
            dissect/target/helpers/shell_folder_ids.py,sha256=Behhb8oh0kMxrEk6YYKYigCDZe8Hw5QS6iK_d2hTs2Y,24978
         | 
| @@ -180,6 +180,7 @@ dissect/target/plugins/general/config.py,sha256=Mdy9uhWn4OJ96zfXpLgjVifV5SrViqHn | |
| 180 180 | 
             
            dissect/target/plugins/general/default.py,sha256=8W_9JV3jKEeETlyTrB25sACoIIFmmO8wlVU5Zoi51W0,1425
         | 
| 181 181 | 
             
            dissect/target/plugins/general/example.py,sha256=6B_YOqajRBLNWBEOfIL_HnLaEANBF8KKoc0mweihiug,6034
         | 
| 182 182 | 
             
            dissect/target/plugins/general/loaders.py,sha256=6iUxhlSAgo7qSE8_XFxgiihK8sdMiP-s4k0W5Iv8m9k,879
         | 
| 183 | 
            +
            dissect/target/plugins/general/network.py,sha256=Ol4Ls1w78-7zpmVaQQOZG27rvYOhJLFVhomZj5kwibs,2430
         | 
| 183 184 | 
             
            dissect/target/plugins/general/osinfo.py,sha256=RdK5mw3-H9H3sGXz8yP8U_p3wUG1Ww7_HBKZpFdsbTE,1358
         | 
| 184 185 | 
             
            dissect/target/plugins/general/plugins.py,sha256=4URjS6DN1Ey6Cqlbyx6NfFGgQZpWDrqxl8KLcZFODGE,4479
         | 
| 185 186 | 
             
            dissect/target/plugins/general/scrape.py,sha256=Fz7BNXflvuxlnVulyyDhLpyU8D_hJdH6vWVtER9vjTg,6651
         | 
| @@ -348,10 +349,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z | |
| 348 349 | 
             
            dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
         | 
| 349 350 | 
             
            dissect/target/volumes/md.py,sha256=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
         | 
| 350 351 | 
             
            dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
         | 
| 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. | 
| 356 | 
            -
            dissect.target-3.19. | 
| 357 | 
            -
            dissect.target-3.19. | 
| 352 | 
            +
            dissect.target-3.19.dev39.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
         | 
| 353 | 
            +
            dissect.target-3.19.dev39.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
         | 
| 354 | 
            +
            dissect.target-3.19.dev39.dist-info/METADATA,sha256=c6QzWVFBBowHJF8fihCzibN_ELCTHhj59sC_YGZIqhY,12719
         | 
| 355 | 
            +
            dissect.target-3.19.dev39.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
         | 
| 356 | 
            +
            dissect.target-3.19.dev39.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
         | 
| 357 | 
            +
            dissect.target-3.19.dev39.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
         | 
| 358 | 
            +
            dissect.target-3.19.dev39.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
    
        {dissect.target-3.19.dev37.dist-info → dissect.target-3.19.dev39.dist-info}/entry_points.txt
    RENAMED
    
    | 
            File without changes
         | 
| 
            File without changes
         |