dissect.target 3.19.dev57__py3-none-any.whl → 3.20__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. dissect/target/container.py +1 -1
  2. dissect/target/exceptions.py +6 -5
  3. dissect/target/filesystem.py +2 -2
  4. dissect/target/filesystems/btrfs.py +14 -5
  5. dissect/target/filesystems/config.py +5 -1
  6. dissect/target/filesystems/extfs.py +5 -4
  7. dissect/target/filesystems/fat.py +22 -16
  8. dissect/target/filesystems/ffs.py +11 -4
  9. dissect/target/filesystems/jffs.py +12 -7
  10. dissect/target/filesystems/ntfs.py +22 -6
  11. dissect/target/filesystems/overlay.py +14 -4
  12. dissect/target/filesystems/smb.py +3 -3
  13. dissect/target/filesystems/squashfs.py +4 -4
  14. dissect/target/filesystems/vmfs.py +4 -4
  15. dissect/target/filesystems/xfs.py +15 -8
  16. dissect/target/helpers/compat/path_common.py +5 -5
  17. dissect/target/helpers/configutil.py +128 -32
  18. dissect/target/helpers/cyber.py +2 -0
  19. dissect/target/helpers/data/windowsZones.xml +19 -23
  20. dissect/target/helpers/docs.py +1 -1
  21. dissect/target/helpers/keychain.py +2 -0
  22. dissect/target/helpers/mount.py +2 -1
  23. dissect/target/helpers/record.py +29 -2
  24. dissect/target/helpers/record_modifier.py +5 -1
  25. dissect/target/helpers/regutil.py +56 -26
  26. dissect/target/loader.py +1 -1
  27. dissect/target/loaders/mqtt.py +104 -9
  28. dissect/target/loaders/proxmox.py +68 -0
  29. dissect/target/loaders/vma.py +1 -1
  30. dissect/target/loaders/xva.py +1 -1
  31. dissect/target/plugin.py +24 -21
  32. dissect/target/plugins/apps/av/mcafee.py +2 -0
  33. dissect/target/plugins/apps/av/sophos.py +2 -0
  34. dissect/target/plugins/apps/av/trendmicro.py +2 -0
  35. dissect/target/plugins/apps/browser/chromium.py +27 -6
  36. dissect/target/plugins/apps/container/docker.py +48 -32
  37. dissect/target/plugins/apps/editor/__init__.py +0 -0
  38. dissect/target/plugins/apps/editor/editor.py +23 -0
  39. dissect/target/plugins/apps/{texteditor → editor}/windowsnotepad.py +40 -31
  40. dissect/target/plugins/apps/other/__init__.py +0 -0
  41. dissect/target/plugins/apps/other/env.py +56 -0
  42. dissect/target/plugins/apps/shell/powershell.py +6 -2
  43. dissect/target/plugins/apps/shell/wget.py +91 -0
  44. dissect/target/plugins/apps/ssh/openssh.py +2 -0
  45. dissect/target/plugins/apps/ssh/opensshd.py +2 -0
  46. dissect/target/plugins/apps/virtualization/__init__.py +0 -0
  47. dissect/target/plugins/apps/virtualization/vmware_workstation.py +61 -0
  48. dissect/target/plugins/apps/vpn/wireguard.py +9 -9
  49. dissect/target/plugins/apps/webhosting/cpanel.py +2 -0
  50. dissect/target/plugins/apps/webserver/caddy.py +2 -0
  51. dissect/target/plugins/apps/webserver/nginx.py +2 -0
  52. dissect/target/plugins/child/esxi.py +3 -1
  53. dissect/target/plugins/child/parallels.py +68 -0
  54. dissect/target/plugins/child/proxmox.py +23 -0
  55. dissect/target/plugins/child/virtuozzo.py +12 -8
  56. dissect/target/plugins/child/vmware_workstation.py +23 -8
  57. dissect/target/plugins/filesystem/acquire_hash.py +2 -1
  58. dissect/target/plugins/filesystem/icat.py +15 -11
  59. dissect/target/plugins/filesystem/ntfs/mft.py +10 -6
  60. dissect/target/plugins/filesystem/ntfs/mft_timeline.py +3 -1
  61. dissect/target/plugins/filesystem/ntfs/usnjrnl.py +2 -0
  62. dissect/target/plugins/filesystem/ntfs/utils.py +3 -1
  63. dissect/target/plugins/filesystem/unix/suid.py +4 -1
  64. dissect/target/plugins/filesystem/walkfs.py +2 -0
  65. dissect/target/plugins/general/example.py +2 -2
  66. dissect/target/plugins/general/loaders.py +18 -5
  67. dissect/target/plugins/general/network.py +20 -5
  68. dissect/target/plugins/general/osinfo.py +1 -0
  69. dissect/target/plugins/general/plugins.py +53 -10
  70. dissect/target/plugins/os/unix/_os.py +70 -44
  71. dissect/target/plugins/os/unix/applications.py +78 -0
  72. dissect/target/plugins/os/unix/bsd/citrix/history.py +2 -0
  73. dissect/target/plugins/os/unix/bsd/osx/_os.py +4 -21
  74. dissect/target/plugins/os/unix/bsd/osx/network.py +92 -0
  75. dissect/target/plugins/os/unix/bsd/osx/user.py +4 -0
  76. dissect/target/plugins/os/unix/cronjobs.py +8 -4
  77. dissect/target/plugins/os/unix/etc/etc.py +4 -0
  78. dissect/target/plugins/os/unix/generic.py +2 -0
  79. dissect/target/plugins/os/unix/history.py +27 -25
  80. dissect/target/plugins/os/unix/linux/_os.py +8 -10
  81. dissect/target/plugins/os/unix/linux/cmdline.py +2 -0
  82. dissect/target/plugins/os/unix/linux/debian/apt.py +4 -1
  83. dissect/target/plugins/os/unix/linux/debian/dpkg.py +3 -3
  84. dissect/target/plugins/os/unix/linux/debian/proxmox/__init__.py +0 -0
  85. dissect/target/plugins/os/unix/linux/debian/proxmox/_os.py +141 -0
  86. dissect/target/plugins/os/unix/linux/debian/proxmox/vm.py +29 -0
  87. dissect/target/plugins/os/unix/linux/debian/snap.py +79 -0
  88. dissect/target/plugins/os/unix/linux/environ.py +2 -0
  89. dissect/target/plugins/os/unix/linux/fortios/_os.py +74 -63
  90. dissect/target/plugins/os/unix/linux/fortios/generic.py +2 -0
  91. dissect/target/plugins/os/unix/linux/fortios/locale.py +2 -0
  92. dissect/target/plugins/os/unix/linux/modules.py +2 -0
  93. dissect/target/plugins/os/unix/linux/netstat.py +2 -0
  94. dissect/target/{helpers → plugins/os/unix/linux}/network_managers.py +11 -9
  95. dissect/target/plugins/os/unix/linux/processes.py +2 -0
  96. dissect/target/plugins/os/unix/linux/redhat/yum.py +4 -1
  97. dissect/target/plugins/os/unix/linux/services.py +5 -3
  98. dissect/target/plugins/os/unix/linux/sockets.py +2 -0
  99. dissect/target/plugins/os/unix/linux/suse/zypper.py +4 -1
  100. dissect/target/plugins/os/unix/locale.py +2 -0
  101. dissect/target/plugins/os/unix/locate/gnulocate.py +4 -2
  102. dissect/target/plugins/os/unix/locate/mlocate.py +2 -0
  103. dissect/target/plugins/os/unix/locate/plocate.py +3 -1
  104. dissect/target/plugins/os/unix/log/atop.py +2 -0
  105. dissect/target/plugins/os/unix/log/audit.py +3 -1
  106. dissect/target/plugins/os/unix/log/auth.py +351 -38
  107. dissect/target/plugins/os/unix/log/journal.py +123 -101
  108. dissect/target/plugins/os/unix/log/lastlog.py +5 -3
  109. dissect/target/plugins/os/unix/log/messages.py +51 -27
  110. dissect/target/plugins/os/unix/log/utmp.py +52 -71
  111. dissect/target/plugins/os/unix/packagemanager.py +5 -38
  112. dissect/target/plugins/os/unix/shadow.py +3 -1
  113. dissect/target/plugins/os/unix/trash.py +132 -0
  114. dissect/target/plugins/os/windows/_os.py +22 -41
  115. dissect/target/plugins/os/windows/activitiescache.py +9 -4
  116. dissect/target/plugins/os/windows/adpolicy.py +2 -1
  117. dissect/target/plugins/os/windows/amcache.py +16 -13
  118. dissect/target/plugins/os/windows/defender.py +4 -3
  119. dissect/target/plugins/os/windows/dpapi/keyprovider/credhist.py +3 -0
  120. dissect/target/plugins/os/windows/dpapi/keyprovider/empty.py +3 -0
  121. dissect/target/plugins/os/windows/dpapi/keyprovider/keychain.py +3 -0
  122. dissect/target/plugins/os/windows/dpapi/keyprovider/lsa.py +3 -0
  123. dissect/target/plugins/os/windows/env.py +1 -2
  124. dissect/target/plugins/os/windows/exchange/exchange.py +6 -4
  125. dissect/target/plugins/os/windows/generic.py +68 -19
  126. dissect/target/plugins/os/windows/lnk.py +2 -0
  127. dissect/target/plugins/os/windows/locale.py +9 -3
  128. dissect/target/plugins/os/windows/log/etl.py +5 -4
  129. dissect/target/plugins/os/windows/log/evt.py +12 -8
  130. dissect/target/plugins/os/windows/log/evtx.py +9 -7
  131. dissect/target/plugins/os/windows/log/mssql.py +103 -0
  132. dissect/target/plugins/os/windows/log/pfro.py +2 -1
  133. dissect/target/plugins/os/windows/network.py +380 -0
  134. dissect/target/plugins/os/windows/notifications.py +6 -4
  135. dissect/target/plugins/os/windows/prefetch.py +7 -2
  136. dissect/target/plugins/os/windows/regf/7zip.py +9 -1
  137. dissect/target/plugins/os/windows/regf/applications.py +62 -0
  138. dissect/target/plugins/os/windows/regf/auditpol.py +2 -1
  139. dissect/target/plugins/os/windows/regf/bam.py +3 -1
  140. dissect/target/plugins/os/windows/regf/cit.py +14 -12
  141. dissect/target/plugins/os/windows/regf/clsid.py +6 -3
  142. dissect/target/plugins/os/windows/regf/firewall.py +2 -1
  143. dissect/target/plugins/os/windows/regf/mru.py +9 -8
  144. dissect/target/plugins/os/windows/regf/nethist.py +6 -3
  145. dissect/target/plugins/os/windows/regf/recentfilecache.py +3 -1
  146. dissect/target/plugins/os/windows/regf/regf.py +5 -1
  147. dissect/target/plugins/os/windows/regf/shellbags.py +351 -345
  148. dissect/target/plugins/os/windows/regf/shimcache.py +1 -1
  149. dissect/target/plugins/os/windows/regf/usb.py +2 -1
  150. dissect/target/plugins/os/windows/regf/userassist.py +2 -1
  151. dissect/target/plugins/os/windows/registry.py +11 -0
  152. dissect/target/plugins/os/windows/services.py +3 -2
  153. dissect/target/plugins/os/windows/startupinfo.py +7 -2
  154. dissect/target/plugins/os/windows/syscache.py +5 -2
  155. dissect/target/plugins/os/windows/tasks.py +1 -1
  156. dissect/target/plugins/os/windows/thumbcache.py +11 -5
  157. dissect/target/plugins/os/windows/ual.py +12 -9
  158. dissect/target/plugins/os/windows/wer.py +21 -6
  159. dissect/target/plugins/os/windows/wua_history.py +0 -1
  160. dissect/target/target.py +13 -8
  161. dissect/target/tools/dump/utils.py +4 -0
  162. dissect/target/tools/fsutils.py +1 -1
  163. dissect/target/tools/info.py +1 -1
  164. dissect/target/tools/mount.py +15 -5
  165. dissect/target/tools/query.py +15 -9
  166. dissect/target/tools/shell.py +98 -9
  167. dissect/target/tools/utils.py +7 -7
  168. dissect/target/volume.py +4 -4
  169. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/METADATA +6 -2
  170. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/RECORD +176 -160
  171. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/WHEEL +1 -1
  172. dissect/target/helpers/targetd.py +0 -58
  173. dissect/target/loaders/targetd.py +0 -223
  174. dissect/target/plugins/apps/texteditor/texteditor.py +0 -13
  175. dissect/target/plugins/os/unix/etc.py +0 -9
  176. /dissect/target/plugins/apps/{texteditor → database}/__init__.py +0 -0
  177. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/COPYRIGHT +0 -0
  178. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/LICENSE +0 -0
  179. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/entry_points.txt +0 -0
  180. {dissect.target-3.19.dev57.dist-info → dissect.target-3.20.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,62 @@
1
+ from datetime import datetime
2
+ from typing import Iterator
3
+
4
+ from dissect.target.exceptions import UnsupportedPluginError
5
+ from dissect.target.helpers.record import WindowsApplicationRecord
6
+ from dissect.target.plugin import Plugin, export
7
+ from dissect.target.target import Target
8
+
9
+
10
+ class WindowsApplicationsPlugin(Plugin):
11
+ """Windows Applications plugin."""
12
+
13
+ def __init__(self, target: Target):
14
+ super().__init__(target)
15
+ self.keys = list(self.target.registry.keys("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"))
16
+
17
+ def check_compatible(self) -> None:
18
+ if not self.target.has_function("registry"):
19
+ raise UnsupportedPluginError("No Windows registry found")
20
+
21
+ if not self.keys:
22
+ raise UnsupportedPluginError("No 'Uninstall' registry keys found")
23
+
24
+ @export(record=WindowsApplicationRecord)
25
+ def applications(self) -> Iterator[WindowsApplicationRecord]:
26
+ """Yields currently installed applications from the Windows registry.
27
+
28
+ Use the Windows eventlog plugin (``evtx``, ``evt``) to parse install and uninstall events
29
+ of applications and services (e.g. ``4697``, ``110707``, ``1034`` and ``11724``).
30
+
31
+ Resources:
32
+ - https://learn.microsoft.com/en-us/windows/win32/msi/uninstall-registry-key
33
+
34
+ Yields ``WindowsApplicationRecord`` records with the following fields:
35
+
36
+ .. code-block:: text
37
+
38
+ ts_modified (datetime): timestamp when the installation was modified according to the registry
39
+ ts_installed (datetime): timestamp when the application was installed according to the application
40
+ name (string): name of the application
41
+ version (string): version of the application
42
+ author (string): author of the application
43
+ type (string): type of the application, either user or system
44
+ path (string): path to the installed location or installer of the application
45
+ """
46
+ for uninstall in self.keys:
47
+ for app in uninstall.subkeys():
48
+ values = {value.name: value.value for value in app.values()}
49
+
50
+ if install_date := values.get("InstallDate"):
51
+ install_date = datetime.strptime(install_date, "%Y%m%d")
52
+
53
+ yield WindowsApplicationRecord(
54
+ ts_modified=app.ts,
55
+ ts_installed=install_date,
56
+ name=values.get("DisplayName") or app.name,
57
+ version=values.get("DisplayVersion"),
58
+ author=values.get("Publisher"),
59
+ type="system" if values.get("SystemComponent") or not values else "user",
60
+ path=values.get("DisplayIcon") or values.get("InstallLocation") or values.get("InstallSource"),
61
+ _target=self.target,
62
+ )
@@ -1,4 +1,5 @@
1
1
  import io
2
+ from typing import Iterator
2
3
 
3
4
  from dissect.cstruct import cstruct
4
5
 
@@ -138,7 +139,7 @@ class AuditpolPlugin(Plugin):
138
139
  raise UnsupportedPluginError(f"Registry key {self.KEY} not found")
139
140
 
140
141
  @export(record=AuditPolicyRecord)
141
- def auditpol(self):
142
+ def auditpol(self) -> Iterator[AuditPolicyRecord]:
142
143
  """Return audit policy settings from the registry.
143
144
 
144
145
  For Windows, the audit policy settings are stored in the HKEY_LOCAL_MACHINE\\Security\\Policy\\PolAdtEv registry
@@ -1,3 +1,5 @@
1
+ from typing import Iterator
2
+
1
3
  from dissect.cstruct import cstruct
2
4
  from dissect.util.ts import wintimestamp
3
5
 
@@ -36,7 +38,7 @@ class BamDamPlugin(Plugin):
36
38
  raise UnsupportedPluginError("No bam or dam registry keys not found")
37
39
 
38
40
  @export(record=BamDamRecord)
39
- def bam(self):
41
+ def bam(self) -> Iterator[BamDamRecord]:
40
42
  """Parse bam and dam registry keys.
41
43
 
42
44
  Yields BamDamRecords with fields:
@@ -1,12 +1,10 @@
1
- # Resources:
2
- # - generaltel.dll
3
- # - win32k.sys (Windows 7)
4
- # - win32kbase.sys (Windows 10)
1
+ from __future__ import annotations
5
2
 
6
3
  import datetime
7
4
  import struct
8
5
  from binascii import crc32
9
6
  from io import BytesIO
7
+ from typing import Iterator, Union, get_args
10
8
 
11
9
  from dissect.cstruct import cstruct
12
10
  from dissect.util.compression import lznt1
@@ -20,6 +18,10 @@ from dissect.target.helpers.record import (
20
18
  )
21
19
  from dissect.target.plugin import Plugin, export
22
20
 
21
+ # Resources:
22
+ # - generaltel.dll
23
+ # - win32k.sys (Windows 7)
24
+ # - win32kbase.sys (Windows 10)
23
25
  cit_def = """
24
26
  typedef QWORD FILETIME;
25
27
 
@@ -353,7 +355,7 @@ CITProgramBitmapForegroundRecord = TargetRecordDescriptor(
353
355
  )
354
356
 
355
357
 
356
- CIT_RECORDS = [
358
+ CITRecords = Union[
357
359
  CITSystemRecord,
358
360
  CITSystemBitmapDisplayPowerRecord,
359
361
  CITSystemBitmapDisplayRequestChangeRecord,
@@ -602,7 +604,7 @@ class ProgramDataBitmaps(BaseUseDataBitmaps):
602
604
  self.foreground = self._parse_bitmap(0)
603
605
 
604
606
 
605
- def decode_name(name):
607
+ def decode_name(name: str) -> bytes:
606
608
  """Decode the registry key name.
607
609
 
608
610
  The CIT key name in the registry has some strange encoding.
@@ -642,8 +644,8 @@ class CITPlugin(Plugin):
642
644
  if not len(list(self.target.registry.keys(self.KEY))) > 0:
643
645
  raise UnsupportedPluginError("No CIT registry key found")
644
646
 
645
- @export(record=CIT_RECORDS)
646
- def cit(self):
647
+ @export(record=get_args(CITRecords))
648
+ def cit(self) -> Iterator[CITRecords]:
647
649
  """Return CIT data from the registry for executed executable information.
648
650
 
649
651
  CIT data is stored at HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CIT\\System.
@@ -772,7 +774,7 @@ class CITPlugin(Plugin):
772
774
  self.target.log.exception("Failed to parse CIT value: %s", value.name)
773
775
 
774
776
  @export(record=CITPostUpdateUseInfoRecord)
775
- def puu(self):
777
+ def puu(self) -> Iterator[CITPostUpdateUseInfoRecord]:
776
778
  """Parse CIT PUU (Post Update Usage) data from the registry.
777
779
 
778
780
  Generally only available since Windows 10.
@@ -823,7 +825,7 @@ class CITPlugin(Plugin):
823
825
  )
