dissect.target 3.16.dev29__py3-none-any.whl → 3.16.dev31__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/apps/webserver/iis.py +2 -1
- dissect/target/plugins/os/unix/esxi/_os.py +61 -9
- dissect/target/plugins/os/windows/log/etl.py +3 -1
- dissect/target/plugins/os/windows/log/evtx.py +1 -1
- dissect/target/plugins/os/windows/registry.py +3 -1
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/METADATA +1 -1
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/RECORD +12 -12
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/LICENSE +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/WHEEL +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/top_level.txt +0 -0
| @@ -60,6 +60,8 @@ class IISLogsPlugin(WebserverPlugin): | |
| 60 60 | 
             
                    super().__init__(target)
         | 
| 61 61 | 
             
                    self.config = self.target.fs.path(self.APPLICATION_HOST_CONFIG)
         | 
| 62 62 |  | 
| 63 | 
            +
                    self._create_extended_descriptor = lru_cache(4096)(self._create_extended_descriptor)
         | 
| 64 | 
            +
             | 
| 63 65 | 
             
                def check_compatible(self) -> None:
         | 
| 64 66 | 
             
                    if not self.config.exists() and not self.target.fs.path("sysvol/files").exists():
         | 
| 65 67 | 
             
                        raise UnsupportedPluginError("No ApplicationHost config file found")
         | 
| @@ -157,7 +159,6 @@ class IISLogsPlugin(WebserverPlugin): | |
| 157 159 | 
             
                        row = replace_dash_with_none(row)
         | 
| 158 160 | 
             
                        yield BasicRecordDescriptor(**row)
         | 
| 159 161 |  | 
| 160 | 
            -
                @lru_cache(maxsize=4096)
         | 
| 161 162 | 
             
                def _create_extended_descriptor(self, extra_fields: tuple[tuple[str, str]]) -> TargetRecordDescriptor:
         | 
| 162 163 | 
             
                    return TargetRecordDescriptor(LOG_RECORD_NAME, BASIC_RECORD_FIELDS + list(extra_fields))
         | 
| 163 164 |  | 
| @@ -4,6 +4,7 @@ import gzip | |
| 4 4 | 
             
            import json
         | 
| 5 5 | 
             
            import lzma
         | 
| 6 6 | 
             
            import struct
         | 
| 7 | 
            +
            import subprocess
         | 
| 7 8 | 
             
            from configparser import ConfigParser
         | 
| 8 9 | 
             
            from configparser import Error as ConfigParserError
         | 
| 9 10 | 
             
            from io import BytesIO
         | 
| @@ -13,6 +14,8 @@ from defusedxml import ElementTree | |
| 13 14 | 
             
            from dissect.hypervisor.util import vmtar
         | 
| 14 15 | 
             
            from dissect.sql import sqlite3
         | 
| 15 16 |  | 
| 17 | 
            +
            from dissect.target.helpers.fsutil import TargetPath
         | 
| 18 | 
            +
             | 
| 16 19 | 
             
            try:
         | 
| 17 20 | 
             
                from dissect.hypervisor.util.envelope import Envelope, KeyStore
         | 
| 18 21 |  | 
| @@ -217,23 +220,72 @@ def _mount_local(target: Target, local_layer: VirtualFilesystem): | |
| 217 220 | 
             
                    local_fs = tar.TarFilesystem(local_tgz.open())
         | 
| 218 221 | 
             
                else:
         | 
| 219 222 | 
             
                    local_tgz_ve = target.fs.path("local.tgz.ve")
         | 
| 220 | 
            -
                     | 
| 223 | 
            +
                    # In the case "encryption.info" does not exist, but ".#encryption.info" does
         | 
| 224 | 
            +
                    encryption_info = next(target.fs.path("/").glob("*encryption.info"), None)
         | 
| 221 225 | 
             
                    if not local_tgz_ve.exists() or not encryption_info.exists():
         | 
| 222 226 | 
             
                        raise ValueError("Unable to find valid configuration archive")
         | 
| 223 227 |  | 
| 224 | 
            -
                     | 
| 225 | 
            -
                        target.log.info("local.tgz is encrypted, attempting to decrypt")
         | 
| 226 | 
            -
                        envelope = Envelope(local_tgz_ve.open())
         | 
| 227 | 
            -
                        keystore = KeyStore.from_text(encryption_info.read_text("utf-8"))
         | 
| 228 | 
            -
                        local_tgz = BytesIO(envelope.decrypt(keystore.key, aad=b"ESXConfiguration"))
         | 
| 229 | 
            -
                        local_fs = tar.TarFilesystem(local_tgz)
         | 
