MuiCache¶
What MuiCache is¶
When a user starts a program, Windows reads the program's version resources for the name the
shell should show (the FileDescription, for example "Windows Command Processor" for
cmd.exe) and caches it per user in MuiCache. Windows 8 and later also cache the company
(CompanyName). The cache is keyed by the program's full path:
- Windows 8 and later: two values per program,
<path>.FriendlyAppNameand<path>.AppCompany. - Windows Vista and 7: one value per program,
<path>, holding the friendly name. - Windows XP: the same form, in
NTUSER.DAT.
MuiCache can provide program-execution leads for a user's shell session, including programs on removable drives, network shares and folders that no longer exist, with the name and company the file itself gave.
Best conclusion: this shell profile cached a file's path, description and company. Correlate it with other execution artifacts. The profile does not identify the account the process ran as. MuiCache has no time per program and no run count.
Location¶
C:\Users\<user>\AppData\Local\Microsoft\Windows\UsrClass.dat Windows Vista and later
Local Settings\Software\Microsoft\Windows\Shell\MuiCache
C:\Documents and Settings\<user>\NTUSER.DAT Windows XP
Software\Microsoft\Windows\ShellNoRoam\MUICache
LangID (the language of the cached strings) is not a program and is left out. Values named
@<file>,-<number> (@shell32.dll,-22019) are resource strings the shell cached for its own
menus and file types, not programs; they are left out and counted in the summary. On Windows Vista
and later, NTUSER.DAT has no MuiCache.
Collect UsrClass.dat (and NTUSER.DAT) with their transaction logs for every profile, and the
system's SYSTEM and SOFTWARE hives for the host and user names.
Analyst cautions¶
- Profile owner is not necessarily the process account. A program started with another
account can display a window in this user's session and leave metadata in this user's cache.
UserandUserSididentify the hive's owner, not the process security context. - No time per program.
KeyLastWrittenUTCis the key's last write: the most recent change to any of its programs, not when a particular one ran. Prefetch, BAM, UserAssist and event logs give times. - Not only programs the user started by hand. A DLL or program the shell itself loaded (for
Open with, a shell extension, an installer's child) can appear, such asexplorerframe.dllorshell32.dll. - The name comes from the file.
FriendlyAppNameandAppCompanyare what the file's version resources said when it ran. Malware can claim any description and company; a renamed tool keeps its original description, which can reveal it (a file namedsvchost.exewhose friendly name is a remote access tool). - One entry per path. Running the same program again doesn't add an entry; a copy at another path does. A program's entry can stay after the file is deleted.
- Both forms for one path. When a path has a friendly name in both forms (an upgraded profile), each gets its own record, so neither value is lost.
- Damaged values. A value that isn't a string, isn't valid UTF-16 or can't be read whole keeps
its bytes (
FriendlyAppNameRaw,AppCompanyRaw) and is reported inProblems. Invalid UTF-16 can also produce replacement characters in the displayed text; use the raw column for the original bytes.
Parse with Juntei¶
Usage: juntei parse-registry muicache <INPUT> [OPTIONS]
Input:
-d, --directory <DIR> Recursively find UsrClass.dat and NTUSER.DAT hives
-f, --file <FILE> Parse one UsrClass.dat or NTUSER.DAT
--log1/--log2 Supply transaction logs explicitly
--no-logs Do not replay logs
Output:
-o, --output <FILE> Save records
-t, --output-type <TYPE> csv, json, or jsonl
juntei parse-registry muicache -d evidence/ -o muicache.csv
juntei parse-registry muicache -f UsrClass.dat -t jsonl \
| jq 'select(.Path | test("\\\\(Users|ProgramData|Temp)\\\\"; "i"))'
The summary lists the programs outside the Windows and Program Files folders (user folders,
other drives, network shares) with their users, and the number of resource strings left out.
Program Files folders with other names (on Windows in other languages) are listed too.
Relative paths and paths that escape an environment-variable folder remain listed. Ordinary
drive paths are checked after resolving . and .. components without accessing the examiner's
file system.
Output fields¶
| Field | Interpretation |
|---|---|
Host, User, UserSID, SourcePath |
Host, the profile folder's name, the user's SID (a UsrClass.dat's root key names it; else the system's ProfileList), and the hive. |
HiveType |
UsrClass.dat or NTUSER.DAT. |
Path |
The program's path: the value's name without .FriendlyAppName or .AppCompany. |
FriendlyAppName |
The program's description, from <path>.FriendlyAppName or <path>. |
AppCompany |
The program's company, from <path>.AppCompany (Windows 8 and later). |
KeyPath, KeyLastWrittenUTC |
The MuiCache key, and its last write: the most recent change to any of its programs. |
FriendlyAppNameRaw, AppCompanyRaw |
The value's bytes (hex), when they aren't text that decodes cleanly. |
TransactionLogStatus, LogsApplied |
Registry recovery context: replayed when the logs wrote one of the program's values. |
Problems |
Values that aren't strings, aren't valid UTF-16 or can't be read. |
Investigation strategy¶
- Look at programs in user-writable places (
\Users\,Downloads,Temp,ProgramData), on other drives and on network shares, and at administration, remote access and archiving tools. - Compare the file name with its friendly name and company: a mismatch can reveal a renamed tool or a masquerading file.
- Correlate with Prefetch, BAM and UserAssist (when it ran), Amcache and ShimCache (the file's
hash and presence), and the
$MFT(whether the file is still there). - Use
parse-registry read --recover-deletedonUsrClass.datfor deleted MuiCache values.