824
826
 
825
827
  @export(record=[CITDPRecord, CITDPDurationRecord])
826
- def dp(self):
828
+ def dp(self) -> Iterator[CITDPRecord | CITDPDurationRecord]:
827
829
  """Parse CIT DP data from the registry.
828
830
 
829
831
  Generally only available since Windows 10.
@@ -878,7 +880,7 @@ class CITPlugin(Plugin):
878
880
  )
879
881
 
880
882
  @export(record=CITTelemetryRecord)
881
- def telemetry(self):
883
+ def telemetry(self) -> Iterator[CITTelemetryRecord]:
882
884
  """Parse CIT process telemetry answers from the registry.
883
885
 
884
886
  In some versions of Windows, processes would get "telemetry answers" set on their process struct, based on
@@ -899,7 +901,7 @@ class CITPlugin(Plugin):
899
901
  )
900
902
 
901
903
  @export(record=CITModuleRecord)
902
- def modules(self):
904
+ def modules(self) -> Iterator[CITModuleRecord]:
903
905
  """Parse CIT tracked module information from the registry.
904
906
 
905
907
  Contains applications that loaded a tracked module. By default these are:
@@ -1,9 +1,12 @@
1
+ from typing import Iterator
2
+
1
3
  from dissect.target.exceptions import RegistryError, UnsupportedPluginError
2
4
  from dissect.target.helpers.descriptor_extensions import (
3
5
  RegistryRecordDescriptorExtension,
4
6
  UserRecordDescriptorExtension,
5
7
  )
6
8
  from dissect.target.helpers.record import create_extended_descriptor
9
+ from dissect.target.helpers.regutil import RegistryKey
7
10
  from dissect.target.plugin import Plugin, export
8
11
 
9
12
  CLSIDRecordDescriptor = create_extended_descriptor(
@@ -50,7 +53,7 @@ class CLSIDPlugin(Plugin):
50
53
  if not len(list(self.target.registry.keys(list(self.KEYS.values())))) > 0:
51
54
  raise UnsupportedPluginError("No CLSID key found")
52
55
 
53
- def create_records(self, keys):
56
+ def create_records(self, keys: list[RegistryKey]) -> Iterator[CLSIDRecord]:
54
57
  """Iterate all CLSID keys from HKEY_CURRENT_USER\\Software\\Classes\\CLSID and
