ModuleAnalysisCache stores metadata about loaded Powershell modules.
Recent updates include filters by regex to enable targeted hunting use cases.
name: Windows.System.Powershell.ModuleAnalysisCache
description: |
ModuleAnalysisCache stores metadata about loaded Powershell modules.
Recent updates include filters by regex to enable targeted hunting
use cases.
reference:
- https://github.com/PowerShell/PowerShell/blob/281b437a65360ae869d40f3766a1f2bbba786e5e/src/System.Management.Automation/engine/Modules/AnalysisCache.cs#L649
parameters:
- name: GlobLookup
default: C:\{Users\*,Windows\System32\config\systemprofile}\AppData\Local\Microsoft\Windows\PowerShell\ModuleAnalysisCache
- name: ModulePathRegex
description: Regex of installed ModulePath to target.
default: .
type: regex
- name: ModulePathIgnoreRegex
description: Regex of installed ModulePath to ignore.
type: regex
- name: FunctionNameRegex
description: Regex of FunctionName to include.
default: .
type: regex
sources:
- query: |
LET Profile = '
[
["Header", 0, [
["Signature", 0, "String", {"length": 13}],
["CountOfEntries", 14, "uint32"],
["Entries", 18, "Array",
{"type": "Entry", "count": "x => x.CountOfEntries"}]
]],
["Entry", "x=>x.Func.SizeOf + x.ModuleLength + 20", [
["Offset", 0, "Value", {"value": "x => x.StartOf"}],
["TimestampTicks", 0, "uint64"],
["ModuleLength", 8, "uint32"],
["ModuleName", 12, "String", {"length": "x => x.ModuleLength"}],
["CommandCount", "x => x.ModuleLength + 12", "uint32"],
["Func", "x => x.ModuleLength + 16", "Array",
{"type": "FunctionInfo", "count": "x => x.CommandCount"}],
["CountOfTypes", "x => x.Func.EndOf", "uint32"]
]],
["FunctionInfo", "x => x.NameLen + 8", [
["NameLen", 0, "uint32"],
["Name", 4, "String", {"length": "x => x.NameLen"}],
["Count", "x => x.NameLen + 4", "uint32"]
]]
]
'
LET parsed = SELECT OSPath,
parse_binary(filename=OSPath, profile=Profile, struct="Header") AS Header
FROM glob(globs=GlobLookup)
SELECT * FROM foreach(row=parsed,
query={
SELECT * FROM foreach(row=Header.Entries,
query={
SELECT OSPath, ModuleName,
timestamp(epoch=TimestampTicks/10000000 - 62136892800) AS Timestamp,
Func.Name AS Functions
FROM scope()
WHERE ModuleName =~ ModulePathRegex
AND NOT if(condition= ModulePathIgnoreRegex,
then= ModuleName =~ ModulePathIgnoreRegex,
else= False )
AND filter(list=Functions,regex=FunctionNameRegex)
})
})