MUICache as an execution artifact: the RegRipper muicache plugin
8 min read
MUICache is the artifact you reach for when you have a path and nothing else. It will not tell you when a binary ran, or how many times, or who clicked it on a multi-user box. What it will tell you, reliably, is that at some point the Windows shell saw a particular full path and pulled a friendly name out of the binary's resources. The RegRipper muicache plugin dumps that list verbatim. Treat it as a low-confidence execution hint with one genuinely useful property: it keys on the full path, so it remembers binaries that have since been renamed or deleted.
Where it lives
MUICache has moved over the years, which is the first thing that trips people up. There are two locations you will actually encounter:
- Modern Windows (Vista/7 and later):
HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache. TheHKCU\Software\Classesportion is backed by UsrClass.dat, not NTUSER.DAT. This matters for acquisition: if you only grabbed NTUSER.DAT, you do not have the modern MUICache. You need%LOCALAPPDATA%\Microsoft\Windows\UsrClass.dat. - Legacy:
HKCU\Software\Microsoft\Windows\ShellNoRoam\MUICache, which lives in NTUSER.DAT. This is the older XP-era location and the one a lot of documentation still quotes. RegRipper'smuicache.plhistorically targeted theShellNoRoampath.
This is worth being precise about because the two paths are parsed by different code. In this site's parser, the NTUSER.DAT ShellNoRoam\MUICache key is handled by the muicache plugin, and the UsrClass.dat Local Settings\...\Shell\MuiCache key is handled by a separate usrclass_muicache plugin. Same artifact, two hives, two plugins. If you only run one, you may miss the data entirely depending on the OS version. On a modern host, the UsrClass.dat copy is the one that will be populated.
What populates it
The mechanism is mundane, which is why MUICache is reliable for what it does. When the shell needs to display a friendly name for an application — the name that shows up in places the OS wants something human-readable rather than iexplore.exe — it reads the binary's version resources (specifically the FileDescription string), and caches the result so it does not have to crack the PE open again next time.
The cache write happens the first time the shell handles that binary. Double-clicking it in Explorer, launching it from a shortcut, the OS resolving it for a context menu or a file association — anything that routes through the shell's name-resolution path will seed an entry. The key word is shell. MUICache is a shell cache, not a process-creation log.
The structure: value name is the path
The layout is as simple as it gets, which is reflected in the plugin's two columns:
- Value name = the full binary path, e.g.
C:\Program Files\Internet Explorer\iexplore.exe. - Value data = the cached friendly name (
FriendlyAppName/FileDescription), e.g.Internet Explorer.
So a parsed entry is just:
Executable: C:\Users\jdoe\AppData\Local\Temp\update.exe
Friendly name: Microsoft Update Health Tools
That is the whole record. No FILETIME embedded in the value. No run count. No focus time. The only timestamp anywhere near it is the LastWrite of the MUICache key itself, and that is a single timestamp for the whole key — it tells you when something in the cache last changed, not when any individual binary was seen. Do not attribute the key's LastWrite to a specific entry.
Not every value under the key is a path-to-name pair. The key also holds a scattering of @-prefixed values (indirect string references like @%SystemRoot%\system32\...,-123) and LangID-style housekeeping values. RegRipper's plugin and this site's parser both filter values whose names start with @, leaving the entries that actually carry full executable paths. When you read raw output from another tool, mentally discard the @ lines; they are resource-string pointers, not evidence of execution.
What it proves
A MUICache entry proves that the shell, running in the context of the user whose hive you are looking at, resolved a friendly name for the binary at that exact path. In practice that almost always means the binary was launched or otherwise handled through the shell. It is genuine execution-adjacent evidence and it is attributed to a user, because the data lives in a per-user hive (UsrClass.dat or NTUSER.DAT).
But it is weak execution evidence. "The shell touched this path" is a weaker statement than "this process was created." There are shell operations short of a full launch that can seed an entry, and there is no counter to tell you a single touch from a thousand. Cite MUICache as the path was known to this user's shell, not as this user ran this N times at time T. If you need the stronger claim, you need a stronger artifact.
Why it is still useful: it remembers by path
Here is the property that earns MUICache a place in the kit despite its thinness. The value name is the full path, and the entry persists after the file is gone. Delete the binary, rename it, wipe the directory — the MUICache value stays put until the cache is rebuilt or cleared. That makes it one of the few artifacts that will surface a path like:
C:\Users\jdoe\AppData\Local\Temp\7za_stage2.exe
for a file that no longer exists on disk. An attacker who drops a tool, runs it through the shell, and deletes it leaves the path behind in this cache. The friendly name is a bonus: a binary masquerading as svchost.exe but carrying a FileDescription of Nirsoft NirCmd is a contradiction worth chasing, and MUICache is where you would notice it without ever touching the file. Renamed binaries are caught the same way — the path under which the shell saw it is recorded, not whatever it was renamed to afterward.
The limits, stated plainly
- No timestamps per entry. You cannot say when a binary was seen. The key LastWrite covers the whole key.
- No run count. Seen once and seen a hundred times look identical.
- Shell-only. A binary launched purely from the command line, a service, or a scheduled task — anything that never routes through the shell's name resolution — may never appear. Same blind spot as UserAssist, and for the same architectural reason: these are shell artifacts.
- Friendly name can be missing or junk. If the binary has no version resources, the data may be empty or a fallback. Absence of a friendly name is not absence of execution.
Contrast: UserAssist and Shimcache
It is easiest to place MUICache by triangulating against its neighbors.
UserAssist is the richer per-user artifact. It also tracks shell-driven launches, also attributes to the user, but it adds a run count, a focus count, focus time, and a last-run FILETIME per entry. Where UserAssist gives you "run 12 times, last on 2026-05-21," MUICache gives you "seen, here is the friendly name." If both contain the same path, lean on UserAssist for the quantitative claim and use MUICache as corroboration — particularly for the friendly name, which UserAssist does not record.
Shimcache (AppCompatCache) is the other direction: system-wide, not per-user, no attribution, but it carries the file's standard-information modification time and, on some versions, an execution flag. Shimcache answers "this binary was present on the system" with a path and an $STANDARD_INFORMATION modified timestamp; MUICache answers "this user's shell saw this path" with a friendly name. Neither gives you a reliable execution time on its own. The move is to pivot: a path in MUICache that also appears in Shimcache, AmCache, and Prefetch is a path you can build a timeline around, with MUICache supplying the user attribution and the friendly name and the others supplying the timestamps.
Tools
- RegRipper's
muicacheplugin. Dumps the key's path-to-name pairs, filtering the@-prefixed resource strings. One line per binary. Read the plugin source to confirm exactly which key path your version targets — older copies point at theShellNoRoamNTUSER.DAT location, so on a modern host make sure you are also parsing the UsrClass.datLocal Settings\...\Shell\MuiCachekey. - Eric Zimmerman's RECmd with a MUICache batch file will pull the same values into CSV.
- The parser on this site surfaces both locations: the NTUSER.DAT
ShellNoRoam\MUICachekey and the UsrClass.dat copy, each as its own table withExecutableandFriendly namecolumns. You can analyze UsrClass.dat in your browser without uploading the hive anywhere.
If you want the full list of registry plugins and which hive each one reads, see the RegRipper plugins reference.
How to use it in a case
Do not build a finding on MUICache alone. Use it for two things it does well. First, surfacing deleted-by-path binaries: scan the entries for paths in %TEMP%, %APPDATA%, \Users\Public\, or any directory that should not contain executables, and check whether those files still exist on disk. The ones that do not are your most interesting leads. Second, friendly-name contradictions: a path that claims to be a system binary but carries a third-party FileDescription is a renamed tool, and MUICache caught the rename for free.
Then pivot. Take the path to Prefetch for execution times, to AmCache for the SHA-1 and first-seen, to UserAssist for run counts and last-run, and to the MFT to recover the file or its metadata if it has been deleted. MUICache hands you the thread; the other artifacts let you pull it. Used that way — as a fast index of paths the shell has seen, deleted files included — it earns its place. Used as an execution log, it will quietly mislead you, because it does not have the timestamps or counts to be one.