55
58
  HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\CLSID.
56
59
 
@@ -98,11 +101,11 @@ class CLSIDPlugin(Plugin):
98
101
  )
99
102
 
100
103
  @export(record=CLSIDRecord)
101
- def user(self):
104
+ def user(self) -> Iterator[CLSIDRecord]:
102
105
  """Return only the user CLSID registry keys."""
103
106
  yield from self.create_records(self.KEYS["user"])
104
107
 
105
108
  @export(record=CLSIDRecord)
106
- def machine(self):
109
+ def machine(self) -> Iterator[CLSIDRecord]:
107
110
  """Return only the machine CLSID registry keys."""
108
111
  yield from self.create_records(self.KEYS["machine"])
@@ -1,4 +1,5 @@
1
1
  import re
2
+ from typing import Iterator
2
3
 
3
4
  from dissect.target.exceptions import UnsupportedPluginError
4
5
  from dissect.target.helpers.record import DynamicDescriptor, TargetRecordDescriptor
@@ -19,7 +20,7 @@ class FirewallPlugin(Plugin):
19
20
  raise UnsupportedPluginError(f"Registry key {self.KEY} not found")
20
21
 
21
22
  @export(record=DynamicDescriptor(["uri"]))
22
- def firewall(self):
23
+ def firewall(self) -> Iterator[DynamicDescriptor]:
23
24
  """Return firewall rules saved in the registry.
24
25
 
25
26
  For a Windows operating system, the Firewall rules are stored in the
@@ -1,4 +1,5 @@
1
1
  import struct
2
+ from typing import Iterator
2
3
 
3
4
  from dissect.util.ts import wintimestamp
4
5
 
@@ -121,7 +122,7 @@ class MRUPlugin(Plugin):
121
122
  return UnsupportedPluginError("Target has no registry")
122
123
 
123
124
  @export(record=RunMRURecord)
124
- def run(self):
125
+ def run(self) -> Iterator[RunMRURecord]:
125
126
  """Return the RunMRU data.
