{"id":1205,"date":"2025-07-15T12:11:24","date_gmt":"2025-07-15T11:11:24","guid":{"rendered":"https:\/\/kolbi.cz\/blog\/?p=1205"},"modified":"2025-09-17T15:41:34","modified_gmt":"2025-09-17T14:41:34","slug":"ucpd-sys-userchoice-protection-driver-part-2","status":"publish","type":"post","link":"https:\/\/kolbi.cz\/blog\/2025\/07\/15\/ucpd-sys-userchoice-protection-driver-part-2\/","title":{"rendered":"UCPD.sys &#8211; UserChoice Protection Driver Part 2"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In my <a href=\"https:\/\/kolbi.cz\/blog\/2024\/04\/03\/userchoice-protection-driver-ucpd-sys\/\" target=\"_blank\" rel=\"noreferrer noopener\">previous blog post<\/a>, I explained the functionality of the UCPD.sys driver when it was at version 2.1. Since then, Microsoft has updated the driver multiple times, adding new features and enhancements.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since my primary focus was on file type association, I didn\u2019t write about the other features of UCPD.sys. However, in this blog post, I want to explore those additional and new features in more detail. I had completely reversed the driver, but I didn\u2019t want to share the details because Microsoft would most likely update UCPD.sys right afterwards. But now, the newest version of UCPD.sys includes dynamic updates, allowing Microsoft to change the driver\u2019s behavior at runtime. <a href=\"https:\/\/x.com\/Xusheng1360201\" target=\"_blank\" rel=\"noreferrer noopener\">@Xusheng1360201<\/a> has also <a href=\"https:\/\/binary.ninja\/2025\/03\/25\/default-browser-upcd.html\" target=\"_blank\" rel=\"noreferrer noopener\">published an article<\/a> which covers some UCPD.sys features &#8211; but those features were not active yet at the time of his post.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I don\u2019t want to share too many technical details, since Microsoft is developing UCPD.sys also for good reasons. After Microsoft activated almost all the new features of UCPD.sys about two months ago, I was contacted by several \u201cshady\u201d companies trying to acquire the source code of SetUserFTA or get a trial version just to steal my code. It\u2019s clear that some applications override users\u2019 settings without notifying them, and Microsoft is specifically trying to block exactly these kinds of apps with UCPD.sys.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recently, Microsoft also added code to block some of my attacks against UCPD.sys even before I had released them. It looks like they are using telemetry and Windows Defender data to analyze possible attack methods &#8211; or they might have discovered them on their own &#8211; but this actually happened with at least three of my workarounds, so I don\u2019t think it\u2019s a coincidence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Currently, UCPD.sys is available in version 4.3 as part of the latest public build of Windows 11. Interestingly, the name&nbsp;<em>UserChoice Protection Driver<\/em>&nbsp;no longer accurately reflects its broader scope, since UCPD.sys now also protects other registry keys and includes functionalities beyond just file type associations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Some of the additional protected registry keys can be seen in the following screenshot:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"606\" src=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2-1024x606.png\" alt=\"\" class=\"wp-image-1210\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2-1024x606.png 1024w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2-300x178.png 300w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2-768x455.png 768w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2024\/12\/image-2.png 1230w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If a non-Microsoft application tries to modify these keys, it will get an&nbsp;<em>ACCESS_DENIED<\/em>&nbsp;error. However, a user can still change these settings through the Windows GUI (Settings, Taskbar, etc.), since most Windows binaries are allowed to make those changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is another important detail about UCPD.sys: it generates a lot of telemetry data, which gets sent back to Microsoft. For example, if you change the default browser, the current setting, the new setting, and even the binary that modified the corresponding registry keys are all reported to Microsoft &#8211; including the type of modification (write, delete, rename, etc.). Big Brother is watching you! In my tests, however, this data only was acessible when Windows was configured to send optional diagnostic data (which is mandatory for Insider builds, for example).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But let\u2019s dive into the details of this driver\u2019s features:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Blocking Registry Key Changes by Third-Party Applications<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">As described above and in my last blog post, UCPD.sys mainly protects the modification of specific registry keys. The list of protected keys can vary depending on the region or the Windows edition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Currently the driver contains code to protect the UserChoice and UserChoiceLatest keys for following protocols and extensions: http, https, .pdf, .htm, .html, .doc, .docx, .xls, .xlsx, .ppt, .pptx<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And it also protects the following keys related to Windows features and the UI:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Feeds<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>ShellFeedsTaskbarViewMode<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Feeds<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>IsFeedsAvailable<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\NandI<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>Control<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Feeds<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>EnableFeeds<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>TaskbarDa<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>SOFTWARE\\Policies\\Microsoft\\Dsh<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>AllowNewsAndInterests<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Taskband<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>Favorites<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Taskband<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>FavoritesResolve<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\Shell\\BrandedKey<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>BrandedKeyChoiceType<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\Shell\\BrandedKey<\/code>\n<ul class=\"wp-block-list\">\n<li>Value: <code>AppAumid<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\SearchSettings<\/code><\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\Search<\/code><\/li>\n\n\n\n<li><code>Software\\Microsoft\\Windows\\CurrentVersion\\Feeds<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">I won\u2019t go into detail about what each of these keys does exactly &#8211; they can easily be looked up online. What\u2019s important is that these keys can no longer be changed automatically by non-Microsoft applications.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Blocking ACL Changes to Protected Registry Keys<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Until UCPD.sys v4.2, it was possible to modify the ACL of a protected registry key. This was especially important in the case of file type associations because the&nbsp;<em>UserChoice<\/em>&nbsp;keys have a deny write ACL set for the current user. By using&nbsp;<em>RegSetKeySecurity<\/em>, I was able to reset the ACL and thereby restore write permissions. I used this little trick in SetUserFTA to make my life easier, but shortly after I had implemented it, UCPD.sys also started blocking ACL changes.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"696\" src=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1-1024x696.png\" alt=\"\" class=\"wp-image-1280\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1-1024x696.png 1024w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1-300x204.png 300w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1-768x522.png 768w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-1.png 1524w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Registry Value Deletion Protection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This protection is also new in UCPD.sys v4.3 and is not yet active. I discovered that I could still delete the&nbsp;ProgId&nbsp;and&nbsp;Hash&nbsp;values from the protected&nbsp;<em>UserChoice<\/em>&nbsp;registry key &#8211; but not the&nbsp;<em>UserChoice<\/em>&nbsp;key itself. UCPD.sys was already blocking modifications to these values, but it was still possible to delete them. This was helpful when we wanted to reset or remove an association protected by UCPD.sys. I updated SetUserFTA to use this approach, but shortly afterwards, the new version of the driver introduced code to block it. Currently, this feature only applies to the Office extensions.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-8.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1646\" height=\"868\" src=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-8.png\" alt=\"\" class=\"wp-image-1308\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-8.png 1646w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-8-300x158.png 300w\" sizes=\"auto, (max-width: 1646px) 100vw, 1646px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dynamic Rules &#8211; Configuration Updates for UCPD.sys<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I had already posted about this change on Twitter, but didn\u2019t share too many details. This feature uses a registry key to load a kind of pattern update for the driver. It can include a&nbsp;<em>DenyList<\/em>,&nbsp;<em>AllowList<\/em>, and other content that extends the driver&#8217;s functionality. With this, Microsoft can block unwanted apps from modifying protected registry keys basically on the fly &#8211; <strong>no driver update or reboot needed!<\/strong> I haven\u2019t yet seen a machine with this feature activated, so I can\u2019t say exactly what the rules contain (manually enabling it didn\u2019t create any rules). The value is encrypted and signed, so it won\u2019t be editable anyway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The rules are stored in this registry key:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>HKLM\\SYSTEM\\CurrentControlSet\\Services\\UCPD\\DR<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Self-Defense: Protecting UCPD.sys Service Keys<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">UCPD.sys v4.3 now contains code that can protect its own registry keys. I had used the&nbsp;<em>FeatureV2<\/em>&nbsp;key in a proof of concept to spoof features of the driver. This allowed me, for example, to re-enable blocked binaries without changing any other Windows configuration settings. I never released this code or shared this idea publicly, but now this method will be blocked as well. By the way, this protection also covers the dynamic rules key. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The driver gets its configuration from the following key (which it can now protect itself):<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>HKLM\\SYSTEM\\CurrentControlSet\\Services\\UCPD<br>Value: FeatureV2<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Unknown File Handler Protection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">When a user double-clicks a file with an unknown extension, Windows will catch this and show the&nbsp;<em>OpenWith.exe<\/em>&nbsp;dialog, allowing you to select an installed application to open that file type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An attacker could override this behavior by replacing the path to&nbsp;<em>OpenWith.exe<\/em>&nbsp;with a path to a malicious file. It looks like this has happened in the wild, so Microsoft now protects these keys accordingly. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UCPD.sys will restore the contents of these keys if they do not contain the original values:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>SOFTWARE\\Classes\\Unknown\\shell<\/code><br><code>SOFTWARE\\Classes\\Unknown\\shell\\open\\command<\/code><br><code>SOFTWARE\\Classes\\Unknown\\shell\\openas\\command<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"326\" src=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4-1024x326.png\" alt=\"\" class=\"wp-image-1288\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4-1024x326.png 1024w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4-300x95.png 300w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4-768x244.png 768w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4-1536x489.png 1536w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-4.png 1590w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">File Rename Protection<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One of the first workarounds I discovered was renaming blocked binaries like&nbsp;<em>powershell.exe<\/em>. If you copied the executable and renamed it to&nbsp;<em>powershell2.exe<\/em>, it would bypass UCPD.sys because the the driver only compared the file name against a static list.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UCPD.sys v4.3 now includes code that can detect this attack by checking the PE resources and comparing the actual file name against the&nbsp;<em>OriginalFilename<\/em>&nbsp;value.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This workaround has been widely used all over the internet, and even VMware used this trick in their DEM solution. They simply copied&nbsp;<em>rundll32.exe<\/em>&nbsp;to a temporary location, renamed it, and used it to execute their DLL.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Currently, this detection code is not generally active, but Microsoft is most likely A\/B testing it right now.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-6.png\"><img loading=\"lazy\" decoding=\"async\" width=\"692\" height=\"632\" src=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-6.png\" alt=\"\" class=\"wp-image-1290\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-6.png 692w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2025\/07\/grafik-6-300x274.png 300w\" sizes=\"auto, (max-width: 692px) 100vw, 692px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">UCPD.sys has become quite a sophisticated protection system in the meantime. There are other features that I won\u2019t describe in detail, as they target specific regions or publishers and therefore don\u2019t apply to everyone anyway.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Update 17.09.2025: <\/strong>The cat is out of the bag, and someone else has published the details I had preferred to keep to myself: <a href=\"https:\/\/min.news\/en\/news\/6d1f017397dc54ae939144bf7d3ad396.html\" target=\"_blank\" rel=\"noreferrer noopener\">UCPD.sys regional restrictions<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Currently, UCPD.sys blocks the following types of attacks on Windows 11 Pro:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Write, delete, rename, and ACL changes to the keys listed above<\/li>\n\n\n\n<li>File type associations for all the extensions mentioned above<\/li>\n\n\n\n<li>Injection attacks for a defined list of publishers<\/li>\n\n\n\n<li>UI automation attacks, also for a set of publishers<\/li>\n\n\n\n<li>Unknown file type registry key modifications<\/li>\n\n\n\n<li>RegRenameKey attacks<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The driver has actually evolved a lot since my last blog post, and it now includes some very advanced techniques to protect Windows against malicious attacks. I\u2019ve learned a lot from this, and it\u2019s always fun to analyze the new protections whenever a new UCPD.sys version is released.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the downside is that Microsoft does not document, comment on, or offer any administrative utilities to manage these protections. While they do serve a good purpose, they are not desired in every environment. In particular, the file type associations are causing a lot of headaches, which is why I am still offering and actively updating <a href=\"https:\/\/setuserfta.com\" target=\"_blank\" rel=\"noreferrer noopener\">SetUserFTA<\/a> accordingly.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>In my previous blog post, I explained the functionality of the UCPD.sys driver when it was at version 2.1. Since then, Microsoft has updated the <a class=\"mh-excerpt-more\" href=\"https:\/\/kolbi.cz\/blog\/2025\/07\/15\/ucpd-sys-userchoice-protection-driver-part-2\/\" title=\"UCPD.sys &#8211; UserChoice Protection Driver Part 2\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":1280,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,6],"tags":[19,25,30,33],"class_list":["post-1205","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security","category-windows","tag-hash","tag-microsoft","tag-security","tag-ucpd"],"_links":{"self":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/1205","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/comments?post=1205"}],"version-history":[{"count":46,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/1205\/revisions"}],"predecessor-version":[{"id":1327,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/1205\/revisions\/1327"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/media\/1280"}],"wp:attachment":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/media?parent=1205"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/categories?post=1205"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/tags?post=1205"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}