| 230 | 
            -
                    else:
         | 
| 231 | 
            -
                        target.log.warning("local.tgz is encrypted but no crypto module available!")
         | 
| 228 | 
            +
                    local_fs = _create_local_fs(target, local_tgz_ve, encryption_info)
         | 
| 232 229 |  | 
| 233 230 | 
             
                if local_fs:
         | 
| 234 231 | 
             
                    local_layer.mount("/", local_fs)
         | 
| 235 232 |  | 
| 236 233 |  | 
| 234 | 
            +
            def _decrypt_envelope(local_tgz_ve: TargetPath, encryption_info: TargetPath) -> BinaryIO:
         | 
| 235 | 
            +
                """Decrypt ``local.tgz.ve`` ourselves with hard-coded keys."""
         | 
| 236 | 
            +
                envelope = Envelope(local_tgz_ve.open())
         | 
| 237 | 
            +
                keystore = KeyStore.from_text(encryption_info.read_text("utf-8"))
         | 
| 238 | 
            +
                local_tgz = BytesIO(envelope.decrypt(keystore.key, aad=b"ESXConfiguration"))
         | 
| 239 | 
            +
                return local_tgz
         | 
| 240 | 
            +
             | 
| 241 | 
            +
             | 
| 242 | 
            +
            def _decrypt_crypto_util(local_tgz_ve: TargetPath) -> Optional[BytesIO]:
         | 
| 243 | 
            +
                """Decrypt ``local.tgz.ve`` using ESXi ``crypto-util``.
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                We write to stdout, but this results in ``crypto-util`` exiting with a non-zero return code
         | 
| 246 | 
            +
                and stderr containing an I/O error message. The file does get properly decrypted, so we return
         | 
| 247 | 
            +
                ``None`` if there are no bytes in stdout which would indicate it actually failed.
         | 
| 248 | 
            +
                """
         | 
| 249 | 
            +
             | 
| 250 | 
            +
                result = subprocess.run(
         | 
| 251 | 
            +
                    ["crypto-util", "envelope", "extract", "--aad", "ESXConfiguration", f"/{local_tgz_ve.as_posix()}", "-"],
         | 
| 252 | 
            +
                    capture_output=True,
         | 
| 253 | 
            +
                )
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                if len(result.stdout) == 0:
         | 
| 256 | 
            +
                    return None
         | 
| 257 | 
            +
             | 
| 258 | 
            +
                return BytesIO(result.stdout)
         | 
| 259 | 
            +
             | 
| 260 | 
            +
             | 
| 261 | 
            +
            def _create_local_fs(
         | 
| 262 | 
            +
                target: Target, local_tgz_ve: TargetPath, encryption_info: TargetPath
         | 
| 263 | 
            +
            ) -> Optional[tar.TarFilesystem]:
         | 
| 264 | 
            +
                local_tgz = None
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                if HAS_ENVELOPE:
         | 
| 267 | 
            +
                    try:
         | 
| 268 | 
            +
                        local_tgz = _decrypt_envelope(local_tgz_ve, encryption_info)
         | 
| 269 | 
            +
                    except NotImplementedError:
         | 
| 270 | 
            +
                        target.log.debug("Failed to decrypt %s, likely TPM encrypted", local_tgz_ve)
         | 
| 271 | 
            +
                else:
         | 
| 272 | 
            +
                    target.log.debug("Skipping static decryption because of missing crypto module")
         | 
| 273 | 
            +
             | 
| 274 | 
            +
                if not local_tgz and target.name == "local":
         | 
| 275 | 
            +
                    target.log.info(
         | 
| 276 | 
            +
                        "local.tgz is encrypted but static decryption failed, attempting dynamic decryption using crypto-util"
         | 
| 277 | 
            +
                    )
         | 
| 278 | 
            +
                    local_tgz = _decrypt_crypto_util(local_tgz_ve)
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    if local_tgz is None:
         | 
| 281 | 
            +
                        target.log.warning("Dynamic decryption of %s failed.", local_tgz_ve)
         | 
| 282 | 
            +
                else:
         | 
| 283 | 
            +
                    target.log.warning("local.tgz is encrypted but static decryption failed and no dynamic decryption available!")
         | 
| 284 | 
            +
             | 
| 285 | 
            +
                if local_tgz:
         | 
| 286 | 
            +
                    return tar.TarFilesystem(local_tgz)
         | 
| 287 | 
            +
             | 
| 288 | 
            +
             | 
| 237 289 | 
             
            def _mount_filesystems(target: Target, sysvol: Filesystem, cfg: dict[str, str]):
         | 
| 238 290 | 
             
                version = cfg["build"]
         | 