126
127
 
127
128
  The ``HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU`` registry key contains information
@@ -136,7 +137,7 @@ class MRUPlugin(Plugin):
136
137
  yield from parse_mru_key(self.target, key, RunMRURecord)
137
138
 
138
139
  @export(record=RecentDocsRecord)
139
- def recentdocs(self):
140
+ def recentdocs(self) -> Iterator[RecentDocsRecord]:
140
141
  """Return the RecentDocs data.
141
142
 
142
143
  The ``HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs`` registry key contains
@@ -153,7 +154,7 @@ class MRUPlugin(Plugin):
153
154
  yield from parse_mru_ex_key(self.target, key, RecentDocsRecord)
154
155
 
155
156
  @export(record=OpenSaveMRURecord)
156
- def opensave(self):
157
+ def opensave(self) -> Iterator[OpenSaveMRURecord]:
157
158
  """Return the OpenSaveMRU data.
158
159
 
159
160
  The ``HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\OpenSaveMRU`` registry key
@@ -169,7 +170,7 @@ class MRUPlugin(Plugin):
169
170
  yield from parse_mru_key(self.target, key, OpenSaveMRURecord)
170
171
 
171
172
  @export(record=LastVisitedMRURecord)
172
- def lastvisited(self):
173
+ def lastvisited(self) -> Iterator[LastVisitedMRURecord]:
173
174
  """Return the LastVisitedMRU data.
174
175
 
175
176
  The ``HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedMRU`` registry key
@@ -210,7 +211,7 @@ class MRUPlugin(Plugin):
210
211
  )
211
212
 
212
213
  @export(record=ACMruRecord)
213
- def acmru(self):
214
+ def acmru(self) -> Iterator[ACMruRecord]:
214
215
  """Return the ACMru (Windows Search) data.
