#!/usr/bin/env python3 """Parse a Windows shell link (.lnk) and recover its command and arguments. Implements a minimal [MS-SHLLINK] parser using stdlib ``struct``: it validates the header, reads LinkFlags, and walks the optional StringData section to extract the name, relative path, working directory, command-line arguments, and icon location. It also reports any data appended past the structure. It parses bytes statically and never executes the shortcut. """ from __future__ import annotations import argparse import json import struct import sys from pathlib import Path HEADER_SIZE = 0x4C LINK_CLSID = b"\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46" # LinkFlags bits relevant to StringData (MS-SHLLINK 2.1.1) F_HAS_LINK_TARGET_IDLIST = 0x00000001 F_HAS_NAME = 0x00000004 F_HAS_RELATIVE_PATH = 0x00000008 F_HAS_WORKING_DIR = 0x00000010 F_HAS_ARGUMENTS = 0x00000020 F_HAS_ICON_LOCATION = 0x00000040 F_IS_UNICODE = 0x00000080 def _read_stringdata(data: bytes, off: int, unicode_: bool) -> tuple[str, int]: count = struct.unpack_from(" dict: data = Path(path).read_bytes() if len(data) < HEADER_SIZE or struct.unpack_from(" int: parser = argparse.ArgumentParser(description="Parse a malicious LNK") sub = parser.add_subparsers(dest="cmd", required=True) p = sub.add_parser("parse") p.add_argument("file") args = parser.parse_args(argv) print(json.dumps(parse(args.file), indent=2)) return 0 if __name__ == "__main__": sys.exit(main())