UPDATE 05.10.2024: Microsoft has updated UCPD.sys multiple times since my initial blog post. The current version is 3.1, and it blocks the following executables from changing HTTP, HTTPS, and .PDF file associations:
dllhost.exe
reg.exe
rundll32.exe
powershell.exe
regedit.exe
wscript.exe
cscript.exe
cmd.exe
InfDefaultInstall.exe
pwsh.exe
WmiPrvSE.exe
UPDATE 30.05.2024: I have released a SetUserFTA update that works with UCPD.sys. Its available for personal use only and can be downloaded on SetUserFTA.com
This is probably not a permanent solution, because Microsoft can block it with an updated UCPD.sys very quickly. It is a rather hacky approach and might not work for everyone, but it should be fine for personal use.
UCPD.sys – the initial discovery
Starting in February, multiple people reported on my blog that setting http and https protocols with SetUserFTA and SetDefaultBrowser stopped working for them – means, changing the Default Browser was not possible anymore with my tools. I have compiled a debug version to get more information from the affected users/machines and to my surprise, writing to the corresponding registry keys returned ACCESS_DENIED and it was also not possible to edit those keys with regedit, reg.exe or PowerShell anymore.
the registry keys in question are:
HKCU\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice HKCU\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
Changing the default browser was still working by using the Settings app in Windows, but modifying those keys by scripts or tools seemed to be blocked somehow.
The first reports were all from Windows 10 Pro users – and only from private environments. I created some test VM’s to analyze the issue, but everything was still working fine for me, even after applying the latest windows updates – I was not able to reproduce the issue myself.
I got more reports and wondered whats going on, because none of my VM’s had this “issue”. then – after some days, multiple reboots and building multiple VM’s, suddenly those registry keys were being blocked on some my VM’s too – without any new updates or changes (at least not visible ones). it somehow activated this “protection”, but i was not able to trigger this behavior in a reliable matter with new VM’s.
I did many, many tests to understand what is going on here. I discovered, that even with full permissions or SYSTEM privileges, these registry keys cannot be edited anymore. this already smelled like a driver based protection, but why and how would Microsoft do something like that? Initially I expected this “feature” to be located in an existing driver, because everything else would be too easy to defeat – but it turned out, that Microsoft indeed created a dedicated driver for this!
I ran a lot of different tests on my VM’s and i figured – by blackbox testing – that there must be a deny list of specific processes like regedit.exe, reg.exe and powershell.exe but that some (Microsoft) processes still can modify those keys – but no 3rd party utilities anymore.
I also found out that the protection does not run in Windows safe mode – this was another hint about a driver – but how can we find out, which driver is responsible for that?
there are multiple approaches for this and one idea that I had, was really straight forward: if this is a driver, it probably contains the path and names of the protected registry keys and we can just “grep” through the driver files and look for the string “UrlAssociations”. drivers are usually located in C:\Windows\System32\drivers and have a .sys extension.
here is a simple PowerShell script that scans all drivers for the string “UrlAssociations”:
that gives only one hit! if we check the properties of UCPD.sys it says: “UserChoice Protection Driver” – that is a really helpful description – and a very creative name /s
btw: findstr.exe does not work in this case, because it cannot handle unicode strings.
here is a screenshot of the drivers properties:
disassembling this driver confirmed my previous findings: there is a blacklist for processes and also a whitelist for Microsoft signed binaries. check the following screenshots:
from this list I noticed that .pdf seems to be protected too and my tests confirmed that. the corresponding registry key is following:
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.pdf\UserChoice
a windows driver can be administered with builtin tools like sc.exe or fltmc.exe – if its a filter driver, which obviously is the case here.
we cannot simply unload this driver, BUT we can of course disable it! this can be done by this one-liner – in an elevated PowerShell followed by a reboot.
New-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\UCPD” -Name “Start” -Value 4 -PropertyType DWORD -Force
this brings back the functionality of SetUserFTA, but sadly requires administrative permissions and a reboot.
in my tests I also noticed that there is an UCPDMgr.exe in the system32 directory. disassembling this binary didn’t reveal much. there is code which configures the driver and changes some other registry keys related to it. it didn’t look like this was useful and I focused more on the driver itself therefore.
but @GHaslinger found out (his blogpost – in german), that this binary runs as a scheduled task and reverts some registry values, if you changed them manually and that it will eventually re-enable the driver! to fully disable the driver, you must also disable the Scheduled Task therefore:
you can disable this task in a script by using powershell with this command (run as administrator):
Disable-ScheduledTask -TaskName ‘\Microsoft\Windows\AppxDeploymentClient\UCPD velocity’
after this change, the driver will not get enabled again and you can use SetUserFTA or SetDefaultBrowser without blocking again (if you have disabled the driver too of course).
but what is this driver all about? does it do other things? what is the point of it?
beside of the http, https and .pdf blocking, there are references to following registry keys in the driver: ShellFeedsTaskbarViewMode, IsFeedsAvailable, TaskbarDa, DeviceRegion
all these references hint at the changes that Microsoft announced for the EEA policy in Windows (Widgets, Feeds, Default Browser):
https://borncity.com/win/2023/11/17/windows-10-11-changes-due-to-the-european-digital-markets-act/
https://www.theverge.com/2023/9/5/23859537/microsoft-windows-11-default-browser-links-eu-eea-changes
but i got reports from non-EU users too and the driver gets loaded on machines outside of europe as well AND it blocks changing the default browser too. Im not sure if the geo-detection is just buggy or if the reason is a completely different one. Microsoft does not have any documentation or announcement about this driver, but the EEA changes were planned to rollout until April 2024 – so that would actually match.
TL/DR:
Microsoft implemented a driver based protection to block changes to http/https and .pdf associations by 3rd party utilities. the rollout was staggered and activated “randomly”, but in the meantime I got many reports – also from business or education environments (but not Server OS).
Microsoft also updated the driver during my tests (from 2.0 to 2.1) and extended the deny list of executables. this means, they can change the behavior almost on the fly and add new tricks or block additional extensions/protocols!
For this reason, its the safest to disable the driver for the moment – or if you are brave enough, you can even delete it by using following command (in an elevated cmd.exe and reboot afterwards):
sc.exe delete UCPD
when you delete it, the UCPDMgr.exe does not activate it again – at least that didn’t happen in my tests. if you only want to disable the driver you can use these two commands in an elevated powershell:
New-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\UCPD” -Name “Start” -Value 4 -PropertyType DWORD -Force
Disable-ScheduledTask -TaskName ‘\Microsoft\Windows\AppxDeploymentClient\UCPD velocity’
Then you have to reboot and this protection is gone. maybe a future windows update will re-enable it. we will see.
But are there other ways around this protection? Yes – and i have released an updated SetUserFTA to work with the activated driver. You can find it on https://setuserfta.com
If you have FSLogix installed, you can use its redirection functionality to override this driver with a simple ruleset just like this:
Are there other utilities affected by this “protection”? Yes, there are already knowledge base articles from VMware and Ivanti:
Issue with DEM FTA and Default Browser settings post applying Feb24/March24 Monthly windows patches(KB5035845)
https://kb.vmware.com/s/article/97169
Microsoft has implemented a very aggressive measure with this driver and obviously didn’t think about the impact of it in enterprise environments. maybe we will see additional processes in the whitelist in the future – but to be honest – i doubt so.
Great writeup and investigation! The problem also hit our corporate Windows 10 VDI desktops and we were puzzled why things stopped working. These Microsoft tricks are baffling and hard to find!
I found Gunnar Haslinger’s finding about Microsoft’s possible try to adhere to the EU directive UCPD (Unfair Commercial Practices Directive) quite amusing, although in the end, it is for their own benefit…
Thank you oh so much for this article. We stumbled upon this issue in our exams environment where we had blocked Edge and made Chrome the default browser/media player/PDF viewer. This worked fine for many years but only a few days ago we found we had a problem. And now just a few days later we have a workaround!
I just reversed everything myself, ucpdmgr has everything gated on a velocity feature, so if you use vivetool to disable velocity feature ID 44860385, ucpdmgr will DISABLE the driver when it runs
so I guess the easiest way is to disable that velocity feature, then run ucpdmgr once as admin to disable the driver, then reboot to ensure it’s no longer loaded
great find! thanks for this info. I spent many hours myself trying to find which feature ID is responsible for that and have tried to disable it with vivetool, sadly without success.
With symbols when reversing a binary it’s easy enough.
::IsEnabled() calls ::GetCachedFeatureEnabledState() which gets a function pointer g_wil_details_internalGetFeatureEnabledState and calls it if non-NULL with first argument being velocity feature ID.
I didn’t spend too much time with the exe and focused more on finding ways around the driver. disabling is just a workaround and might not be a solution for all environments anyway. but thanks for the info – I was not on the wrong way with vivetool, but when I played with it, i didn’t know about the driver yet and eventually gave up.
You’re such a life savior. Thank you so much, great investigation and awesome solution! Works like a charm now.