215
216
 
216
217
  The following keys are being searched:
@@ -252,7 +253,7 @@ class MRUPlugin(Plugin):
252
253
  yield from parse_mru_ex_key(self.target, key, ACMruRecord)
253
254
 
254
255
  @export(record=MapNetworkDriveMRURecord)
255
- def networkdrive(self):
256
+ def networkdrive(self) -> Iterator[MapNetworkDriveMRURecord]:
256
257
  """Return MRU of mapped network drives.
257
258
 
258
259
  The HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Map Network Drive MRU registry key contains
@@ -268,7 +269,7 @@ class MRUPlugin(Plugin):
268
269
  yield from parse_mru_key(self.target, key, MapNetworkDriveMRURecord)
269
270
 
270
271
  @export(record=TerminalServerMRURecord)
271
- def mstsc(self):
272
+ def mstsc(self) -> Iterator[TerminalServerMRURecord]:
272
273
  """Return Terminal Server Client MRU data."""
273
274
 
274
275
  KEY = "HKCU\\Software\\Microsoft\\Terminal Server Client\\Default"
@@ -290,7 +291,7 @@ class MRUPlugin(Plugin):
290
291
  )
291
292
 
292
293
  @export(record=MSOfficeMRURecord)
293
- def msoffice(self):
294
+ def msoffice(self) -> Iterator[MSOfficeMRURecord]:
294
295
  """Return MS Office MRU keys."""
295
296
 
296
297
  KEY = "HKCU\\Software\\Microsoft\\Office"
@@ -1,5 +1,6 @@
1
1
  import datetime
2
2
  import struct
3
+ from typing import Iterator
3
4
 
4
5
  from dissect.target.exceptions import RegistryError, UnsupportedPluginError
5
6
  from dissect.target.helpers.record import TargetRecordDescriptor
@@ -22,6 +23,8 @@ NetworkHistoryRecord = TargetRecordDescriptor(
22
23
 
23
24
 
24
25
  class NethistPlugin(Plugin):
26
+ """Windows network history plugin."""
27
+
25
28
  KEY = "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Networklist\\Signatures"
26
29
  PROFILE_KEY = "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Networklist\\Profiles"
27
30
 
@@ -30,7 +33,7 @@ class NethistPlugin(Plugin):
30
33
  raise UnsupportedPluginError("No Networklist registry keys found")
31
34
 
32
35
  @export(record=NetworkHistoryRecord)
33
- def network_history(self):
36
+ def network_history(self) -> Iterator[NetworkHistoryRecord]:
34
37
  """Return attached network history.