| 239 291 |  | 
| @@ -13,6 +13,9 @@ from dissect.target.plugins.os.windows.datetime import parse_tzi | |
| 13 13 | 
             
            class EtlRecordBuilder:
         | 
| 14 14 | 
             
                RECORD_NAME = "filesystem/windows/etl"
         | 
| 15 15 |  | 
| 16 | 
            +
                def __init__(self):
         | 
| 17 | 
            +
                    self._create_event_descriptor = lru_cache(4096)(self._create_event_descriptor)
         | 
| 18 | 
            +
             | 
| 16 19 | 
             
                def _build_record(self, etl_event: Event, etl_path: Path, target: Target):
         | 
| 17 20 | 
             
                    """Builds an ETL event record"""
         | 
| 18 21 |  | 
| @@ -51,7 +54,6 @@ class EtlRecordBuilder: | |
| 51 54 | 
             
                    desc = self._create_event_descriptor(tuple(record_fields))
         | 
| 52 55 | 
             
                    return desc(**record_values)
         | 
| 53 56 |  | 
| 54 | 
            -
                @lru_cache(maxsize=4096)
         | 
| 55 57 | 
             
                def _create_event_descriptor(self, record_fields):
         | 
| 56 58 | 
             
                    return TargetRecordDescriptor(self.RECORD_NAME, record_fields)
         | 
| 57 59 |  | 
| @@ -29,6 +29,7 @@ class EvtxPlugin(WindowsEventlogsMixin, plugin.Plugin): | |
| 29 29 |  | 
| 30 30 | 
             
                def __init__(self, target):
         | 
| 31 31 | 
             
                    super().__init__(target)
         | 
| 32 | 
            +
                    self._create_event_descriptor = lru_cache(4096)(self._create_event_descriptor)
         | 
| 32 33 |  | 
| 33 34 | 
             
                @plugin.arg("--logs-dir", help="logs directory to scan")
         | 
| 34 35 | 
             
                @plugin.arg("--log-file-glob", default=EVTX_GLOB, help="glob pattern to match a log file name")
         | 
| @@ -145,7 +146,6 @@ class EvtxPlugin(WindowsEventlogsMixin, plugin.Plugin): | |
| 145 146 | 
             
                    desc = self._create_event_descriptor(tuple(record_fields))
         | 
| 146 147 | 
             
                    return desc(**record_values)
         | 
| 147 148 |  | 
| 148 | 
            -
                @lru_cache(maxsize=4096)
         | 
| 149 149 | 
             
                def _create_event_descriptor(self, record_fields) -> TargetRecordDescriptor:
         | 
| 150 150 | 
             
                    return TargetRecordDescriptor(self.RECORD_NAME, record_fields)
         | 
| 151 151 |  | 
| @@ -72,6 +72,7 @@ class RegistryPlugin(Plugin): | |
| 72 72 |  | 
| 73 73 | 
             
                def __init__(self, target: Target) -> None:
         | 
| 74 74 | 
             
                    super().__init__(target)
         | 
| 75 | 
            +
             | 
| 75 76 | 
             
                    self._root = VirtualHive()
         | 
| 76 77 | 
             
                    self._hive_collections = defaultdict(HiveCollection)
         | 
| 77 78 | 
             
                    self._hive_paths = []
         | 
| @@ -83,6 +84,8 @@ class RegistryPlugin(Plugin): | |
| 83 84 | 
             
                    self._users_loaded = False
         | 
| 84 85 | 
             
                    self._init_registry()
         | 
| 85 86 |  | 
| 87 | 
            +
                    self.key = lru_cache(4096)(self.key)
         | 
| 88 | 
            +
             | 
| 86 89 | 
             
                def _init_registry(self) -> None:
         | 
