Skip to content

Commit

Permalink
refactor: type marker.
Browse files Browse the repository at this point in the history
- cache office component root dirs
  • Loading branch information
twiggler committed Jan 7, 2025
1 parent 6110333 commit 5751d33
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
7 changes: 4 additions & 3 deletions dissect/target/helpers/regutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from functools import cached_property
from io import BytesIO
from pathlib import Path
from typing import BinaryIO, Iterator, Optional, TextIO, Union
from typing import BinaryIO, Iterator, NewType, Optional, TextIO, Union

from dissect.regf import c_regf, regf

Expand Down Expand Up @@ -161,9 +161,10 @@ def subkeys(self) -> list[RegistryKey]:
"""Returns a list of subkeys from this key."""
raise NotImplementedError()

__marker = object()
Marker = NewType("Marker", object)
__marker = Marker(object())

def value(self, value: str, default: ValueType = __marker) -> RegistryValue:
def value(self, value: str, default: ValueType | Marker = __marker) -> RegistryValue:
"""Returns a specific value from this key.
Args:
Expand Down
19 changes: 14 additions & 5 deletions dissect/target/plugins/apps/productivity/msoffice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import itertools
from enum import Enum
from functools import lru_cache
from pathlib import Path
from typing import Iterable, Iterator, NamedTuple
from typing import Iterable, Iterator, Literal, NamedTuple
from xml.etree.ElementTree import Element

from defusedxml import ElementTree
Expand Down Expand Up @@ -51,7 +52,11 @@


class ClickOnceDeploymentManifestParser:
"""Parser for information about vsto plugins"""
"""Parser to extact information out ClickOnce deployment manifest files.
Currently only extracts codebase information. Also handles nested manifests.
Can be extended to a .NET assembly parser in the future.
"""

XML_NAMESPACE = {"": "urn:schemas-microsoft-com:asm.v2"}

Expand Down Expand Up @@ -133,16 +138,18 @@ class MSOffice(Plugin):
OFFICE_KEY = "Software\\Microsoft\\Office"
OFFICE_COMPONENTS = ["Access", "Excel", "Outlook", "PowerPoint", "Word", "OneNote"]
ADD_IN_KEY = "Addins"
WEB_ADDIN_MANIFEST_GLOB = "AppData/Local/Microsoft/Office/16.0/Wef/**/Manifests/**/*"
OFFICE_DEFAULT_USER_STARTUP = [
"%APPDATA%/Microsoft/Templates",
"%APPDATA%/Microsoft/Word/Startup",
"%APPDATA%/Microsoft/Excel/XLSTART",
"%APPDATA%/Microsoft/Outlook/Startup",
"%APPDATA%/Microsoft/PowerPoint/Startup",
]

OFFICE_DEFAULT_ROOT = "C:/Program Files/Microsoft Office/root/Office16/"

# Office is fixed at version 16.0 since Microsoft Office 2016 (released in 2015)
# Powerpoint and Outlook do not have a alternate startup folder
OFFICE_STARTUP_OPTIONS = [
("Software\\Microsoft\\Office\\16.0\\Word\\Options", "STARTUP-PATH"),
("Software\\Microsoft\\Office\\16.0\\Word\\Options", "UserTemplates"),
Expand Down Expand Up @@ -290,8 +297,9 @@ def startup(self) -> Iterable[OfficeStartupItem]:
def _wef_cache_folders(self) -> Iterable[Path]:
"""List cache folders which contain office web-addin data."""

WEB_ADDIN_MANIFEST_GLOB = "AppData/Local/Microsoft/Office/16.0/Wef/**/Manifests/**/*"
for user_details in self.target.user_details.all_with_home():
for manifest_path in user_details.home_path.glob(self.WEB_ADDIN_MANIFEST_GLOB):
for manifest_path in user_details.home_path.glob(WEB_ADDIN_MANIFEST_GLOB):
if manifest_path.is_file() and manifest_path.suffix != ".metadata":
yield manifest_path

Expand Down Expand Up @@ -358,7 +366,7 @@ def _parse_web_addin_manifest(self, manifest_path: Path) -> OfficeWebAddinRecord
modification_time=manifest_path.stat().st_mtime,
)

def _office_install_root(self, component: str) -> str:
def _office_install_root(self, component: Literal["Word", "Excel"]) -> str:
"""Return the installation root for a office component"""

# Typically, all components share the same root.
Expand All @@ -369,6 +377,7 @@ def _office_install_root(self, component: str) -> str:
except RegistryError:
return self.OFFICE_DEFAULT_ROOT

@lru_cache(16)
def _machine_startup_folders(self) -> Iterable[str]:
"""Return machine-scoped office startup folders"""

Expand Down

0 comments on commit 5751d33

Please sign in to comment.