dissect.target 3.19.dev33__py3-none-any.whl → 3.19.dev35__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/helpers/config.py +22 -7
- dissect/target/plugins/filesystem/yara.py +1 -1
- dissect/target/target.py +3 -2
- dissect/target/tools/shell.py +34 -2
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/METADATA +1 -1
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/RECORD +11 -11
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/COPYRIGHT +0 -0
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/LICENSE +0 -0
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/WHEEL +0 -0
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/entry_points.txt +0 -0
- {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/top_level.txt +0 -0
    
        dissect/target/helpers/config.py
    CHANGED
    
    | @@ -1,27 +1,35 @@ | |
| 1 | 
            +
            from __future__ import annotations
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            import ast
         | 
| 2 4 | 
             
            import importlib.machinery
         | 
| 3 5 | 
             
            import importlib.util
         | 
| 4 6 | 
             
            import logging
         | 
| 5 7 | 
             
            from pathlib import Path
         | 
| 6 8 | 
             
            from types import ModuleType
         | 
| 7 | 
            -
            from typing import Optional, Union
         | 
| 8 9 |  | 
| 9 10 | 
             
            log = logging.getLogger(__name__)
         | 
| 10 11 |  | 
| 11 12 | 
             
            CONFIG_NAME = ".targetcfg.py"
         | 
| 12 13 |  | 
| 13 14 |  | 
| 14 | 
            -
            def load( | 
| 15 | 
            +
            def load(paths: list[Path | str] | Path | str | None) -> ModuleType:
         | 
| 16 | 
            +
                """Attempt to load one configuration from the provided path(s)."""
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                if isinstance(paths, Path) or isinstance(paths, str):
         | 
| 19 | 
            +
                    paths = [paths]
         | 
| 20 | 
            +
             | 
| 15 21 | 
             
                config_spec = importlib.machinery.ModuleSpec("config", None)
         | 
| 16 22 | 
             
                config = importlib.util.module_from_spec(config_spec)
         | 
| 17 | 
            -
                config_file = _find_config_file( | 
| 23 | 
            +
                config_file = _find_config_file(paths)
         | 
| 24 | 
            +
             | 
| 18 25 | 
             
                if config_file:
         | 
| 19 26 | 
             
                    config_values = _parse_ast(config_file.read_bytes())
         | 
| 20 27 | 
             
                    config.__dict__.update(config_values)
         | 
| 28 | 
            +
             | 
| 21 29 | 
             
                return config
         | 
| 22 30 |  | 
| 23 31 |  | 
| 24 | 
            -
            def _parse_ast(code: str) -> dict[str,  | 
| 32 | 
            +
            def _parse_ast(code: str) -> dict[str, str | int]:
         | 
| 25 33 | 
             
                # Only allow basic value assignments for backwards compatibility
         | 
| 26 34 | 
             
                obj = {}
         | 
| 27 35 |  | 
| @@ -49,15 +57,19 @@ def _parse_ast(code: str) -> dict[str, Union[str, int]]: | |
| 49 57 | 
             
                return obj
         | 
| 50 58 |  | 
| 51 59 |  | 
| 52 | 
            -
            def _find_config_file( | 
| 53 | 
            -
                """Find a config file anywhere in the given path and return it.
         | 
| 60 | 
            +
            def _find_config_file(paths: list[Path | str] | None) -> Path | None:
         | 
| 61 | 
            +
                """Find a config file anywhere in the given path(s) and return it.
         | 
| 54 62 |  | 
| 55 63 | 
             
                This algorithm allows parts of the path to not exist or the last part to be a filename.
         | 
| 56 64 | 
             
                It also does not look in the root directory ('/') for config files.
         | 
| 57 65 | 
             
                """
         | 
| 58 66 |  | 
| 67 | 
            +
                if not paths:
         | 
| 68 | 
            +
                    return
         | 
| 69 | 
            +
             | 
| 59 70 | 
             
                config_file = None
         | 
| 60 | 
            -
             | 
| 71 | 
            +
             | 
| 72 | 
            +
                for path in paths:
         | 
| 61 73 | 
             
                    path = Path(path)
         | 
| 62 74 | 
             
                    cur_path = path.absolute()
         | 
| 63 75 |  | 
| @@ -69,4 +81,7 @@ def _find_config_file(path: Optional[Union[Path, str]]) -> Optional[Path]: | |
| 69 81 | 
             
                            config_file = cur_config
         | 
| 70 82 | 
             
                        cur_path = cur_path.parent
         | 
| 71 83 |  | 
| 84 | 
            +
                    if config_file:
         | 
| 85 | 
            +
                        break
         | 
| 86 | 
            +
             | 
| 72 87 | 
             
                return config_file
         | 
| @@ -45,7 +45,7 @@ class YaraPlugin(Plugin): | |
| 45 45 |  | 
| 46 46 | 
             
                @arg("-r", "--rules", required=True, nargs="*", help="path(s) to YARA rule file(s) or folder(s)")
         | 
| 47 47 | 
             
                @arg("-p", "--path", default="/", help="path on target(s) to recursively scan")
         | 
| 48 | 
            -
                @arg("-m", "--max-size", default=DEFAULT_MAX_SCAN_SIZE, help="maximum file size in bytes to scan")
         | 
| 48 | 
            +
                @arg("-m", "--max-size", type=int, default=DEFAULT_MAX_SCAN_SIZE, help="maximum file size in bytes to scan")
         | 
| 49 49 | 
             
                @arg("-c", "--check", default=False, action="store_true", help="check if every YARA rule is valid")
         | 
| 50 50 | 
             
                @export(record=YaraMatchRecord)
         | 
| 51 51 | 
             
                def yara(
         | 
    
        dissect/target/target.py
    CHANGED
    
    | @@ -87,9 +87,10 @@ class Target: | |
| 87 87 | 
             
                    self._applied = False
         | 
| 88 88 |  | 
| 89 89 | 
             
                    try:
         | 
| 90 | 
            -
                        self._config = config.load(self.path)
         | 
| 90 | 
            +
                        self._config = config.load([self.path, os.getcwd()])
         | 
| 91 91 | 
             
                    except Exception as e:
         | 
| 92 | 
            -
                        self.log. | 
| 92 | 
            +
                        self.log.warning("Error loading config file: %s", self.path)
         | 
| 93 | 
            +
                        self.log.debug("", exc_info=e)
         | 
| 93 94 | 
             
                        self._config = config.load(None)  # This loads an empty config.
         | 
| 94 95 |  | 
| 95 96 | 
             
                    # Fill the disks and/or volumes and/or filesystems and apply() will
         | 
    
        dissect/target/tools/shell.py
    CHANGED
    
    | @@ -58,6 +58,7 @@ try: | |
| 58 58 | 
             
            except ImportError:
         | 
| 59 59 | 
             
                # Readline is not available on Windows
         | 
| 60 60 | 
             
                log.warning("Readline module is not available")
         | 
| 61 | 
            +
                readline = None
         | 
| 61 62 |  | 
| 62 63 | 
             
            # ['mode', 'addr', 'dev', 'nlink', 'uid', 'gid', 'size', 'atime', 'mtime', 'ctime']
         | 
| 63 64 | 
             
            STAT_TEMPLATE = """  File: {path} {symlink}
         | 
| @@ -111,12 +112,43 @@ class TargetCmd(cmd.Cmd): | |
| 111 112 |  | 
| 112 113 | 
             
                CMD_PREFIX = "cmd_"
         | 
| 113 114 |  | 
| 115 | 
            +
                DEFAULT_HISTFILE = "~/.dissect_history"
         | 
| 116 | 
            +
                DEFAULT_HISTFILESIZE = 10_000
         | 
| 117 | 
            +
                DEFAULT_HISTDIR = None
         | 
| 118 | 
            +
                DEFAULT_HISTDIRFMT = ".dissect_history_{uid}_{target}"
         | 
| 119 | 
            +
             | 
| 114 120 | 
             
                def __init__(self, target: Target):
         | 
| 115 121 | 
             
                    cmd.Cmd.__init__(self)
         | 
| 116 122 | 
             
                    self.target = target
         | 
| 117 123 | 
             
                    self.debug = False
         | 
| 118 124 | 
             
                    self.identchars += "."
         | 
| 119 125 |  | 
| 126 | 
            +
                    self.histfilesize = getattr(target._config, "HISTFILESIZE", self.DEFAULT_HISTFILESIZE)
         | 
| 127 | 
            +
                    self.histdir = getattr(target._config, "HISTDIR", self.DEFAULT_HISTDIR)
         | 
| 128 | 
            +
             | 
| 129 | 
            +
                    if self.histdir:
         | 
| 130 | 
            +
                        self.histdirfmt = getattr(target._config, "HISTDIRFMT", self.DEFAULT_HISTDIRFMT)
         | 
| 131 | 
            +
                        self.histfile = pathlib.Path(self.histdir).resolve() / pathlib.Path(
         | 
| 132 | 
            +
                            self.histdirfmt.format(uid=os.getuid(), target=target.name)
         | 
| 133 | 
            +
                        )
         | 
| 134 | 
            +
                    else:
         | 
| 135 | 
            +
                        self.histfile = pathlib.Path(getattr(target._config, "HISTFILE", self.DEFAULT_HISTFILE)).expanduser()
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                def preloop(self) -> None:
         | 
| 138 | 
            +
                    if readline and self.histfile.exists():
         | 
| 139 | 
            +
                        try:
         | 
| 140 | 
            +
                            readline.read_history_file(self.histfile)
         | 
| 141 | 
            +
                        except Exception as e:
         | 
| 142 | 
            +
                            log.debug("Error reading history file: %s", e)
         | 
| 143 | 
            +
             | 
| 144 | 
            +
                def postloop(self) -> None:
         | 
| 145 | 
            +
                    if readline:
         | 
| 146 | 
            +
                        readline.set_history_length(self.histfilesize)
         | 
| 147 | 
            +
                        try:
         | 
| 148 | 
            +
                            readline.write_history_file(self.histfile)
         | 
| 149 | 
            +
                        except Exception as e:
         | 
| 150 | 
            +
                            log.debug("Error writing history file: %s", e)
         | 
| 151 | 
            +
             | 
| 120 152 | 
             
                def __getattr__(self, attr: str) -> Any:
         | 
| 121 153 | 
             
                    if attr.startswith("help_"):
         | 
| 122 154 | 
             
                        _, _, command = attr.partition("_")
         | 
| @@ -1241,10 +1273,11 @@ def run_cli(cli: cmd.Cmd) -> None: | |
| 1241 1273 | 
             
                        # Print an empty newline on exit
         | 
| 1242 1274 | 
             
                        print()
         | 
| 1243 1275 | 
             
                        return
         | 
| 1276 | 
            +
             | 
| 1244 1277 | 
             
                    except KeyboardInterrupt:
         | 
| 1245 1278 | 
             
                        # Add a line when pressing ctrl+c, so the next one starts at a new line
         | 
| 1246 1279 | 
             
                        print()
         | 
| 1247 | 
            -
             | 
| 1280 | 
            +
             | 
| 1248 1281 | 
             
                    except Exception as e:
         | 
| 1249 1282 | 
             
                        if cli.debug:
         | 
| 1250 1283 | 
             
                            log.exception(e)
         | 
| @@ -1252,7 +1285,6 @@ def run_cli(cli: cmd.Cmd) -> None: | |
| 1252 1285 | 
             
                            log.info(e)
         | 
| 1253 1286 | 
             
                            print(f"*** Unhandled error: {e}")
         | 
| 1254 1287 | 
             
                            print("If you wish to see the full debug trace, enable debug mode.")
         | 
| 1255 | 
            -
                        pass
         | 
| 1256 1288 |  | 
| 1257 1289 |  | 
| 1258 1290 | 
             
            @catch_sigpipe
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.1
         | 
| 2 2 | 
             
            Name: dissect.target
         | 
| 3 | 
            -
            Version: 3.19. | 
| 3 | 
            +
            Version: 3.19.dev35
         | 
| 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
         | 
| @@ -5,7 +5,7 @@ dissect/target/filesystem.py,sha256=G1gbOUpnQZyovubYGEUKgaDV0eHH5vE83-0gTc5PZAM, | |
| 5 5 | 
             
            dissect/target/loader.py,sha256=I8WNzDA0SMy42F7zfyBcSKj_VKNv64213WUvtGZ77qE,7374
         | 
| 6 6 | 
             
            dissect/target/plugin.py,sha256=HAN8maaDt-Rlqt8Rr1IW7gXQpzNQZjCVz-i4aSPphSw,48677
         | 
| 7 7 | 
             
            dissect/target/report.py,sha256=06uiP4MbNI8cWMVrC1SasNS-Yg6ptjVjckwj8Yhe0Js,7958
         | 
| 8 | 
            -
            dissect/target/target.py,sha256= | 
| 8 | 
            +
            dissect/target/target.py,sha256=nqd5OuVTwYR7XSzlMp7SHQoRCgZD_Z7QshnEEKcX-tw,32426
         | 
| 9 9 | 
             
            dissect/target/volume.py,sha256=aQZAJiny8jjwkc9UtwIRwy7nINXjCxwpO-_UDfh6-BA,15801
         | 
| 10 10 | 
             
            dissect/target/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 11 11 | 
             
            dissect/target/containers/asdf.py,sha256=DJp0QEFwUjy2MFwKYcYqIR_BS1fQT1Yi9Kcmqt0aChM,1366
         | 
| @@ -45,7 +45,7 @@ dissect/target/filesystems/xfs.py,sha256=kIyFGKYlyFYC7H3jaEv-lNKtBW4ZkD92H0WpfGc | |
| 45 45 | 
             
            dissect/target/filesystems/zip.py,sha256=WT1bQhzX_1MXXVZTKrJniae4xqRqMZ8FsfbvhgGQRTQ,4462
         | 
| 46 46 | 
             
            dissect/target/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 47 47 | 
             
            dissect/target/helpers/cache.py,sha256=TXlJBdFRz6V9zKs903am4Yawr0maYw5kZY0RqklDQJM,8568
         | 
| 48 | 
            -
            dissect/target/helpers/config.py,sha256= | 
| 48 | 
            +
            dissect/target/helpers/config.py,sha256=RMHnIuKJHINHiLrvKN3EyA0jFA1o6-pbeaycG8Pgrp8,2596
         | 
| 49 49 | 
             
            dissect/target/helpers/configutil.py,sha256=AEnkMQ0e6PncvCqGa-ACzBQWQBhMGBCzO5qzGJtRu60,27644
         | 
| 50 50 | 
             
            dissect/target/helpers/cyber.py,sha256=WnJlk-HqAETmDAgLq92JPxyDLxvzSoFV_WrO-odVKBI,16805
         | 
| 51 51 | 
             
            dissect/target/helpers/descriptor_extensions.py,sha256=uT8GwznfDAiIgMM7JKKOY0PXKMv2c0GCqJTCkWFgops,2605
         | 
| @@ -164,7 +164,7 @@ dissect/target/plugins/filesystem/acquire_hash.py,sha256=OVxI19-Bl1tdqCiFMscFMLm | |
| 164 164 | 
             
            dissect/target/plugins/filesystem/icat.py,sha256=bOMi04IlljnKwxTWTZJKtK7RxKnabFu3WcXyUwzkE-4,4090
         | 
| 165 165 | 
             
            dissect/target/plugins/filesystem/resolver.py,sha256=HfyASUFV4F9uD-yFXilFpPTORAsRDvdmTvuYHgOaOWg,4776
         | 
| 166 166 | 
             
            dissect/target/plugins/filesystem/walkfs.py,sha256=e8HEZcV5Wiua26FGWL3xgiQ_PIhcNvGI5KCdsAx2Nmo,2298
         | 
| 167 | 
            -
            dissect/target/plugins/filesystem/yara.py,sha256= | 
| 167 | 
            +
            dissect/target/plugins/filesystem/yara.py,sha256=zh4hU3L_egddLqDeaHDVuCWYhTlNzPYPVak36Q6IMxI,6621
         | 
| 168 168 | 
             
            dissect/target/plugins/filesystem/ntfs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 169 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
         | 
| @@ -331,7 +331,7 @@ dissect/target/tools/logging.py,sha256=5ZnumtMWLyslxfrUGZ4ntRyf3obOOhmn8SBjKfdLc | |
| 331 331 | 
             
            dissect/target/tools/mount.py,sha256=L_0tSmiBdW4aSaF0vXjB0bAkTC0kmT2N1hrbW6s5Jow,3254
         | 
| 332 332 | 
             
            dissect/target/tools/query.py,sha256=ONHu2FVomLccikb84qBrlhNmEfRoHYFQMcahk_y2c9A,15580
         | 
| 333 333 | 
             
            dissect/target/tools/reg.py,sha256=FDsiBBDxjWVUBTRj8xn82vZe-J_d9piM-TKS3PHZCcM,3193
         | 
| 334 | 
            -
            dissect/target/tools/shell.py,sha256= | 
| 334 | 
            +
            dissect/target/tools/shell.py,sha256=sjoc4nI9fsU5ZG7nDPNZvE-RtIPTwREbVdbg8WA3XTo,46442
         | 
| 335 335 | 
             
            dissect/target/tools/utils.py,sha256=sQizexY3ui5vmWw4KOBLg5ecK3TPFjD-uxDqRn56ZTY,11304
         | 
| 336 336 | 
             
            dissect/target/tools/yara.py,sha256=70k-2VMulf1EdkX03nCACzejaOEcsFHOyX-4E40MdQU,2044
         | 
| 337 337 | 
             
            dissect/target/tools/dump/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| @@ -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=7ShPtusuLGaIv27SvEETtgsuoQyAa4iAAeOR1NEaajI,1689
         | 
| 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.dev35.dist-info/COPYRIGHT,sha256=m-9ih2RVhMiXHI2bf_oNSSgHgkeIvaYRVfKTwFbnJPA,301
         | 
| 350 | 
            +
            dissect.target-3.19.dev35.dist-info/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
         | 
| 351 | 
            +
            dissect.target-3.19.dev35.dist-info/METADATA,sha256=3ApP47TWFjPe5wV6_fuejtFbpr7YL-bwmvPePNKfN1M,12719
         | 
| 352 | 
            +
            dissect.target-3.19.dev35.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
         | 
| 353 | 
            +
            dissect.target-3.19.dev35.dist-info/entry_points.txt,sha256=BWuxAb_6AvUAQpIQOQU0IMTlaF6TDht2AIZK8bHd-zE,492
         | 
| 354 | 
            +
            dissect.target-3.19.dev35.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
         | 
| 355 | 
            +
            dissect.target-3.19.dev35.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
    
        {dissect.target-3.19.dev33.dist-info → dissect.target-3.19.dev35.dist-info}/entry_points.txt
    RENAMED
    
    | 
            File without changes
         | 
| 
            File without changes
         |