| 87 90 | 
             
                    dirs = [
         | 
| 88 91 | 
             
                        ("sysvol/windows/system32/config", False),
         | 
| @@ -217,7 +220,6 @@ class RegistryPlugin(Plugin): | |
| 217 220 | 
             
                    return self.key()
         | 
| 218 221 |  | 
| 219 222 | 
             
                @internal
         | 
| 220 | 
            -
                @lru_cache(4096)
         | 
| 221 223 | 
             
                def key(self, key: Optional[str] = None) -> KeyCollection:
         | 
| 222 224 | 
             
                    """Query the virtual registry on the given key.
         | 
| 223 225 |  | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: dissect.target
         | 
| 3 | 
            -
            Version: 3.16. | 
| 3 | 
            +
            Version: 3.16.dev31
         | 
| 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
         | 
| @@ -143,7 +143,7 @@ dissect/target/plugins/apps/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe | |
| 143 143 | 
             
            dissect/target/plugins/apps/webserver/apache.py,sha256=bD6_XObfO7W-cFlLRWyhdwEfw-Y57JBi47rWnXCx-vg,15026
         | 
| 144 144 | 
             
            dissect/target/plugins/apps/webserver/caddy.py,sha256=qZsAK_tILGvroV4SWkDKc-Otwd41bUEtv9H9TuHmt-0,6422
         | 
| 145 145 | 
             
            dissect/target/plugins/apps/webserver/citrix.py,sha256=FEPdBteEJeeGg3B95W_27O9wLJVhenEc5A5fSLDmK18,3044
         | 
| 146 | 
            -
            dissect/target/plugins/apps/webserver/iis.py,sha256= | 
| 146 | 
            +
            dissect/target/plugins/apps/webserver/iis.py,sha256=t92JGTuMbBlUma5BVurdOuzUYvrjpgT8NEHpu9Xz5F0,14734
         | 
| 147 147 | 
             
            dissect/target/plugins/apps/webserver/nginx.py,sha256=WA5soi1FU1c44oHRcyOoHK3gH8Jzc_Qi5uXcimDYukw,4129
         | 
| 148 148 | 
             
            dissect/target/plugins/apps/webserver/webserver.py,sha256=a7a2lLrhsa9c1AXnwiLP-tqVv-IUbmaVaSZI5S0fKa8,1500
         | 
| 149 149 | 
             
            dissect/target/plugins/child/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| @@ -201,7 +201,7 @@ dissect/target/plugins/os/unix/bsd/osx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC | |
| 201 201 | 
             
            dissect/target/plugins/os/unix/bsd/osx/_os.py,sha256=KvP7YJ7apVwoIop7MR-8q5QbVGoB6MdR42l6ssEe6es,4081
         | 
| 202 202 | 
             
            dissect/target/plugins/os/unix/bsd/osx/user.py,sha256=qopB0s3n7e6Q7NjWzn8Z-dKtDtU7e6In4Vm7hIvvedo,2322
         | 
| 203 203 | 
             
            dissect/target/plugins/os/unix/esxi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 204 | 
            -
            dissect/target/plugins/os/unix/esxi/_os.py,sha256= | 
| 204 | 
            +
            dissect/target/plugins/os/unix/esxi/_os.py,sha256=jqw71St-L_BiREai8bw27oFOrLK4_GuEDLUTK5FMGLU,17498
         | 
| 205 205 | 
             
            dissect/target/plugins/os/unix/linux/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 206 206 | 
             
            dissect/target/plugins/os/unix/linux/_os.py,sha256=YJYwuq_iAinOrPqTE49Q4DLYMWBeRCly1uTbDvPhp6Q,2796
         | 
| 207 207 | 
             
            dissect/target/plugins/os/unix/linux/cmdline.py,sha256=XIvaTL42DzeQGhqHN_RTMI5g8hbI2_wjzb7KZ0kPOM0,1591
         | 
| @@ -261,7 +261,7 @@ dissect/target/plugins/os/windows/locale.py,sha256=yXVdclpUqss9h8Nq7N4kg3OHwWGDf | |
| 261 261 | 
             
            dissect/target/plugins/os/windows/notifications.py,sha256=64xHHueHwtJCc8RTAF70oa0RxvqfCu_DBPWRSZBnYZc,17386
         | 
| 262 262 | 
             
            dissect/target/plugins/os/windows/prefetch.py,sha256=5hRxdIP9sIV5Q9TAScMjLbl_mImZ37abvdE_pAd6rh4,10398
         | 
| 263 263 | 
             
            dissect/target/plugins/os/windows/recyclebin.py,sha256=4GSj0Q3YvONufnqANbnG0ffiMQyToCiL5s35Wmu4JOQ,4898
         | 
| 264 | 
            -
            dissect/target/plugins/os/windows/registry.py,sha256= | 
| 264 | 
            +
            dissect/target/plugins/os/windows/registry.py,sha256=EfqUkgbzaqTuq1kIPYNG1TfvJxhJE5X-TEjV3K_xsPU,12814
         | 
| 265 265 | 
             
            dissect/target/plugins/os/windows/sam.py,sha256=Es_8ROQ6R6-akuTtegCdsJHXzZJNhzgoFuS8y9xNN8E,15267
         | 
| 266 266 | 
             
            dissect/target/plugins/os/windows/services.py,sha256=_6YkuoZD8LUxk72R3n1p1bOBab3A1wszdB1NuPavIGM,6037
         | 
| 267 267 | 
             
            dissect/target/plugins/os/windows/sru.py,sha256=sOM7CyMkW8XIXzI75GL69WoqUrSK2X99TFIfdQR2D64,17767
         | 
| @@ -280,9 +280,9 @@ dissect/target/plugins/os/windows/exchange/__init__.py,sha256=47DEQpj8HBSa-_TImW | |
| 280 280 | 
             
            dissect/target/plugins/os/windows/exchange/exchange.py,sha256=ofoapuDQXefIX4sTzwNboyk5RztN2JEyw1OWl5cx-wo,1564
         | 
| 281 281 | 
             
            dissect/target/plugins/os/windows/log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 282 282 | 
             
            dissect/target/plugins/os/windows/log/amcache.py,sha256=TabtjNx9Ve-u-Fn0K95A0v_SLGzn2YeNPHrcQvjVKJc,5877
         | 
| 283 | 
            -
            dissect/target/plugins/os/windows/log/etl.py,sha256= | 
| 283 | 
            +
            dissect/target/plugins/os/windows/log/etl.py,sha256=Rau1zqPJ5LL91j59nC4Jg81KF2t1uuMx-oQp9JK0a00,7049
         | 
| 284 284 | 
             
            dissect/target/plugins/os/windows/log/evt.py,sha256=vK9XHc-hOxf6BbLKMNzGNlbCRWN2nlksQoCLdHqPgnw,7049
         | 
| 285 | 
            -
            dissect/target/plugins/os/windows/log/evtx.py,sha256= | 
| 285 | 
            +
            dissect/target/plugins/os/windows/log/evtx.py,sha256=C1JM64GW7z82qT9K9hIiyCv0EFxszFD9GVvtUZUHdL4,6096
         | 
| 286 286 | 
             
            dissect/target/plugins/os/windows/log/pfro.py,sha256=BCjg3OZzkIP4-HzRa1b1dPkDv_B4sbd78fl40obUVkM,2706
         | 
| 287 287 | 
             
            dissect/target/plugins/os/windows/log/schedlgu.py,sha256=vzMOcCSrGRTMNQUZzvyQorZzbTNgs1UJiPe0zeOOupQ,5515
         | 
| 288 288 | 
             
            dissect/target/plugins/os/windows/regf/7zip.py,sha256=Vc336zhS6R8W98GGlLtPJ_OR0vEP014QnBtYwbx_HUo,3217
         | 
| @@ -331,10 +331,10 @@ dissect/target/volumes/luks.py,sha256=OmCMsw6rCUXG1_plnLVLTpsvE1n_6WtoRUGQbpmu1z | |
| 331 331 | 
             
            dissect/target/volumes/lvm.py,sha256=wwQVR9I3G9YzmY6UxFsH2Y4MXGBcKL9aayWGCDTiWMU,2269
         | 
| 332 332 | 
             
            dissect/target/volumes/md.py,sha256=j1K1iKmspl0C_OJFc7-Q1BMWN2OCC5EVANIgVlJ_fIE,1673
         | 
| 333 333 | 
             
            dissect/target/volumes/vmfs.py,sha256=-LoUbn9WNwTtLi_4K34uV_-wDw2W5hgaqxZNj4UmqAQ,1730
         | 
| 334 | 
            -
            dissect.target-3.16. | 
| 335 | 
            -
            dissect.target-3.16. | 
| 336 | 
            -
            dissect.target-3.16. | 
| 337 | 
            -
            dissect.target-3.16. | 
| 338 | 
            -
            dissect.target-3.16. | 
| 339 | 
            -
            dissect.target-3.16. | 
| 340 | 
            -
            dissect.target-3.16. | 
| 334 | 
            +
            dissect.target-3.16.dev31.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
         | 
| 335 | 
            +
            dissect.target-3.16.dev31.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
         | 
| 336 | 
            +
            dissect.target-3.16.dev31.dist-info/METADATA,sha256=bQJydAA40PRNfKgAuW4LJCissMW3rELgyfBIyapzadU,11107
         | 
| 337 | 
            +
            dissect.target-3.16.dev31.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
         | 
| 338 | 
            +
            dissect.target-3.16.dev31.dist-info/entry_points.txt,sha256=tvFPa-Ap-gakjaPwRc6Fl6mxHzxEZ_arAVU-IUYeo_s,447
         | 
| 339 | 
            +
            dissect.target-3.16.dev31.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
         | 
| 340 | 
            +
            dissect.target-3.16.dev31.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
    
        {dissect.target-3.16.dev29.dist-info → dissect.target-3.16.dev31.dist-info}/entry_points.txt
    RENAMED
    
    | 
            File without changes
         | 
| 
            File without changes
         |