Jump List AppIDs: What They Are and How to Resolve One
The 16-character hex string in front of .automaticDestinations-ms is not a serial number Windows handed out. It is a hash, and once you understand what it hashes you stop treating an unfamiliar AppID as noise and start treating it as a question.
Every other post in this series leans on AppID mapping. The DFIR walkthrough tells you to triage by AppID first. This is the post it should have linked to.
The filename is the identity
A Jump List file is named for the application that owns it. 1b4dd67f29cb1962.automaticDestinations-ms belongs to one specific application, and 9b9cdc69c1c24e2b.automaticDestinations-ms belongs to another. The hex value is the AppID. There is no separate field inside the file that names the app. The name is the filename, and it is hashed.
There are two ways that hash gets produced, and the distinction matters when a lookup fails.
Most desktop applications never set an identity of their own. For those, the shell computes the AppID from the full path of the executable, lowercased and normalized, and runs it through a CRC-64. Move the same binary to a different path and you get a different AppID. Notepad launched from C:\Windows\System32\notepad.exe and the identical binary copied to C:\Temp\notepad.exe are two different AppIDs to Windows, because the input to the hash changed.
The other case is an application that explicitly sets an Application User Model ID (AppUserModelID), a string like Microsoft.Windows.Explorer or a packaged-app identity. When that string is present, Windows hashes the string instead of the path. UWP and packaged apps, Office, and a handful of first-party tools all do this. Their AppIDs are stable regardless of where the binary lives, which is the entire point of the mechanism.
You resolve by lookup, not by reversing
CRC-64 is one-way. You cannot take 1b4dd67f29cb1962 and compute "Notepad" back out of it. Anyone who tells you they reversed an AppID means one of two things: they looked it up in a table, or they hashed candidate inputs until one matched. There is no third option, so do not waste time trying to invert the hash.
In practice almost everyone uses the reference list that ships with JLECmd. It is the de facto table, community-maintained, and it covers the common applications across Windows versions. Hexacorn published the original research on the derivation and maintains a large mapping as well. For day-to-day triage, the list resolves the AppIDs you will see ninety-something percent of the time without you computing anything.
When the list comes up empty, you build the match yourself. Enumerate the executables present on the host, compute the path-based CRC-64 for each, and look for your AppID in the results. This only works for the path-derived case. An explicit-AppUserModelID app will never match a path hash, so if the host clearly has the application installed and your computed hashes do not produce the AppID, that is a sign the app sets its own identity string and you need the known-string list instead.
A quick way to enumerate the explicit AppIDs already registered on a live host is PowerShell:
Get-StartApps | Sort-Object Name | Format-Table Name, AppID
That returns the AppUserModelID for everything pinned or registered to Start. It will not cover path-derived desktop apps, but it resolves the packaged and first-party identities that the path-hashing approach cannot.
When an AppID is not in any list
This is where it gets useful for an investigation. A blank in the lookup table is not a dead end, it is a signal. The benign explanations come first, as always:
- A portable application run from a USB stick or a download folder. Different path, unknown hash.
- Software installed somewhere non-standard, which is common on developer and admin workstations.
- A legitimate app that simply is not in the public list yet.
Then the explanation that earns the triage:
- A renamed or relocated binary. Attackers copy
cmd.exe,powershell.exe, or a dropped payload to an odd path and run it. The Jump List, if the binary touches the shell in a way that generates one, records an AppID nobody has ever catalogued because nobody has ever run that exact binary from that exact path before. An unmapped AppID with a recentDestListtimestamp is exactly the kind of thread that turns into a finding.
To run it down, take the unknown AppID and treat it as the question "what executable, at what path, hashes to this?" Pivot through the rest of the host: Prefetch, AmCache, and ShimCache give you candidate executable paths. Hash those paths, look for the match. When a path from AmCache hashes to your mystery AppID, you have tied the Jump List to a specific binary that ran on the box, and often to one that should not have been there.
A note on spoofing
Because the filename is just a hash and Windows does not authenticate it, an AppID can be planted. Someone who wants to mislead an analyst can drop a file named for a benign application and fill it with whatever entries they like, or pollute a real one. That is an offensive technique, not a parsing detail, and it is covered in the attacker-side post. For now the takeaway is narrow: the AppID tells you which application a well-behaved Windows shell attributed the activity to. On a host you already suspect of tampering, treat that attribution as a claim to verify, not a fact to cite.
Further reading
- Eric Zimmerman, JLECmd - the canonical AppID reference list lives here.
- Hexacorn, "Jump List AppID derivation" - the original reverse engineering of the CRC-64 input and algorithm.
- The automaticDestinations file format and customDestinations file format posts for where the AppID sits in the container.