Windows 8 Secrets: The WinX Menu and its hashing algorithm

Last week, a reader – “Windows Fan” – tipped me off to an article on Vishal Guptas blog indicating how to customize the new WinX menu in Windows 8. (You know, the menu that appears when you right-click the lower-left Start tip.) Not happy with hacking core system files and peeling back file system security, I dug a little deeper to understand what's going on and came up with a simpler solution.

So let's start at the top. The WinX menu is a simple context menu that appears when you right-click the Start tip that appears when you squish the mouse into the lower-left corner of the screen. The purpose of the menu is not to act as a Start Menu replacement but rather as a springboard to perform advanced system functions that are slightly out of reach. For example, if you’re trying to kill a runaway system process, you will probably need quick access to Task Manager, an elevated Command Prompt, and perhaps Programs and Features to uninstall the culprit app. Launching those applications in succession via the Start Screen would be a pain in the rump.

The entries on the menu are driven by shortcut (.lnk) files present in each Group folder located at %LocalAppData%\Microsoft\Windows\WinX. But you can’t manipulate the shortcuts within or add new ones. That’s because at first invocation (e.g. a fresh boot), the menu scans for and only adds approved shortcuts. Why? Again, Microsoft doesn’t want this becoming another Start Menu or, worse, an icon landfill for installers a la Quick Launch back in Windows Vista.

But an argument could be made for that small sliver of folks who genuinely want to lightly extend the menu, perhaps with utilities such as Process Monitor and DebugView. So let’s talk about what makes an approved shortcut.

An approved shortcut – a moniker I made up – is a .lnk file that has the appropriate markings to indicate to Windows “Hey, I’m special.” The marking is a simple 4-byte hash of several pieces of information. From the .lnk itself, two points are collected:

  • The link’s target application path/file (e.g. C:\Games\Minecraft.exe)
  • The link’s target application arguments (e.g. –windowed)

The third ingredient is simply a hard-coded chunk of text, or a salt if you will, to keep things interesting. That string is, literally, “Do not prehash links.  This should only be done by the user.”

With these three strings in hand, Windows then glues them together, lowercases everything, and runs them through the HashData function. But you’re probably wondering at this point, what does it compare to?

Let’s shift our focus to .lnk files. We know them as shortcuts to things. But they’re officially called Shell Links and can store a lot of information on other data objects in Windows. More specifically, they support storing a structure of data called a PropertyStoreDataBlock that acts as a container for arbitrary string or numeric key/value pairs. Yep, the “WinX hash” is stored in here. If you’re curious, the key can be defined as such:

DEFINE_PROPERTYKEY(PKEY_WINX_HASH, 0xFB8D2D7B, 0x90D1, 0x4E34, 0xBF, 0x60, 0x6E, 0xAC, 0x09, 0x92, 0x2B, 0xBF, 0x02);

So to tie it all together, Windows – the Shell specifically – iterates through the .lnk files in each GroupN folder; opens them up; pulls out and concatenates the target path, args, and an arbitrary string; then finally hashes the result. This hash is then compared with the one stored in the .lnk to determine if it’s approved. Rinse and repeat.

If you’re interested in stuffing items into that menu, I wrote a tool to mark your shortcuts as approved. (The source code is on Github, if you're interested.)

NOTE: The WinX menu doesn’t seem to handle architecture-dependent environment string expansion very well, so shortcuts to %ProgramFiles% may not work (e.g. Internet Explorer 64-bit). I suspect this is a WONTFIX given it’s not designed to work with your own shortcuts.

Update: I replaced the executable with a VS2010 compiled copy, sorry. The previous one would not execute on Windows 8 machines w/o Visual Studio 11 installed. (We don't have a VC11 runtime redist. kit yet.)