Windows.System.AppCompatPCA

Parse the Program Compatibility Assistant launch dictionary for executable launch times.


name: Windows.System.AppCompatPCA
description: |
   Parse the Program Compatibility Assistant launch dictionary for executable launch times.

author: Eric Capuano - @eric_capuano@infosec.exchange

reference:
  - https://aboutdfir.com/new-windows-11-pro-22h2-evidence-of-execution-artifact/

type: CLIENT
parameters:
  - name: FileGlob
    default: C:\Windows\appcompat\pca\PcaAppLaunchDic.txt
  - name: ExecutableRegex
    description: "Regex of EXE of interest."
    default: .
  - name: SearchVSS
    description: "Add VSS into query."
    type: bool

sources:
  - query: |

      -- expand provided glob into a list of paths on the file system (fs)
      LET fspaths <= SELECT FullPath FROM glob(globs=expand(path=FileGlob))

      -- function returning list of VSS paths corresponding to path
      LET vsspaths(path) = SELECT FullPath
        FROM Artifact.Windows.Search.VSS(SearchFilesGlob=path)

      LET parse_log(FullPath) = SELECT FullPath,
          parse_string_with_regex(
            string=Line,
            regex="^(?P<ExePath>[^|]+)\\|" +
              "(?P<LastExecuted>.*)") as Record
        FROM parse_lines(filename=FullPath)
        WHERE Line
          AND Record.ExePath =~ ExecutableRegex

      LET logsearch(PathList) = SELECT * FROM foreach(
            row=PathList,
            query={
                SELECT *
                FROM parse_log(FullPath=FullPath)
            })

      LET include_vss = SELECT * FROM foreach(row=fspaths,
            query={
                SELECT *
                FROM logsearch(PathList={
                        SELECT FullPath FROM vsspaths(path=FullPath)
                    })
                GROUP BY Record
              })

      LET exclude_vss = SELECT * FROM logsearch(PathList={SELECT FullPath FROM fspaths})

      SELECT
        Record.ExePath as ExePath,
        Record.LastExecuted as LastExecuted,
        FullPath
      FROM if(condition=SearchVSS,
            then=include_vss,
            else=exclude_vss)