This artiact parses LNK shortcut files.
A LNK file is a type of Shell Item that serves as a shortcut or reference to a specific file, folder, or application. It contains metadata and information about the accessed file or location and is a valuable forensic artifact. LNK files can be automatically created by the Windows operating system when a user accesses a file from a supported application or manually created by the user.
This artifact has several configurable options:
List of fields targeted by filter regex:
NOTE: regex startof (^) and endof ($) line modifiers will not work.
Windows.Forensics.Lnk also will highlight suspicious lnk attributes in a Suspicious field.
name: Windows.Forensics.Lnk
author: Matt Green - @mgreen27
description: |
This artiact parses LNK shortcut files.
A LNK file is a type of Shell Item that serves as a shortcut or reference to a
specific file, folder, or application. It contains metadata and information
about the accessed file or location and is a valuable forensic artifact.
LNK files can be automatically created by the Windows operating system when a
user accesses a file from a supported application or manually created by the user.
This artifact has several configurable options:
- TargetGlob: glob targeting. Default targets *.lnk files in Startup and Recent paths.
- IOCRegex: Regex search on key fields: StringData, TrackerData and PropertyStore.
- IgnoreRegex: Ignore regex filter on key fields.
- UploadLnk: uploads lnk hits.
- SuspiciousOnly: only returns LNK files reporting a suspicious attribute.
- SusSize: Any lnk over this size in bytes is suspicious.
- SusArgSize: Any lnk with Argument strings over this size is suspicious.
- SusArgRegex: Regex for suspicious strings in Arguments.
- SusHostnameRegex: Regex for suspicious TrackerData Hostname.
- VmPrefixMAC: Regex to match known Virtual Machine MacAddress prefix in TrackerData.
- RiskyExe: Regex target exe to flag as risky.
List of fields targeted by filter regex:
- StringData.TargetPath
- StringData.Name
- StringData.RelativePath
- StringData.WorkingDir
- StringData.Arguments
- StringData.IconLocation
- LinkTarget.LinkTarget
- PropertyStore
- TrackerData.MachineID
- TrackerData.MacAddress
NOTE: regex startof (^) and endof ($) line modifiers will not work.
Windows.Forensics.Lnk also will highlight suspicious lnk attributes in a Suspicious field.
* Large Size - Check for large size, default over 20000 bytes
* Startup Path - Path with \Startup\
* Zeroed Headers - Check for ShellHeader items zeroed.
* Hidden window - Check for ShellLinkHeader.ShowCommand as SHOWMINNOACTIVE
* Target Changed path - Check LNK TargetPath different to PropertyStore path.
* Target Changed size - Check LNK ShellLinkHeader.FileSize different to PropertyStore size.
* Risky target - Checks several LNK target paths to the RiskyExe regex.
* WebDAV - Checks for NetworkProviderType = WNNC_NET_DAV
* Line break in StringData.Name
* Suspicious argument size - large sized arguments over 250 characters as default
* Environment variable script - environment vatiable with a common script configured (bat|cmd|ps1|js|vbs|vbe|py)
* No Target with environmant variable - environment variable only execution
* Suspicious hostname - some common malicious hostnames
* Created in VM - Check TrackerData MacAddress for known VM prefix
* Local Admin- check PropertyStore for indications LNK created by local admin UID 500
* Cyrillic Language - check PropertyStore for Cyrillic strings
* Chinese Language - check PropertyStore for Chinese strings
* Korean Language - check PropertyStore for Korean strings
* Persian Language - check PropertyStore for Persian strings
* Vietnamese Language - check PropertyStore for Vietnamese strings
* CodePage - checks for existance of a ExtraData code page setting. Rare enough to report on - 936:Simplified Chinese, 949:Korean, 950:Traditional Chinese
* Has Overlay - check for overlay and extra data attached to LNK
* Long Base64 - check for a long base64 blog over 20 decoded characters
* Arguments have ticks - ticks are common in malicious LNK files
* Arguments have environment variables - environment variables (%|\$env:) are common in malicious LNKs
* Arguments have rare characters - looks for specific rare characters that may indicate obfuscation (\?|\!|\~|\@)
* Arguments have leading space - malicious LNK files may have a many leading spaces to obfuscate some tools
* Arguments have http strings - LNKs are reguarly used as a download cradle - https?://
* Arguments have UNC strings
* Suspicious arguments - some common malicious arguments observed in field (with mind to False positive)
reference:
- https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-shllink
parameters:
- name: TargetGlob
default: C:\{ProgramData,Users\*\AppData\*}\Microsoft\Windows\{Start Menu\Programs\StartUp,Recent\**}\*.lnk
- name: IocRegex
type: regex
description: A regex to filter on all fields
- name: IgnoreRegex
type: regex
description: A regex to ignore ilter all fields
- name: UploadLnk
description: Also upload the link files themselves.
type: bool
- name: SuspiciousOnly
description: Only returns LNK files reporting a suspicious attribute
type: bool
- name: SusSize
description: Any lnk over this size in bytes is suspicious.
default: 20000
type: int
- name: SusArgSize
default: 250
description: Any lnk with Argument strings over this size is suspicious.
type: int
- name: SusArgRegex
description: Regex for suspicious strings in Argumetns.
type: regex
default: \\AppData\\|\\Users\\Public\\|\\Temp\\|comspec|&cd&echo| -NoP | -W Hidden | [-/]decode | -e.* (JAB|SUVYI|SQBFAFgA|aWV4I|aQBlAHgA)|start\s*[\\/]b|\.downloadstring\(|\.downloadfile\(|iex
- name: SusHostnameRegex
description: Regex for suspicious TrackerData Hastname.
type: regex
default: ^(Win-|Desktop-|Commando$)
- name: CheckHostnameMismatch
description: Compare TrackerData.MachineID with Hostname (noisy in many networks)
type: bool
- name: VmPrefixMAC
description: VM MacAddress prefix regex to compate to LNK TrackerData.
type: regex
default: ^(00:50:56|00:0C:29|00:05:69|00:1C:14|08:00:27|52:54:00|00:21:F6|00:14:4F|00:0F:4B|00:15:5D)
- name: RiskyExe
description: Regex target exe to flag as risky.
type: regex
default: \\(cmd|powershell|cscript|wscript|rundll32|regsvr32|mshta|wmic|conhost)\.exe$
export: |
LET Profile = '''
[
["ShellLinkHeader", 0, [
["HeaderSize", 0, "uint32"],
["__LinkClsID", 4, "String", {
"length": 16,
"term": ""
}],
["LinkClsID", 0, "Value", {
"value": "x=>format(format='%x', args=x.__LinkClsID)"
}],
["LinkFlags", 20, "Flags", {
"type": "uint32",
"bitmap": {
"HasLinkTargetIDList": 0,
"HasLinkInfo": 1,
"HasName": 2,
"HasRelativePath": 3,
"HasWorkingDir": 4,
"HasArguments": 5,
"HasIconLocation": 6,
"IsUnicode": 7,
"ForceNoLinkInfo": 8,
"HasExpString": 9,
"RunInSeparateProcess": 10,
"HasDarwinID": 12,
"RunAsUser": 13,
"HasExpIcon": 14,
"NoPidlAlias": 15,
"RunWithShimLayer": 17,
"ForceNoLinkTrack": 18,
"EnableTargetMetadata": 19,
"DisableLinkPathTracking": 20,
"DisableKnownFolderTracking": 21,
"DisableKnownFolderAlias": 22,
"AllowLinkToLink": 23,
"UnaliasOnSave": 24,
"PreferEnvironmentPath": 25,
"KeepLocalIDListForUNCTarget": 26
}
}],
["FileAttributes", 24, "Flags", {
"type": "uint32",
"bitmap": {
"FILE_ATTRIBUTE_READONLY": 0,
"FILE_ATTRIBUTE_HIDDEN": 1,
"FILE_ATTRIBUTE_SYSTEM": 2,
"FILE_ATTRIBUTE_DIRECTORY": 4,
"FILE_ATTRIBUTE_ARCHIVE": 5,
"FILE_ATTRIBUTE_NORMAL": 7,
"FILE_ATTRIBUTE_TEMPORARY": 8,
"FILE_ATTRIBUTE_SPARSE_FILE": 9,
"FILE_ATTRIBUTE_REPARSE_POINT": 10,
"FILE_ATTRIBUTE_COMPRESSED": 11,
"FILE_ATTRIBUTE_OFFLINE": 12,
"FILE_ATTRIBUTE_NOT_CONTENT_INDEXED": 13,
"FILE_ATTRIBUTE_ENCRYPTED": 14,
}
}],
["CreationTime", 28, "WinFileTime", {
"type": "uint64"
}],
["AccessTime", 36, "WinFileTime", {
"type": "uint64"
}],
["WriteTime", 44, "WinFileTime", {
"type": "uint64"
}],
["FileSize", 52, "uint32"],
["IconIndex", 56, "uint32"],
["ShowCommand", 60, "Enumeration", {
"type": "uint32",
"map": {
"SHOWNORMAL": 0x00000001,
"SHOWMAXIMIZED": 0x00000003,
"SHOWMINNOACTIVE": 0x00000007,
}
}],
["__HotKeyLow", 62, "Enumeration", {
"type": "uint8",
"map": {
"No key assigned." : 0x00,
"0" : 0x30,
"1" : 0x31,
"2" : 0x32,
"3" : 0x33,
"4" : 0x34,
"5" : 0x35,
"6" : 0x36,
"7" : 0x37,
"8" : 0x38,
"9" : 0x39,
"A" : 0x41,
"B" : 0x42,
"C" : 0x43,
"D" : 0x44,
"E" : 0x45,
"F" : 0x46,
"G" : 0x47,
"H" : 0x48,
"I" : 0x49,
"J" : 0x4A,
"K" : 0x4B,
"L" : 0x4C,
"M" : 0x4D,
"N" : 0x4E,
"O" : 0x4F,
"P" : 0x50,
"Q" : 0x51,
"R" : 0x52,
"S" : 0x53,
"T" : 0x54,
"U" : 0x55,
"V" : 0x56,
"W" : 0x57,
"X" : 0x58,
"Y" : 0x59,
"Z" : 0x5A,
"F1" : 0x70,
"F2" : 0x71,
"F3" : 0x72,
"F4" : 0x73,
"F5" : 0x74,
"F6" : 0x75,
"F7" : 0x76,
"F8" : 0x77,
"F9" : 0x78,
"F10" : 0x79,
"F11" : 0x7A,
"F12" : 0x7B,
"F13" : 0x7C,
"F14" : 0x7D,
"F15" : 0x7E,
"F16" : 0x7F,
"F17" : 0x80,
"F18" : 0x81,
"F19" : 0x82,
"F20" : 0x83,
"F21" : 0x84,
"F22" : 0x85,
"F23" : 0x86,
"F24" : 0x87,
"NumLock" : 0x90,
"ScrollLock" : 0x91,
}
}],
["__HotKeyHigh", 63, "Enumeration", {
"type": "uint8",
"map": {
"No modifier key used." : 0x00,
"SHIFT" : 0x01,
"CONTROL" : 0x02,
"ALT" : 0x04,
}
}],
["HotKey", 0, "Value", {
"value": "x=>if(condition= x.__HotKeyLow=~'No key assigned',
then=x.__HotKeyLow,
else=x.__HotKeyLow + ' + ' + x.__HotKeyHigh)"
}],
# The LinkTargetIDList only exists if the Link Flag is set otherwise it is empty.
["LinkTargetIDList", "x=>x.HeaderSize", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasLinkTargetIDList'",
"choices": {
"true": "LinkTargetIDList",
"false": "Empty"
}
}],
["LinkInfo", "x=>x.LinkTargetIDList.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasLinkInfo'",
"choices": {
"true": "LinkInfo",
"false": "Empty"
}
}],
# StringData flag checks
["__Name", "x=>x.LinkInfo.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasName'",
"choices": {
"true": "Name",
"false": "Empty"
}
}],
["__RelativePath", "x=>x.__Name.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasRelativePath'",
"choices": {
"true": "RelativePath",
"false": "Empty"
}
}],
["__WorkingDir", "x=>x.__RelativePath.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasWorkingDir'",
"choices": {
"true": "WorkingDir",
"false": "Empty"
}
}],
["__Arguments", "x=>x.__WorkingDir.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasArguments'",
"choices": {
"true": "Arguments",
"false": "Empty"
}
}],
["__IconLocation", "x=>x.__Arguments.EndOf", "Union", {
"selector": "x=>x.LinkFlags =~ 'HasIconLocation'",
"choices": {
"true": "IconLocation",
"false": "Empty"
}
}],
["StringData",0,"StringData"],
["ExtraData", "x=>x.__IconLocation.EndOf", "Array", {
"type": "ExtraData",
"count": 1000,
"sentinel": "x=>x.Size < 0x00000004"
}],
["Overlay", "x=>x.ExtraData.EndOf", "Overlay"],
]],
["Empty", 0, []],
# Struct size includes the size field
["LinkTargetIDList", "x=>x.IDListSize + 2", [
["IDListSize", 0, "uint16"],
["IDList", 2, "Array", {
"type": "ItemIDList",
"count": 1000 # Max count until sentinel
}]
]],
# Item List contains shell bags
["ItemIDList", "x=>x.ItemIDSize", [
["ItemIDSize", 0, "uint16"],
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Type", 2, "BitField", {
"type": "uint8",
"start_bit": 4,
"end_bit": 7,
}],
["Subtype", 2, "BitField", {
"type": "uint8",
"start_bit": 0,
"end_bit": 1,
}],
# For now only support some common shell bags
["ShellBag", 0, "Union", {
"selector": "x=>x.Type",
"choices": {
# Older VQL had a bug in BitField
"64": "ShellBag0x40",
"48": "ShellBag0x30",
"16": "ShellBag0x1f",
"32": "ShellBag0x20",
# Newer versions should work better
"1": "ShellBag0x1f",
"2": "ShellBag0x20",
"3": "ShellBag0x30",
"4": "ShellBag0x40",
}
}]
]],
["ShellBag0x40", 0, [
["Name", 5, "String", {
encoding: "utf8",
}],
["Description", 0, "Value", {
"value": 'x=>dict(
Type="NetworkLocation",
ShortName=x.Name
)'
}]
]],
# A LinkInfo stores information about the destination of the link.
["LinkInfo", "x=>x.__LinkInfoSize", [
["__LinkInfoOffset", 0, "Value", {"value": "x=>x.StartOf"}],
["__LinkInfoSize", 0, "uint32"],
["__LinkInfoHeaderSize", 4, "uint32"],
["LinkInfoFlags", 8, "Flags", {
"type": "uint32",
"bitmap": {
"VolumeIDAndLocalBasePath": 0,
"CommonNetworkRelativeLinkAndPathSuffix": 1
}
}],
["__VolumeIDOffset", 0xc, "uint32"],
["__LocalBasePathOffset", 16, "uint32"],
["__CommonNetworkRelativeLinkOffset", 20, "uint32"],
["__CommonPathSuffixOffset", 24, "uint32"],
["__LocalBasePath", "x=>x.__LocalBasePathOffset", "String", {}],
["__CommonNetworkRelativePath", "x=>x.__CommonNetworkRelativeLinkOffset", "String"],
["__CommonPathSuffix", "x=>x.__CommonPathSuffixOffset", "String"],
["__VolumeID", "x=>x.__VolumeIDOffset", "VolumeID"],
["__CommonNetworkRelativeLink", "x=>x.__CommonNetworkRelativeLinkOffset", "CommonNetworkRelativeLink"],
["Target", 0, "Value", { # Depending on the LinkInfoFlags this struct needs to be interpreted differently.
"value": '
x=>if(condition=x.LinkInfoFlags =~ "VolumeIDAndLocalBasePath",
then=dict(Path=x.__LocalBasePath,
VolumeInfo=x.__VolumeID),
else=dict(Path=format(format="%v\\%v",
args=[x.__CommonNetworkRelativeLink.NetName, x.__CommonPathSuffix]),
RelativeLink=x.__CommonNetworkRelativeLink) )'
}]
]],
["CommonNetworkRelativeLink", 0, [
["__CommonNetworkRelativeLinkSize", 0, "uint32"],
["__CommonNetworkRelativeLinkFlags", 4, "Flags", {
"type": "uint32",
"bitmap": {
"ValidDevice": 0,
"ValidNetType": 1,
}
}],
["__NetNameOffset", 8, "uint32"],
["__DeviceNameOffset", 12, "uint32"],
["NetworkProviderType", 16, "Enumeration", {
"type": "uint32",
"map": {
"WNNC_NET_AVID": 0x001A0000,
"WNNC_NET_DOCUSPACE": 0x001B0000,
"WNNC_NET_MANGOSOFT": 0x001C0000,
"WNNC_NET_SERNET": 0x001D0000,
"WNNC_NET_RIVERFRONT1": 0X001E0000,
"WNNC_NET_RIVERFRONT2": 0x001F0000,
"WNNC_NET_DECORB": 0x00200000,
"WNNC_NET_PROTSTOR": 0x00210000,
"WNNC_NET_FJ_REDIR": 0x00220000,
"WNNC_NET_DISTINCT": 0x00230000,
"WNNC_NET_TWINS": 0x00240000,
"WNNC_NET_RDR2SAMPLE": 0x00250000,
"WNNC_NET_CSC": 0x00260000,
"WNNC_NET_3IN1": 0x00270000,
"WNNC_NET_EXTENDNET": 0x00290000,
"WNNC_NET_STAC": 0x002A0000,
"WNNC_NET_FOXBAT": 0x002B0000,
"WNNC_NET_YAHOO": 0x002C0000,
"WNNC_NET_EXIFS": 0x002D0000,
"WNNC_NET_DAV": 0x002E0000,
"WNNC_NET_KNOWARE": 0x002F0000,
"WNNC_NET_OBJECT_DIRE": 0x00300000,
"WNNC_NET_MASFAX": 0x00310000,
"WNNC_NET_HOB_NFS": 0x00320000,
"WNNC_NET_SHIVA": 0x00330000,
"WNNC_NET_IBMAL": 0x00340000,
"WNNC_NET_LOCK": 0x00350000,
"WNNC_NET_TERMSRV": 0x00360000,
"WNNC_NET_SRT": 0x00370000,
"WNNC_NET_QUINCY": 0x00380000,
"WNNC_NET_OPENAFS": 0x00390000,
"WNNC_NET_AVID1": 0X003A0000,
"WNNC_NET_DFS": 0x003B0000,
"WNNC_NET_KWNP": 0x003C0000,
"WNNC_NET_ZENWORKS": 0x003D0000,
"WNNC_NET_DRIVEONWEB": 0x003E0000,
"WNNC_NET_VMWARE": 0x003F0000,
"WNNC_NET_RSFX": 0x00400000,
"WNNC_NET_MFILES": 0x00410000,
"WNNC_NET_MS_NFS": 0x00420000,
"WNNC_NET_GOOGLE": 0x00430000,
}
}],
["__NetNameOffsetUnicode", 20, "uint32"],
["__DeviceNameOffsetUnicode", 24, "uint32"],
["__NetNameAscii", "x=>x.__NetNameOffset", "String"],
["__DeviceNameAscii", "x=>x.__DeviceNameOffset", "String"],
["__NetNameUnicode", "x=>x.__NetNameOffsetUnicode", "String", {"encoding": "utf16"}],
["__DeviceNameUnicode", "x=>x.__DeviceNameOffsetUnicode", "String", {"encoding": "utf16"}],
["NetName", 0, "Value", {
"value": "x=>if(condition=x.__NetNameOffset, then=x.__NetNameAscii, else=x.__NetNameUnicode)"
}],
["DeviceName", 0, "Value", {
"value": "x=>if(condition=x.__DeviceNameOffset, then=x.__DeviceNameAscii, else=x.__DeviceNameUnicode)"
}]
]],
# This is a comment
["VolumeID", 0, [
["__VolumeIDSize", 0, "uint32"],
["DriveType", 4, "Enumeration", {
"type": "uint32",
"choices": {
"0": "DRIVE_UNKNOWN",
"1": "DRIVE_NO_ROOT_DIR",
"2": "DRIVE_REMOVABLE",
"3": "DRIVE_FIXED",
"4": "DRIVE_REMOTE",
"5": "DRIVE_CDROM",
"6": "DRIVE_RAMDISK"
}
}],
["DriveSerialNumber", 8, "uint32"],
["__VolumeLabelOffset", 12, "uint32"],
["__VolumeLabelOffsetUnicode", 16, "uint32"],
["__VolumeLabelAscii", "x=>x.__VolumeLabelOffset", "String"],
["__VolumeLabelUnicode", "x=>x.__VolumeLabelOffsetUnicode", "String", {"encoding": "utf16"}],
["VolumeLabel", 0, "Value", {
"value": 'x=>if(condition=x.__VolumeLabelOffset,
then=x.__VolumeLabelAscii, else=x.__VolumeLabelUnicode)'
}]
]],
# Volume name
["ShellBag0x20", 0, [
["__Name", 3, "String"],
# Name is only valid if the first bit is set.
["Name", 3, "Value", {
"value": "x=>if(condition=x.ParentOf.Subtype, then=x.__Name, else='')",
}],
["Description", 0, "Value", {
"value": 'x=>dict(
LongName=x.Name,
ShortName=x.Name,
Type="Volume"
)'
}]
]],
# Marks the root class My Computer
["ShellBag0x1f", 0, [
["Description", 0, "Value", {
"value": 'x=>dict(
ShortName="My Computer",
Type="Root"
)'
}]
]],
# Represent a file or directory
["ShellBag0x30", 0, [
["Size", 0, "uint16"],
["Type", 2, "uint8"],
["SubType", 2, "Flags", {
"type": "uint8",
"bitmap": {
"File": 1,
"Directory": 0,
"Unicode": 4,
}
}],
["__LastModificationTime", 8, "uint32"],
["LastModificationTime", 8, "FatTimestamp"],
["ShortName", 14, "String"],
# Variable length search for the extension signature from the start of the struct.
["__pre", 0, "String", {
"term_hex": "0400efbe"
}],
# The extension tag should be immediately after the search string.
["__ExtensionTag", "x=>len(list=x.__pre)", "uint32"],
# Extension starts 4 bytes before the tag
["Extension", "x=>len(list=x.__pre) - 4", "Union", {
"selector": "x=>format(format='%#x', args=x.__ExtensionTag)",
"choices": {
"0xbeef0004": "Beef0004",
}
}],
# Put all the data together in a convenient location
["Description", 0, "Value", {
"value": 'x=>dict(
Type=x.SubType,
Modified=if(condition=x.__LastModificationTime, then=x.LastModificationTime),
LastAccessed=if(condition=x.Extension.__LastAccessed, then=x.Extension.LastAccessed),
CreateDate=if(condition=x.Extension.__CreateDate, then=x.Extension.CreateDate),
ShortName=x.ShortName,
LongName=x.Extension.LongName,
MFTID=x.Extension.MFTReference.MFTID,
MFTSeq=x.Extension.MFTReference.SequenceNumber
)'
}]
]],
["Beef0004", 0, [
["Size", 0, "uint16"],
["Version", 2, "uint16"],
["__Signature", 4, "uint32"],
["Signature", 0, "Value", {
"value": "x=>format(format='%#x', args=x.__Signature)"
}],
["__CreateDate", 8, "uint32"],
["__LastAccessed", 12, "uint32"],
["CreateDate", 8, "FatTimestamp"],
["LastAccessed", 12, "FatTimestamp"],
["MFTReference", 20, "MFTReference"],
["LongName", 46, "String", {
"encoding": "utf16"
}]
]],
["MFTReference", 0, [
["MFTID", 0, "BitField", {
"type": "uint64",
"start_bit": 0,
"end_bit": 48,
}],
["SequenceNumber", 0, "BitField", {
"type": "uint64",
"start_bit": 48,
"end_bit": 64,
}]
]],
["StringData",0,[
["TargetPath",0,"Value",{ "value":"x=> x.ParentOf.LinkInfo.Target.Path"}],
["Name",0,"Value",{ "value":"x=> x.ParentOf.__Name.StringData"}],
["RelativePath",0,"Value",{ "value":"x=> x.ParentOf.__RelativePath.StringData"}],
["WorkingDir",0,"Value",{ "value":"x=> x.ParentOf__WorkingDir.StringData"}],
["Arguments",0,"Value",{ "value":"x=> x.ParentOf.__Arguments.StringData"}],
["IconLocation",0,"Value",{ "value":"x=> x.ParentOf.__IconLocation.StringData"}],
]],
## StringDataBlock structs
["Name", "x=>x.Size + 2", [
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Characters", 0, "uint16"],
["Size", 0, "Value", {"value": "x=>x.Characters * 2"}],
["StringData", 2, "String", {
"encoding": "utf16",
"length": "x=>x.Size",
"max_length": 10000,
"term": "",
}],
]],
["WorkingDir", "x=>x.Size + 2", [
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Characters", 0, "uint16"],
["Size", 0, "Value", {"value": "x=>x.Characters * 2"}],
["StringData", 2, "String", {
"encoding": "utf16",
"length": "x=>x.Size",
"max_length": 10000,
"term": "",
}],
]],
["RelativePath", "x=>x.Size + 2", [
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Characters", 0, "uint16"],
["Size", 0, "Value", {"value": "x=>x.Characters * 2"}],
["StringData", 2, "String", {
"encoding": "utf16",
"length": "x=>x.Size",
"max_length": 10000,
"term": "",
}],
]],
["Arguments", "x=>x.Size + 2", [
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Characters", 0, "uint16"],
["Size", 0, "Value", {"value": "x=>x.Characters * 2"}],
["SizeType", 0, "Value", {"value": "x=>format(format='%T',args=x.Size)"}],
["StringData", 2, "String", {
"encoding": "utf16",
"length": "x=>x.Size",
"max_length": 50000,
"term": "",
}],
]],
["IconLocation", "x=>x.Size + 2", [
["Offset", 0, "Value", {"value": "x=>x.StartOf"}],
["Characters", 0, "uint16"],
["Size", 0, "Value", {"value": "x=>x.Characters * 2"}],
["StringData", 2, "String", {
"encoding": "utf16",
"length": "x=>x.Size",
"max_length": 10000,
"term": "",
}],
]],
["ExtraData","x=>x.Size",[
["Offset",0,"Value",{"value":"x=>x.StartOf"}],
["Size",0,"uint32"],
["EndOf",0,"Value",{"value":"x=>x.EndOf"}],
["__Header",4,"uint32"],
["Header",0,"Value",{"value":"x=>'0x' + upcase(string=format(format='%08x',args=x.__Header))"}],
["BlockClass", 4, "Enumeration", {
"type": "uint32",
"map": {
"EnvironmentVariable": 0xA0000001,
"Console": 0xA0000002,
"TrackerData": 0xA0000003,
"CodePage": 0xA0000004,
"SpecialFolder": 0xA0000005,
"Darwin": 0xA0000006,
"IconEnvironment": 0xA0000007,
"Shim": 0xA0000008,
"PropertyStore": 0xA0000009,
"KnownFolder": 0xA000000B,
"VistaAndAboveIDList": 0xA000000C,
}}],
["Data", 0, "Union", {
"selector": "x=>x.Header",
"choices": {
"0xA0000001": "EnvironmentVariableDataBlock",
"0xA0000002": "ConsoleDataBlock",
"0xA0000003": "TrackerDataBlock",
"0xA0000004": "ConsoleFEDataBlock",
"0xA0000005": "SpecialFolderDataBlock",
"0xA0000006": "DarwinDataBlock",
"0xA0000007": "IconEnvironmentDataBlock",
"0xA0000008": "ShimDataBlock",
"0xA0000009": "PropertyStoreDataBlock",
"0xA000000B": "KnownFolderDataBlock",
"0xA000000C": "VistaAndAboveIDListDataBlock",
}
}],
]],
#0xA0000001
["EnvironmentVariableDataBlock", 0x00000314, [
["__DataBlockSize",0,"uint32"],
["__TargetAnsi", 8, "String", {"max_length": 260 }],
["__TargetUnicode", 268, "String", {
"encoding": "utf16",
"max_length": 520
}],
["DataValue", 0, "Value",{
"value": "x=>if(condition= x.__TargetAnsi=x.__TargetUnicode,
then=x.__TargetAnsi,
else=dict(Ascii=x.__TargetAnsi,Unicode=x.__TargetUnicode))" }],
]],
#0xA0000002
["ConsoleDataBlock", 0x000000CC, [
["__DataBlockSize",0,"uint32"],
["FillAttributes",8,"Flags", {
"type": "uint16",
"bitmap": {
"FOREGROUND_BLUE": 0,
"FOREGROUND_GREEN": 1,
"FOREGROUND_RED": 2,
"FOREGROUND_INTENSITY": 3,
"BACKGROUND_BLUE": 4,
"BACKGROUND_GREEN": 5,
"BACKGROUND_RED": 6,
"BACKGROUND_INTENSITY": 7,
}}],
["PopupFillAttributes",10,"Flags", {
"type": "uint16",
"bitmap": {
"FOREGROUND_BLUE": 0,
"FOREGROUND_GREEN": 1,
"FOREGROUND_RED": 2,
"FOREGROUND_INTENSITY": 3,
"BACKGROUND_BLUE": 4,
"BACKGROUND_GREEN": 5,
"BACKGROUND_RED": 6,
"BACKGROUND_INTENSITY": 7,
}}],
["__ScreenBufferSizeX",12,"int16"],
["__ScreenBufferSizeY",14,"int16"],
["ScreenBufferSize",0,"Value",{
"value":"x=>format(format='%v x %v',args=[x.__ScreenBufferSizeX,x.__ScreenBufferSizeY])"
}],
["__WindowSizeX",16,"int16"],
["__WindowSizeY",18,"int16"],
["WindowSize",0,"Value",{
"value":"x=>format(format='%v x %v',args=[x.__WindowSizeX,x.__WindowSizeY])"
}],
["__WindowOriginX",20,"int16"],
["__WindowOriginY",22,"int16"],
["WindowOrigin",0,"Value",{
"value":"x=>format(format='%v / %v',args=[x.__WindowOriginX,x.__WindowOriginY])"
}],
["__FontSizeW",32,"int16"],
["__FontSizeH",34,"int16"],
["FontSize",0,"Value",{
"value":"x=>if(condition= x.__FontSizeW=0,
then= x.__FontSizeH,
else= format(format='%v / %v',args=[x.__FontSizeW,x.__FontSizeH])) "
}],
["__FontFamily", 36, "BitField", {
type: "uint32",
start_bit: 4,
end_bit: 31,
}],
["FontFamily", 0, "Value", {
"value": "x=>get(item=dict(
`0`='DONTCARE',
`16`='ROMAN',
`32`='SWISS',
`48`='MODERN',
`64`='SCRIPT',
`80`='DECORATIVE',
`1`='ROMAN',
`2`='SWISS',
`3`='MODERN',
`4`='SCRIPT',
`5`='DECORATIVE'),
member=x.__FontFamily)"
}],
["__FontPitch", 36, "BitField", {
type: "uint32",
start_bit: 0,
end_bit: 3,
}],
# TODO: implement Flag select for FontPitch
["FontPitch", 0 ,"Value",{
"value":"x=>format(format='0x%02x',args=x.__FontPitch)"
}],
["__FontWeight",40,"uint32"],
["BoldFont", 0 ,"Value",{
"value":"x=>if(condition= 700<=x.__FontWeight,
then= True,
else= False)"
}],
["FaceName", 44, "String", {
"encoding": "utf16",
"length": 64,
}],
["__CursorSize",108,"uint32"],
["CursorSize", 0 ,"Value",{
"value":"x=> if(condition= x.__CursorSize <= 25,
then= 'Small',
else=if(condition= x.__CursorSize >= 26 AND x.__CursorSize <= 50,
then= 'Medium',
else=if(condition= x.__CursorSize >= 51 AND x.__CursorSize <= 100,
else= 'Large',
else= x.__CursorSize )))"
}],
["__FullScreen",112,"uint32"],
["FullScreen", 0 ,"Value",{
"value":"x=> if(condition= x.__FullScreen > 0,
then= True,
else= False )"
}],
["__QuickEdit",116,"uint32"],
["QuickEdit", 0 ,"Value",{
"value":"x=> if(condition= x.__QuickEdit > 0,
then= True,
else= False )"
}],
["__InsertMode",120,"uint32"],
["InsertMode", 0 ,"Value",{
"value":"x=> if(condition= x.__InsertMode > 0,
then= True,
else= False )"
}],
["__AutoPosition",124,"uint32"],
["AutoPosition", 0 ,"Value",{
"value":"x=> if(condition= x.__AutoPosition > 0,
then= True,
else= False )"
}],
["HistoryBufferSize",128,"uint32"],
["NumberOfHistoryBuffers",132,"uint32"],
["__HistoryNoDup",136,"uint32"],
["HistoryDuplicatesAllowed", 0 ,"Value",{
"value":"x=> if(condition= x.__HistoryNoDup > 0,
then= True,
else= False )"
}],
["ColorTable", 140, "Array", {
"type": "uint32",
"count": 16 # Max count until sentinel
}],
]],
#0xA0000003
["TrackerDataBlock", 0x00000060, [
["__DataBlockSize",0,"uint32"],
["__MachineID", 16, "String"],
["MachineID", 0, "Value",{ "value": "x=>if(condition= x.__MachineID=~'[^ -~]+', then=Null, else=x.__MachineID )" }],
["MacAddress", 0, "Value",{ "value": "x=>if(condition=x.MachineID,then=strip(suffix=':',string=regex_replace(source=split(string=x.FileDroid,sep='-')[-1],re='.{2}',replace='$0:')))" }],
["__CreationTimeHex", 0, "Value",{ "value": "x=>if(condition=x.MachineID,then='0x' + x.FileDroid[15:18] + x.FileDroid[9:13] + x.FileDroid[0:8] )" }],
["CreationTime", 0, "Value",{ "value": "x=>timestamp(epoch=int(int=( int(int=x.__CreationTimeHex) - 0x01B21DD213814000) / 10000))" }],
["__Droid0", 32, "GUID"],
["__Droid1", 48, "GUID"],
["__DroidBirth0", 64, "GUID"],
["__DroidBirth1", 80, "GUID"],
["VolumeDroid", 0, "Value",{"value": "x=>if(condition=x.MachineID,then=x.__Droid0.Value)" }],
["VolumeDroidBirth", 0, "Value",{ "value": "x=>if(condition=x.MachineID,then=x.__DroidBirth0.Value)" }],
["FileDroid", 0, "Value",{"value": "x=>if(condition=x.MachineID,then=x.__Droid1.Value)" }],
["FileDroidBirth", 0, "Value",{ "value": "x=>if(condition=x.MachineID,then=x.__DroidBirth1.Value)" }],
]],
#0xA0000004
["ConsoleFEDataBlock", 0x0000000C, [
["__DataBlockSize",0,"uint32"],
["CodePage",8,"uint32"],
["DataValue",0,"Value",{"value":"x=>x.CodePage"}],
]],
#0xA0000005
["SpecialFolderDataBlock", 0x00000010, [
["__DataBlockSize",0,"uint32"],
["SpecialFolderId",8,"uint32"],
["IdOffset",12,"uint32"],
["DataValue",0,"Value",{"value":"x=>x.SpecialFolderId"}],
]],
#0xA0000006
["DarwinDataBlock", 0x00000314, [
["__DataBlockSize",0,"uint32"],
["__DarwinDataAnsi", 8, "String", {"max_length": 260 }],
["__DarwinDataUnicode", 268, "String", {
"encoding": "utf16",
"max_length": 520
}],
["DataValue", 0, "Value",{
"value": "x=>if(condition= x.__DarwinDataAnsi=x.__DarwinDataUnicode,
then=x.__DarwinDataAnsi,
else=dict(Ascii=x.__DarwinDataAnsi,Unicode=x.__DarwinDataUnicode))" }],
]],
#0xA0000007
["IconEnvironmentDataBlock", 0x00000314, [
["__DataBlockSize",0,"uint32"],
["__TargetAnsi", 8, "String", {"max_length": 260 }],
["__TargetUnicode", 268, "String", {
"encoding": "utf16",
"max_length": 520,
}],
["DataValue", 0, "Value",{
"value": "x=>if(condition= x.__TargetAnsi=x.__TargetUnicode,
then=x.__TargetAnsi,
else=dict(Ascii=x.__TargetAnsi,Unicode=x.__TargetUnicode))" }],
]],
#0xA0000008
["ShimDataBlock", "x=>x.__DataBlockSize", [
["__DataBlockSize",0,"uint32"],
["LayerName", 8, "String", {
"encoding": "utf16",
"length": "x=>x.__DataBlockSize - 8",
"max_length": 10000
}],
["DataValue",0,"Value",{"value":"x=>x.LayerName"}],
]],
#0xA0000009
["PropertyStoreDataBlock", "x=>x.__DataBlockSize", [
["__DataBlockSize",0,"uint32"],
["PropertyStorage", 8, "Array", {
"count": 1000,
"type": "PropertyStorage",
"sentinel": "x=>x.__DataBlockSize = 0"
}],
["DataValue",0,"Value",{"value":"x=>x.PropertyStorage.PropertyValue"}],
#["DataValue",0,"Value",{"value":"x=>property_store(data=x.PropertyStorage.PropertyValue)"}],
]],
#0xA000000B
["KnownFolderDataBlock", 0x00000314, [
["__DataBlockSize",0,"uint32"],
["__KnownFolderId", 8, "GUID"],
["GUID",0,"Value",{"value":"x=>x.__KnownFolderId.Value"}],
["__Offset", 24,"uint32"],
["KnownFolder", 0, "Value", {
"value": "x=> get(item=dict(
`DE61D971-5EBC-4F02-A3A9-6C82895E5C04`='AddNewPrograms',
`724EF170-A42D-4FEF-9F26-B60E846FBA4F`='AdminTools',
`A520A1A4-1780-4FF6-BD18-167343C5AF16`='AppDataLow',
`A305CE99-F527-492B-8B1A-7E76FA98D6E4`='AppUpdates',
`9E52AB10-F80D-49DF-ACB8-4330F5687855`='CDBurning',
`DF7266AC-9274-4867-8D55-3BD661DE872D`='ChangeRemovePrograms',
`D0384E7D-BAC3-4797-8F14-CBA229B392B5`='CommonAdminTools',
`C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D`='CommonOEMLinks',
`0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8`='CommonPrograms',
`A4115719-D62E-491D-AA7C-E74B8BE3B067`='CommonStartMenu',
`82A5EA35-D9CD-47C5-9629-E15D2F714E6E`='CommonStartup',
`B94237E7-57AC-4347-9151-B08C6C32D1F7`='CommonTemplates',
`0AC0837C-BBF8-452A-850D-79D08E667CA7`='Computer',
`4BFEFB45-347D-4006-A5BE-AC0CB0567192`='Conflict',
`6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD`='Connections',
`56784854-C6CB-462B-8169-88E350ACB882`='Contacts',
`82A74AEB-AEB4-465C-A014-D097EE346D63`='ControlPanel',
`2B0F765D-C0E9-4171-908E-08A611B84FF6`='Cookies',
`B4BFCC3A-DB2C-424C-B029-7FE99A87C641`='Desktop',
`FDD39AD0-238F-46AF-ADB4-6C85480369C7`='Documents',
`374DE290-123F-4565-9164-39C4925E467B`='Downloads',
`1777F761-68AD-4D8A-87BD-30B759FA33DD`='Favorites',
`FD228CB7-AE11-4AE3-864C-16F3910AB8FE`='Fonts',
`CAC52C1A-B53D-4EDC-92D7-6B2E8AC19434`='Games',
`054FAE61-4DD8-4787-80B6-090220C4B700`='GameTasks',
`D9DC8A3B-B784-432E-A781-5A1130A75963`='History',
`4D9F7874-4E0C-4904-967B-40B0D20C3E4B`='Internet',
`352481E8-33BE-4251-BA85-6007CAEDCF9D`='InternetCache',
`BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968`='Links',
`F1B32785-6FBA-4FCF-9D55-7B8E7F157091`='LocalAppData',
`2A00375E-224C-49DE-B8D1-440DF7EF3DDC`='LocalizedResourcesDir',
`4BD8D571-6D19-48D3-BE97-422220080E43`='Music',
`C5ABBF53-E17F-4121-8900-86626FC2C973`='NetHood',
`D20BEEC4-5CA8-4905-AE3B-BF251EA09B53`='Network',
`31C0DD25-9439-4F12-BF41-7FF4EDA38722`='Objects3D',
`2C36C0AA-5812-4B87-BFD0-4CD0DFB19B39`='OriginalImages',
`69D2CF90-FC33-4FB7-9A0C-EBB0F0FCB43C`='PhotoAlbums',
`33E28130-4E1E-4676-835A-98395C3BC3BB`='Pictures',
`DE92C1C7-837F-4F69-A3BB-86E631204A23`='Playlists',
`76FC4E2D-D6AD-4519-A663-37BD56068185`='Printers',
`9274BD8D-CFD1-41C3-B35E-B13F55A758F4`='PrintHood',
`5E6C858F-0E22-4760-9AFE-EA3317B67173`='Profile',
`62AB5D82-FDC1-4DC3-A9DD-070D1D495D97`='ProgramData',
`905E63B6-C1BF-494E-B29C-65B732D3D21A`='ProgramFiles',
`F7F1ED05-9F6D-47A2-AAAE-29D317C6F066`='ProgramFilesCommon',
`6365D5A7-0F0D-45E5-87F6-0DA56B6A4F7D`='ProgramFilesCommonX64',
`DE974D24-D9C6-4D3E-BF91-F4455120B917`='ProgramFilesCommonX86',
`6D809377-6AF0-444B-8957-A3773F02200E`='ProgramFilesX64',
`7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E`='ProgramFilesX86',
`A77F5D77-2E2B-44C3-A6A2-ABA601054A51`='Programs',
`DFDF76A2-C82A-4D63-906A-5644AC457385`='Public',
`C4AA340D-F20F-4863-AFEF-F87EF2E6BA25`='PublicDesktop',
`ED4824AF-DCE4-45A8-81E2-FC7965083634`='PublicDocuments',
`3D644C9B-1FB8-4F30-9B45-F670235F79C0`='PublicDownloads',
`DEBF2536-E1A8-4C59-B6A2-414586476AEA`='PublicGameTasks',
`3214FAB5-9757-4298-BB61-92A9DEAA44FF`='PublicMusic',
`B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5`='PublicPictures',
`2400183A-6185-49FB-A2D8-4A392A602BA3`='PublicVideos',
`52A4F021-7B75-48A9-9F6B-4B87A210BC8F`='QuickLaunch',
`AE50C081-EBD2-438A-8655-8A092E34987A`='Recent',
`BD85E001-112E-431E-983B-7B15AC09FFF1`='RecordedTV',
`B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC`='RecycleBin',
`8AD10C31-2ADB-4296-A8F7-E4701232C972`='ResourceDir',
`3EB685DB-65F9-4CF6-A03A-E3EF65729F3D`='RoamingAppData',
`B250C668-F57D-4EE1-A63C-290EE7D1AA1F`='SampleMusic',
`C4900540-2379-4C75-844B-64E6FAF8716B`='SamplePictures',
`15CA69B3-30EE-49C1-ACE1-6B5EC372AFB5`='SamplePlaylists',
`859EAD94-2E85-48AD-A71A-0969CB56A6CD`='SampleVideos',
`4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4`='SavedGames',
`7D1D3A04-DEBB-4115-95CF-2F29DA2920DA`='SavedSearches',
`EE32E446-31CA-4ABA-814F-A5EBD2FD6D5E`='SEARCH_CSC',
`98EC0E18-2098-4D44-8644-66979315A281`='SEARCH_MAPI',
`190337D1-B8CA-4121-A639-6D472D16972A`='SearchHome',
`8983036C-27C0-404B-8F08-102D10DCFD74`='SendTo',
`7B396E54-9EC5-4300-BE0A-2482EBAE1A26`='SidebarDefaultParts',
`A75D362E-50FC-4FB7-AC2C-A8BEAA314493`='SidebarParts',
`625B53C3-AB48-4EC1-BA1F-A1EF4146FC19`='StartMenu',
`B97D20BB-F46A-4C97-BA10-5E3608430854`='Startup',
`43668BF8-C14E-49B2-97C9-747784D784B7`='SyncManager',
`289A9A43-BE44-4057-A41B-587A76D7E7F9`='SyncResults',
`0F214138-B1D3-4A90-BBA9-27CBC0C5389A`='SyncSetup',
`1AC14E77-02E7-4E5D-B744-2EB1AE5198B7`='System',
`D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27`='SystemX86',
`A63293E8-664E-48DB-A079-DF759E0509F7`='Templates',
`5B3749AD-B49F-49C1-83EB-15370FBD4882`='TreeProperties',
`0762D272-C50A-4BB0-A382-697DCD729B80`='UserProfiles',
`F3CE0F7C-4901-4ACC-8648-D5D44B04EF8F`='UsersFiles',
`18989B1D-99B5-455B-841C-AB7C74E4DDFC`='Videos',
`F38BF404-1D43-42F2-9305-67DE0B28FC23`='Windows'),
field=x.GUID)"
}],
]],
#0xA000000C
["VistaAndAboveIDListDataBlock", "x=>x.__BlockSize", [
["__DataBlockSize",0,"uint32"],
["IDList", 8, "ItemIDList"],
]],
["PropertyStorage","x=>x.StorageSize", [
["StorageSize",0,"uint32"],
#["Version",4,"String",{ "length":4 }], #Expect 1SPS / 0x53505331
["__Format", 8,"GUID"],
["Format", 0, "Value",{"value": "x=>x.__Format.Value" }],
["PropertyValue", 24, "Array", {
"type": "PropertyValue",
"count": 1000,
"sentinel": "x=>x.__ValueSize = 0"
}],
]],
["PropertyValue","x=>x.__ValueSize", [
["__ValueSize",0,"uint32"],
["__ID",4,"uint32"],
["GuidId",0,"Value",{"value": "x=>x.ParentOf.Format + '/' + str(str=x.__ID)"}],
["Description", 0, "Value", {
"value": "x=> get(item=dict(
`28636AA6-953D-11D2-B5D6-00C04FD918D0`=x.__SHELL_DETAILS,
`446D16B1-8DAD-4870-A748-402EA43D788C`=x.__CACHE,
`46588AE2-4CBC-4338-BBFC-139326986DCE`=x.__User,
`841E4F90-FF59-4D16-8947-E81BBFFAB36D`=x.__Software,
`86407DB8-9DF7-48CD-B986-F999ADC19731`=x.__Share,
`86D40B4D-9069-443C-819A-2A54090DCCEC`=x.__Tile,
`9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3`=x.__AppUserModel,
`B725F130-47EF-101A-A5F1-02608C9EEBAC`=x.__STORAGE,
`DABD30ED-0043-4789-A7F8-D013A4736622`=x.__FolderDisplay,
`E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD`=x.__SEARCH,
`F29F85E0-4FF9-1068-AB91-08002B27B3D9`=x.__Document,
`FB8D2D7B-90D1-4E34-BF60-6EAC09922BBF`=x.__Hash),
member=x.ParentOf.Format) || 'Unknown Guid' "
}],
["__STORAGE", 4, "Enumeration", {
"type": "uint32",
"map": {
"System.ItemFolderNameDisplay": 0x00000002,
"ClassId": 0x00000003,
"System.ItemTypeText": 0x00000004,
"FileIndex": 0x00000008,
"USN": 0x00000009,
"System.ItemNameDisplay": 0x0000000A,
"Path": 0x0000000B,
"System.Size": 0x0000000C,
"System.FileAttributes": 0x0000000D,
"System.DateModified": 0x0000000E,
"System.DateCreated": 0x0000000F,
"System.DateAccessed": 0x00000010,
"AllocSize": 0x00000012,
"ShortFilename": 0x00000014,
}}],
["__SHELL_DETAILS", 4, "Enumeration", {
"type": "uint32",
"map": {
"ComputerName": 0x00000005,
"ContainedItems": 0x0000001D,
"FileCount": 0x0000000C,
"FindData": 0x00000000,
"IsSendToTarget": 0x00000021,
"ItemPathDisplayNarrow": 0x00000008,
"ItemSubType": 0x00000025,
"ItemType": 0x0000000B,
"ParsingName": 0x00000018,
"ParsingPath": 0x0000001E,
"PerceivedType": 0x00000009,
"SFGAOFlags": 0x00000019,
"TotalFileSize": 0x0000000E,
"DescriptionID": 0x00000002,
"NamespaceCLSID": 0x00000006,
}}],
["__CACHE", 4, "Enumeration", {
"type": "uint32",
"map": {
"ThumbnailCacheId": 0x00000064,
"VolumeId": 0x00000068,
}}],
["__SEARCH", 4, "Enumeration", {
"type": "uint32",
"map": {
"FolderPath": 0x00000006,
"SearchRanking": 0x00000003,
}}],
["__User", 4, "Enumeration", {
"type": "uint32",
"map": {
"SID": 0x00000004,
}}],
["__Share", 4, "Enumeration", {
"type": "uint32",
"map": {
"Share Target Description": 0x00000002,
}}],
["__Hash", 4, "Enumeration", {
"type": "uint32",
"map": {
"WinX Hash": 0x00000002,
}}],
["__FolderDisplay", 4, "Enumeration", {
"type": "uint32",
"map": {
"Item Folder Path Display Narrow": 0x00000064,
}}],
["__AppUserModel", 4, "Enumeration", {
"type": "uint32",
"map": {
"App User Model Relaunch Command": 2,
"App User Model Relaunch Icon Resource": 3,
"App User Model Relaunch Display Name Resource": 4,
"App User Model ID": 5,
"App User Model Is DestList Separator": 6,
"App User Model Is DestList Link": 7,
"App User Model Exclude From Show In New Install": 8,
"App User Model Prevent Pinning": 9,
"App User Model Best Shortcut": 10,
"App User Model Is Dual Mode": 11,
"App User Model Start Pin Option": 12,
"App User Model Relevance": 13,
"App User Model Host Environment": 14,
"App User Model Package Install Path": 15,
"App User Model Record State": 16,
"App User Model Package Family Name": 17,
"App User Model Installed By": 18,
"App User Model Parent ID": 19,
"App User Model Activation Context": 20,
"App User Model Package Full Name": 21,
"App User Model Package Relative Application ID": 22,
"App User Model Excluded From Launcher": 23,
"App User Model AppCompat ID": 24,
"App User Model Run Flags": 25,
"App User Model Toast Activator CLSID": 26,
"App User Model DestList Provided Title": 27,
"App User Model DestList Provided Description": 28,
"App User Model DestList Logo Uri": 29,
"App User Model DestList Provided Group Name": 30,
}}],
["__Software", 4, "Enumeration", {
"type": "uint32",
"map": {
"Publisher Display Name": 2,
"Software Registered Owner": 3,
"Software Registered Company": 4,
"Software AppId": 5,
"Software Support Url": 6,
"Software Support Telephone": 7,
"Software Help Link": 8,
"Software Install Location": 9,
"Software Install Source": 10,
"Software Date Installed": 11,
"Software Support Contact Name": 12,
"Software ReadMe Url": 13,
"Software Update Info Url": 14,
"Software Times Used": 15,
"Software Date Last Used": 16,
"Software Tasks File Url": 17,
"Software Parent Name": 18,
"Software Product ID": 19,
"Software Comments": 20,
"Software Null Preview Total Size": 997,
"Software Null Preview Subtitle": 998,
"Software Null Preview Title": 999,
}}],
["__Tile", 4, "Enumeration", {
"type": "uint32",
"map": {
"Tile Small Image Location": 0x00000002,
"Tile Background Color": 0x00000004,
"Tile Foreground Color": 0x00000005,
"Tile Display Name": 0x0000000b,
"Tile Image Location": 0x0000000c,
"Tile Wide 310x150 Logo Path": 0x0000000d,
"Tile Unknown Flags": 0x0000000e,
"Tile Badge Logo Path": 0x0000000f,
"Tile Suite Display Name": 0x00000010,
"Tile Suite Sor tName": 0x00000011,
"Tile Display Name Language": 0x00000012,
"Tile Square 310x310 Logo Path": 0x00000013,
"Tile Square 70x70 Logo Path": 0x00000014,
"Tile Fence Post": 0x00000015,
"Tile Install Progress": 0x00000016,
"Tile Encoded Target Path": 0x00000017,
}}],
["__Document", 4, "Enumeration", {
"type": "uint32",
"map": {
"Subject": 3,
"Author": 4,
"Keywords": 5,
"Comment": 6,
"Document Template": 7,
"Document Last Author": 8,
"Document Revision Number": 9,
"Document Total Editing Time": 10,
"Document Date Printed": 11,
"Document Date Created": 12,
"Document Date Saved": 13,
"Document Page Count": 14,
"Document Word Count": 15,
"Document Character Count": 16,
"Thumbnail": 17,
"Application Name": 18,
"Document Security": 19,
"High Keywords": 24,
"Low Keywords": 25,
"Medium Keywords": 26,
"Thumbnail Stream": 27,
}}],
#["Unused",8,"char"],
["Type", 9, "Enumeration", {
"type": "uint32",
"map": {
"LPWSTR": 0x0000001F,
"FILETIME": 0x00000040,
"UI8": 0x00000015,
"CLSID": 0x00000048
}
}],
["__Size",13,"uint32"],
["__LPWSTR",17, "String",{
"term_hex": "00",
"length": "x=>x.__Size * 2",
"encoding": "utf16"
}],
["__FILETIME",13, "WinFileTime"],
["__UI8",13, "uint64"],
["__CLSID",13,"GUID"],
["Value", 0, "Value", {
"value": "x=> get(item=dict(
`LPWSTR`=x.__LPWSTR,
`FILETIME`=x.__FILETIME,
`UI8`=x.__UI8,
`CLSID`=x.__CLSID.Value),
member=x.Type) || 'Unknown: First bytes 0x' + upcase(string=format(format='%08x',args=x.__Size))"
}],
]],
["GUID", 16, [
["__D1", 0, "uint32"],
["__D2", 4, "uint16"],
["__D3", 6, "uint16"],
["__D4", 8, "String", {"term": "", "length": 2}],
["__D5", 10, "String", {"term": "", "length": 6}],
["Value", 0, "Value", { "value": "x=>upcase(string=
format(format='%08x-%04x-%04x-%02x-%02x',
args=[x.__D1, x.__D2, x.__D3, x.__D4, x.__D5]))" }],
]],
["Overlay", "x=>x.Length", [
["Header", 0, "Value", {"value": "x=>format(format='0x%08x',args=read_file(filename=OSPath,offset=x.StartOf + 4,length=4))"}],
["Offset", 0, "Value", {"value": "x=>x.StartOf + 4"}],
["Length", 0, "Value", {"value": "x=>len(list=read_file(filename=OSPath, offset=x.StartOf + 4))"}],
["Entropy", 0, "Value", {"value": "x=>entropy(string=read_file(filename=OSPath,offset=x.StartOf + 4))"}],
["Magic", 0, "Value", {"value": "x=>magic(accessor='data',path=read_file(filename=OSPath,offset=x.StartOf + 4))"}],
]],
]
'''
LET fixpath(data) = regex_transform(key='x', source=join(sep='\\',array=data),
map=dict( `My Computer\\\\` = '', `:\\\\\\\\` = ''':\''',`\\\\\\\\\\\\` = '\\'))
// Pretty format the PropertyStorage
LET property_store(Parsed) = SELECT * FROM foreach(
row=Parsed.ExtraData.Data.PropertyStorage.PropertyValue,
query={
SELECT * FROM foreach(row=_value,
query={
SELECT GuidId,Description,Type,Value FROM foreach(row=_value)
})})
LET ShowHeader(Parsed) = dict(
Headersize = Parsed.HeaderSize,
LinkClsID = Parsed.LinkClsID,
LinkFlags = Parsed.LinkFlags,
FileAttributes = Parsed.FileAttributes,
FileSize = Parsed.FileSize,
CreationTime = Parsed.CreationTime,
AccessTime = Parsed.AccessTime,
WriteTime = Parsed.WriteTime,
IconIndex = Parsed.IconIndex,
ShowCommand = Parsed.ShowCommand,
HotKey = Parsed.HotKey
)
LET ShowLinkTarget(Parsed) = dict(
LinkTarget= if(
condition= len(list=fixpath(data=Parsed.LinkTargetIDList.IDList.ShellBag.Description.LongName)) < len(list=fixpath(data=Parsed.LinkTargetIDList.IDList.ShellBag.Description.ShortName)),
then= fixpath(data=Parsed.LinkTargetIDList.IDList.ShellBag.Description.ShortName),
else= fixpath(data=Parsed.LinkTargetIDList.IDList.ShellBag.Description.LongName)),
LinkTargetIDList = Parsed.LinkTargetIDList
)
LET ShowExtraData(Parsed) = to_dict(item={
SELECT if(condition= BlockClass=~'^0x',
then= 'Overlay',
else= BlockClass ) as _key,
if(condition= Data.DataValue,
then= Data.DataValue, else=
if(condition= NOT BlockClass =~ '^0x',
then= Data,
else= dict(
Header=format(format='0x%x',args=read_file(filename=OSPath, offset=Offset,length=4)),
Offset=Offset,
Length=len(list=read_file(filename=OSPath, offset=Offset)),
Entropy=entropy(string=read_file(filename=OSPath,offset=Offset)),
Magic=magic(accessor='data',path=read_file(filename=OSPath,offset=Offset))
))) as _value
FROM foreach(row=Parsed.ExtraData)
})
sources:
- query: |
LET targets = SELECT OSPath, Mtime,Atime,Ctime,Btime,Size,
read_file(filename=OSPath,offset=0,length=2) as _Header
FROM glob(globs=TargetGlob)
WHERE NOT IsDir AND _Header =~ '^L\x00$'
LET lnk_files = SELECT *,
parse_binary(filename=OSPath,
profile=Profile, struct="ShellLinkHeader") AS Parsed
FROM targets
LET parsed = SELECT
dict(OSPath=OSPath, Size=Size,
Mtime=Mtime,Btime=Btime) as SourceFile,
ShowHeader(Parsed=Parsed) as ShellLinkHeader,
Parsed.LinkInfo as LinkInfo,
ShowLinkTarget(Parsed=Parsed) as LinkTarget,
Parsed.StringData as StringData,
ShowExtraData(Parsed=Parsed) as ExtraData,
property_store(data=Parsed) as PropertyStore,
Parsed.Overlay as Overlay,
Parsed
FROM lnk_files
-- Several dynamic functions to check propertystore for anormalities
LET find_uid(propertystore) = SELECT regex_replace(source=Value,re='''S-1-5-\d{2}-\d+-\d+-\d+-''',replace='') as Value
FROM propertystore WHERE Description = 'SID'
LET find_oldpath(propertystore) = SELECT Value FROM propertystore WHERE Description = 'ParsingPath'
LET find_oldsize(propertystore) = SELECT Value FROM propertystore WHERE Description = 'System.Size'
LET results = SELECT SourceFile,
ShellLinkHeader,
LinkInfo,
LinkTarget,
StringData,
if(condition=PropertyStore,
then= if(condition= ExtraData.Overlay,
then= ExtraData + dict(PropertyStore=PropertyStore),
else= if(condition= Overlay.Length > 4,
then= ExtraData + dict(PropertyStore=PropertyStore) + dict(Overlay=to_dict(item=Overlay)),
else= ExtraData + dict(PropertyStore=PropertyStore)
)),
else= if(condition= ExtraData.Overlay,
then= ExtraData,
else= if(condition= Overlay.Length > 4,
then= ExtraData + dict(Overlay=to_dict(item=Overlay)),
else= ExtraData
)
)) as ExtraData,
find_uid(propertystore=PropertyStore)[0].Value as UID,
find_oldpath(propertystore=PropertyStore)[0].Value as OldPath,
find_oldsize(propertystore=PropertyStore)[0].Value as OldSize
FROM parsed
WHERE if(condition= IocRegex,
then= format(format='%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\s%s',
args=[
StringData.TargetPath,
StringData.Name,
StringData.RelativePath,
StringData.WorkingDir,
StringData.Arguments,
StringData.IconLocation,
LinkTarget.LinkTarget,
ExtraData.TrackerData.MachineID,
ExtraData.TrackerData.MacAddress,
join(array=PropertyStore.Value,sep='\n')
]) =~ IocRegex,
else= True)
AND NOT if(condition= IgnoreRegex,
then= format(format='%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\s%s',
args=[
StringData.TargetPath,
StringData.Name,
StringData.RelativePath,
StringData.WorkingDir,
StringData.Arguments,
StringData.IconLocation,
LinkTarget.LinkTarget,
ExtraData.TrackerData.MachineID,
ExtraData.TrackerData.MacAddress,
join(array=PropertyStore.Value,sep='\n')
]) =~ IgnoreRegex,
else= False)
LET sus_cli(data) = dict(
`Arguments have ticks` = data=~'''\^|\`|[a-z][\'\"]{2}[a-z]''',
`Arguments have environment variables` = data=~'''\%|\$env:''',
`Arguments have rare characters` = data=~'''\?\!\~\@''',
`Arguments have leading space` = data=~ '^ ',
`Arguments have http strings` = data=~'''(http|ftp)s?://''',
`Arguments have UNC strings` = data=~'''(\s|^)\\\\[a-z0-9$_.-]+''',
`Suspicious arguments` = data=~SusArgRegex
)
-- find largest base64 blob over 10 characters
LET find_b64(data) = SELECT *
FROM if(condition=data,
then={
SELECT Base64, len(list=Base64) as Length
FROM parse_records_with_regex(accessor='data',file=data, regex='''(?P<Base64>(https?://[^\s]+/)*[A-Za-z0-9+/]{10,}={0,2})''')
WHERE NOT Base64 =~ '^http' -- Implementing negative regex match: We exclude b64 strings with http prefix.
ORDER BY Length DESC
LIMIT 1
},
else=null )
LET add_suspicious = SELECT *, dict(
`Large Size` = SourceFile.Size > SusSize,
`Startup Path` = SourceFile.OSPath =~ '''\\Startup\\''',
`Zeroed Headers` = ( ShellLinkHeader.FileSize=0 AND ShellLinkHeader.CreationTime=~'^1601-01' AND len(list=LinkInfo.LinkInfoFlags)=0 ),
`Hidden window` = ShellLinkHeader.ShowCommand = 'SHOWMINNOACTIVE',
`Target Changed path` = lowcase(string=LinkInfo.Target.Path) != lowcase(string=OldPath) AND OldPath,
`Target Changed size` = ( ShellLinkHeader.FileSize - OldSize != 0 ) AND ShellLinkHeader.FileSize AND OldSize,
`Risky target` = StringData.TargetPath =~ RiskyExe || LinkInfo.Target.Path =~ RiskyExe || LinkTarget.LinkTarget =~ RiskyExe,
`WebDAV` = LinkInfo.Target.RelativeLink.NetworkProviderType = 'WNNC_NET_DAV',
`Line break in StringData.Name` = StringData.Name =~ '''\n''',
`Suspicious argument size` = len(list=StringData.Arguments) > SusArgSize,
`Environment variable script` = ExtraData.EnvironmentVariable =~ '''\.(bat|cmd|ps1|js|vbs|vbe|py)$''',
`No Target with environment variable` = ExtraData.EnvironmentVariable AND StringData.Arguments AND NOT (StringData.TargetPath OR StringData.RelativePath),
`Suspicious hostname` = ExtraData.TrackerData.MachineID AND SusHostnameRegex AND ExtraData.TrackerData.MachineID=~SusHostnameRegex,
`Created in VM` = ExtraData.TrackerData.MacAddress =~ VmPrefixMAC,
`Local Admin` = UID='500',
`Cyrillic Language` = format(format='%s%s',args=[LinkTarget,ExtraData])=~ '''[\x{0400}-\x{04FF}]''',
`Chinese Language` = format(format='%s%s',args=[LinkTarget,ExtraData])=~ '''[\x{4E00}-\x{9FCC}]''',
`Korean Language` = format(format='%s%s',args=[LinkTarget,ExtraData])=~ '''[\x{3131}-\x{314e}|\x{314f}-\x{3163}|\x{ac00}-\x{d7a3}]''',
`Persian Language` = format(format='%s%s',args=[LinkTarget,ExtraData])=~ '''[\x{0600}-\x{06FF}]''',
`Vietnamese Language` = format(format='%s%s',args=[LinkTarget,ExtraData])=~ '''[\x{0102}\x{0103}\x{0110}\x{0111}\x{01A0}\x{01A1}\x{01AF}\x{01B0}\x{1EA0}-\x{1EF9}]''',
`CodePage` = ExtraData.CodePage,
`Has Overlay` = if(condition=ExtraData.Overlay, then=True)
) as Suspicious,
regex_replace(source=base64decode(string=find_b64(data=StringData.Arguments)[0].Base64),re='''[^ -~\s]''',replace='') as ArgumentsDecoded,
sus_cli(data=StringData.Arguments) as SuspiciousCli
FROM results
WHERE if(condition=SuspiciousOnly,
then= join(array=Suspicious) =~ ''':(true|0x|\d)''' OR join(array=SuspiciousCli) =~ ''':(true|0x|\d)''' OR len(list=ArgumentsDecoded) > 20,
else= True )
LET add_suspiciousb64 = SELECT *
if(condition= len(list=ArgumentsDecoded) > 20, then = dict(`Long Base64`=True) + sus_cli(data=ArgumentsDecoded)) as SuspiciousCliB64
FROM add_suspicious
LET upload_results = SELECT *,
upload(file=SourceFile.OSPath) as UploadedLnk
FROM add_suspiciousb64
-- finally return rows and remove suspicious attributes that are not true
SELECT
SourceFile,
ShellLinkHeader,
LinkInfo,
LinkTarget,
if(condition= SuspiciousCliB64,
then= to_dict(item=StringData) + dict(`DecodedBase64`=ArgumentsDecoded),
else= StringData) as StringData,
ExtraData,
to_dict(item={SELECT * FROM items(item=Suspicious) WHERE _value }) +
to_dict(item={SELECT * FROM items(item=SuspiciousCli) WHERE _value }) +
to_dict(item={SELECT * FROM items(item=SuspiciousCliB64) WHERE _value })
as Suspicious
FROM if(condition=UploadLnk,
then= upload_results,
else= add_suspiciousb64 )
column_types:
- name: SourceFile.Mtime
type: timestamp
- name: SourceFile.Btime
type: timestamp
- name: ShellLinkHeader.CreationTime
type: timestamp
- name: ShellLinkHeader.AccessTime
type: timestamp
- name: ShellLinkHeader.WriteTime
type: timestamp