35
38
 
36
39
  The HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Networklist\\Signatures and
@@ -38,8 +41,8 @@ class NethistPlugin(Plugin):
38
41
  about the networks to which the system has been connected, both wireless and wired.
39
42
 
40
43
  References:
41
- - https://www.weaklink.org/2016/11/windows-network-profile-registry-keys/
42
- """
44
+ - https://web.archive.org/web/20221127181357/https://www.weaklink.org/2016/11/windows-network-profile-registry-keys/
45
+ """ # noqa: E501
43
46
  for key in self.target.registry.keys(self.KEY):
44
47
  for kind in key.subkeys():
45
48
  for sig in kind.subkeys():
@@ -1,3 +1,5 @@
1
+ from typing import Iterator
2
+
1
3
  from dissect.cstruct import cstruct
2
4
 
3
5
  from dissect.target.exceptions import UnsupportedPluginError
@@ -40,7 +42,7 @@ class RecentFileCachePlugin(Plugin):
40
42
  raise UnsupportedPluginError("Could not load RecentFileCache.bcf")
41
43
 
42
44
  @export(record=RecentFileCacheRecord)
43
- def recentfilecache(self):
45
+ def recentfilecache(self) -> Iterator[RecentFileCacheRecord]:
44
46
  """Parse RecentFileCache.bcf.
45
47
 
46
48
  Yields RecentFileCacheRecords with fields:
@@ -1,3 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Iterator
4
+
1
5
  from dissect.target.exceptions import PluginError, UnsupportedPluginError
2
6
  from dissect.target.helpers.record import TargetRecordDescriptor
3
7
  from dissect.target.plugin import Plugin, export
@@ -37,7 +41,7 @@ class RegfPlugin(Plugin):
37
41
  raise UnsupportedPluginError("Registry plugin not loaded")
38
42
 
39
43
  @export(record=[RegistryKeyRecord, RegistryValueRecord])
40
- def regf(self):
44
+ def regf(self) -> Iterator[RegistryKeyRecord | RegistryValueRecord]:
41
45
  """Return all registry keys and values.
42
46
 
43
47
  The Windows Registry is a hierarchical database that stores low-level settings for the Windows operating system