From d809f769f471eab0359d9307e49d2d298a603c0d Mon Sep 17 00:00:00 2001 From: Stefan de Reuver <9864602+Horofic@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:14:20 +0100 Subject: [PATCH] Fix Vista idlist parsing --- dissect/shellitem/lnk/lnk.py | 40 +++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/dissect/shellitem/lnk/lnk.py b/dissect/shellitem/lnk/lnk.py index c772dcd..c0a71d4 100644 --- a/dissect/shellitem/lnk/lnk.py +++ b/dissect/shellitem/lnk/lnk.py @@ -68,16 +68,16 @@ def _parse(self, fh: BinaryIO) -> None: ) return - struct = c_lnk.typedefs[block_name](block_data) + if block_name == "VISTA_AND_ABOVE_IDLIST_PROPS": + struct = LnkTargetIdList(BytesIO(block_data), read_size) + else: + struct = c_lnk.typedefs[block_name](block_data) if block_name == "PROPERTY_STORE_PROPS": # TODO implement actual serialized property parsing guid = self._parse_guid(struct.format_id) struct._values.update({"format_id": guid}) - elif block_name == "VISTA_AND_ABOVE_IDLIST_PROPS": - struct = LnkTargetIdList(BytesIO(block_data), read_size) - elif block_name == "TRACKER_PROPS": for name, value in struct._values.items(): if "droid" in name: @@ -103,7 +103,7 @@ def _parse(self, fh: BinaryIO) -> None: self.extradata.update({block_name: struct}) else: - log.warning(f"Unknown extra data block encountered with signature 0x{signature:x}") + log.warning("Unknown extra data block encountered with signature %x", signature) # keep calling parse until the TERMINAL_BLOCK is hit. self._parse(fh) @@ -111,8 +111,8 @@ def _parse(self, fh: BinaryIO) -> None: def _parse_guid(self, guid: bytes, endianness: str = "<") -> UUID: if endianness == "<": return UUID(bytes_le=guid) - else: - return UUID(bytes=guid) + + return UUID(bytes=guid) def __getattr__(self, attr: str) -> Any: try: @@ -208,8 +208,8 @@ def __init__(self, fh: Optional[BinaryIO] = None): # if so the LocalBasePathOffsetUnicode and CommonPathSuffixOffsetUnicode fields are present if self.linkinfo_header.link_info_header_size >= 0x00000024: log.error( - "Unicode link_info_header encountered. Size bigger than 0x00000024. Size encountered:" - f"{self.linkinfo_header.link_info_header_size}" + "Unicode link_info_header encountered. Size bigger than 0x00000024. Size encountered: %x", + self.linkinfo_header.link_info_header_size, ) # TODO parse unicode headers. none encountered yet. @@ -323,7 +323,7 @@ class LnkTargetIdList: size: Size of the TARGET_IDLIST structure """ - def __init__(self, fh: Optional[BinaryIO] = None, size: Optional[int] = None): + def __init__(self, fh: Optional[BinaryIO] = None, size: Optional[int] = None) -> None: self.target_idlist = None self.idlist = None self.size = None @@ -373,7 +373,7 @@ def __init__( linkinfo: Optional[LnkInfo] = None, stringdata: Optional[LnkStringData] = None, extradata: Optional[LnkExtraData] = None, - ): + ) -> None: self.fh = fh self.flags = None @@ -435,16 +435,18 @@ def _parse_header(self, fh: Optional[BinaryIO]) -> Optional[c_lnk.SHELL_LINK_HEA if link_clsid == "00021401-0000-0000-c000-000000000046": return link_header - else: - log.info(f"Encountered invalid link file header: {link_header}. Skipping.") - return None - else: - log.info( - f"Encountered invalid link file with magic header size 0x{header_size:x} - " - f"magic header size should be 0x{LINK_HEADER_SIZE:x}. Skipping." - ) + + log.info("Encountered invalid link file header: %s. Skipping.", link_header) return None + log.info( + "Encountered invalid link file with magic header size 0x%x. \ + Magic header size should be 0x%x. Skipping.", + header_size, + LINK_HEADER_SIZE, + ) + return None + @property def clsid(self) -> UUID: """Returns the class id (clsid) of the LNK file."""