While working through an interview process, I came across the old Microsoft.Windows.Cortana artifacts and wondered what they would look like on my personal computer that I had never configured or given permissions to Cortana. I found a directory named DeviceSearchCache and AppCache#.txt. Within the text file, I found some data that wasn't available in other artifacts or that was different from other artifacts. As a result, I wrote a simple script to parse out the JSON data to a CSV with slightly cleaner headers for easier sorting.
Here is where I'll put my notes and script so far. This is ongoing research and development - very much a work in progress.
C:\Users%USERNAME%\AppData\Local\Packages\Microsoft.Windows.Search_cw5n1h2txyewy\LocalState\DeviceSearchCache\AppCache[##################].txt
The numbers at the end of the filename are the Windows filetime stamp of the iteration of AppCache. It writes numerous times throughout the day, however, it is not consistent to the hour.
The file is in JSON format and not locked - so easily copied out while running.
| Headers | Sample | Hypothesis |
|---|---|---|
| System.FileExtension | {'Value': '.exe', 'Type': 12} | The file extension for the indexed file. |
| System.Software.ProductVersion | {'Value': '1.0.4.0', 'Type': 12} | If available, the product version for the application. |
| System.Kind | {'Value': 'program', 'Type': 12} | Program, document, link, and unknown are the options. |
| System.ParsingName | {'Value': 'Chrome', 'Type': 12} | Anything from app name, to full path, to an AutoGenerated GUID |
| System.Software.TimesUsed | {'Value': 221, 'Type': 5} | Does not match other artifacts like prefetch run count |
| System.Tile.Background | {'Value': 4280291898, 'Type': 5} |
Unsure, may be whether the app also runs in the background? |
| System.AppUserModel.PackageFullName | {'Value': 'Microsoft.BingWeather_4.53.41681.0_x64 __8wekyb3d8bbwe', 'Type': 12} | Full name |
| System.Identity | {'Value': 'Microsoft.BingWeather_8wekyb3d8bbwe', 'Type': 12} | Short name |
| System.FileName | {'Value': 'vmware', 'Type': 12} | Actual filename without extension |
| System.ConnectedSearch.JumpList | List of values, in Screenshot | Contains jumplists for some apps that don't have jumplists in the normal location |
| System.ConnectedSearch. VoiceCommandExamples | Unknown | Not sure yet, all my rows were blank. |
| System.ItemType | Trusted Immersive | Options on my machine are "Trusted Immersive", "Immersive", or "Desktop" |
| System.DateAccessed | 133022364739230000 |
Date of access in Windows Filetime - not last access for all |
| System.Tile.EncodedTargetPath | C:\Users\%USERNAME%\AppData\Local\Programs\Python\Python310\pythonw.exe |
May be full file path or same as ParsingName |
| System.Tile.SmallLogoPath | images\logo.png | Mostly Windows services have this, looks like part of path to the logo/icon image |
| System.ItemNameDisplay | GitHub Desktop | Basic application display name. |
As I messed with the files in the live folder, they would stop being deleted by the system and the "TimesUsed" and "DateAccessed" columns are zeroed out in future captures. I think if the file is open or edited before next write, the system just creates a new one and loses the count somewhere. I started with one AppCache file at the start of me research and now I have 5 of them and all 5 have empty "TimesUsed" and "DateAccessed" columns.
If the value contains "Points: ", that appears consistent with the "Interaction Count" in the automatic jumplists.
If ParsingName starts with 6D809377-6AF0-444B-8957-A3773F02200E or 7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E that seems to refer to the folder C:\Program Files (x86)\. Confirmed by both registry folder values (HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions) and looking at the full path of the executable. If it starts with 1AC14E77-02E7-4E5D-B744-2EB1AE5198B7 or D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27 that seems to refer to System32 or SysWOW64. Last, if it starts with F38BF404-1D43-42F2-9305-67DE0B28FC23, it is located in the C:\Windows folder.
It appears that Tile.Background has a common value of 16777215 on my machine for most applications and then some Windows applications have other larger values.
It appears that the "Type:" is based on what data is in the containing field.
| Type | Hypothesis |
|---|---|
| 0 | list of lists of files/directories |
| 1 | list of Name, Path, Description data for directories and document type files (.txt, .docx, .csv, .pdf, or files opened in a text editor, ex: hex views of other filetypes) |
| 2 | list containing Name, Path, Description data for directories and any other filetype (ex: .py, .lnk, cloud files) |
| 3 | list of Type 2 data that appears to match CustomDestination jumplist data/style with plaintext titles as they appear on hover |
| 4 | list of "Frequent", "Recent", "Recently Closed" data of Type 1 or 2 |
| 5 | an integer |
| 12 | a string |
Adobe Acrobat recent file list
Browser recently closed tabs/windows titles (not the website URL but like "Discord", "One Drive", etc.) - combine with CustomDestinations Jumplist for links
Slack data identifies the "Workspaces" by name in the list - Ex: "SANS Cyber42" (Similar to browsers, combine with CustomDest for link data)
Display names for entries that are unclear in jumplists (Ex: CCleaner shows "AUTOJL" in jumplists but "Run CCleaner" in AppCache)
Some Microsoft programs have jumplist entries but not defined - the options are defined in AppCache (Ex: Snip&Sketch has entries in jumplists but none in plaintext, AppCache has "Take a new snip, New snip in 3 seconds, New snip in 10 seconds" as entries
File Explorer has an entry that includes last visted directories and the date of visit and possible # of unique visits (requires additional testing)
Some apps provide additional data - Ex: PyCharm shows specific .py within a project file where jumplist just shows the general project file
However, I don't see files opened in Browsers in AppCache but that data is in jumplists.
Appears to be default data related to searches that would call Windows data, troubleshooters, and system settings. Not every row has entries in every column and the parser for this breaks at the same row every time I run it and I haven't had time to troubleshoot yet.
Parsed SettingsCache-output.csv will be INCOMPLETE.
Headers are:
ParsingName, ActivationContext, SmallLogoPath, PageID, SettingID, HostID, Condition, Comment, and HighKeywords
| Headers | Sample | Hypothesis |
|---|---|---|
| ParsingName | Classic_{1498BF43-8A3E-4B9C-917B-C419E4501A62}.settingcontent-ms |
File identifier |
| ActivationContext | %windir%\system32\msdt.exe -id NetworkDiagnosticsInbound -ep CortanaSearch |
What is offered/returned |
| SmallLogoPath | %windir%\diagnostics\system\Networking\DiagPackage.dll,-20004 |
Path to a logo |
| PageID | C58C4893-3BE0-4B45-ABB5-A63E4B8C8651 |
Registry - SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ControlPanel\NameSpace\ - Identifies as "Troubleshooting" |
| SettingID | 1498BF43-8A3E-4B9C-917B-C419E4501A62 |
Matches the ParsingName alphanumerics |
| HostID | 12B1697E-D3A0-4DBC-B568-CCF64A3F934D |
Only two unique values through the list |
| Condition | shcond://v1#IsServer;1 |
Windows Shell conditions cached? |
| Comment | Find and fix problems with Windows Firewall | Default text that pops up in search when you search related keywords |
| HighKeywords | windows firewall troubleshooter;troubleshoot windows firewall;troubleshoot firewall;network troubleshooter;troubleshoot network;fix firewall;fix network;network issues;network problems;firewall issues;firewall problems;incoming connections;inbound connections;troubleshooters | Keywords for Search optimizing? |
I will be continuing to work on this as time allows. It is intended only for my research purposes at this time. You can run it from any folder on a Windows machine and it should pull the DeviceSearchCache folder contents from the host machine and copy it to a folder within the working directory along with the CSVs of simply parsed data. The ConnectedSearch.Jumplists needs more parsing but I wanted a quick way to pull on different machines so I could just copy one folder over. I am running this on Python 3.10.4.
