A persistent mechanism that requires a user interaction is probably deemed to fail, but there is still some potential here (I described some functionality like this before) and that’s why I am going to talk about yet another little trick like this here…
Every once in a while Windows needs to tell the user about something important. The standard way to do it is through these annoying balloons at the bottom of the tray’s area (or system area, or whatever they call it nowadays – this changes all the time). One of the first examples of such ‘important’ notification was the Tour in Windows XP. Anytime you install XP from the scratch, or add a new user and that user logs on, the annoying balloon immediately shows up:
The balloons like this are created using the IUserNotification interface. Clicking the ‘cloud’ area executes a program that is associated with the balloon. And this this is the interactivity part I mentioned. The user needs to click the thing to launch the application associated with the message.
Now that we know how the interactive part works, let’s explore the persistence bit.
Windows uses a mechanism called PostBootReminder to preserve a list of important notifications that system will show after the reboot. The name is misleading as these notifications are user-related and stored in the user’s Registry hive. So it’s not really Post Boot, but when Shell is loaded. One just needs to log off and log on again and the thingie will trigger.
Adding PostBootReminder entries is relatively easy. The below reg file is a simple example of such notification:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\PostBootReminders\Malware] "Title"="Malwaretest" "Text"="Yet another lame persistence mechanism-wannabe..." "ToolTip"="Hello World!" "ShellExecute"="c:\\windows\\system32\\calc.exe" "IconResource"="%SystemRoot%\\\\system32\\\\shell32.dll,-16783" "ShowTime"=dword:00803600 "RetryInterval"=dword:0000060 "RetryCount"=dword:00000060 "TypeFlags"=dword:00000000
As we can see, the entries are stored under the HKCU key:
Once the system reads and creates the notification, it deletes the entry. So, in some way it works like a RunOnce key.
The Tour application that is being executed by Windows XP is scheduled the same way, except it is added not prior to reboot/log off, but when Windows Explorer starts. There is a Registry entry:
that dictates whether the Tour app will get scheduled via PostBootReminders mechanism.
This is obviously a bit of an archaeologic trivia, but I can mention that the name of that PostBootReminders entry is ‘Microsoft.OfferTour’. Of course, being clever reader as you are, you will surely notice that the Tour Registry key, together with a replacement of the Tour program executable (tourstart.exe) could work as a nice persistence mechanism as well (back when replacing files in system32 was easier).
Another trivia to add: there is one more fake PostBootReminders entry added by Windows Explorer on Windows XP. It is called ‘Microsoft.FixScreenResolution’
and is supposed to help fixing the screen resolution. This entry is controlled by the following Registry key:
The conditions when it is launched are a bit more complex than just a presence/value of the Registry entry and are described in detail here.
Going back to the future – Windows 10 continues to use the very same mechanism. The known PostBootReminders entries include:
Going back to the .reg example I posted above – the arguments of the PostBootReminders subkey are passed directly to methods of IUserNotification interface, so their explanation can be easily found by exploring the Microsoft site: Title, Text and TypeFlags, RetryInterval, RetryCount, ShowTime, IconResource, ToolTip. The ShellExecute is just a path to the executable. It is worth mentioning that there is also one more entry that can be added – CLSID – this represents the GUID of the class that will be instantiated if present, but I have not explored it yet and not sure how it works.
As I mentioned, I doubt this thing can fly, but who knows… one could annoy the user, by making the message never go away (hint: RetryCount/RetryInterval), until clicked – same as on the animation below 🙂 [you may need to click to watch]