{"id":346,"date":"2017-10-25T20:11:19","date_gmt":"2017-10-25T19:11:19","guid":{"rendered":"http:\/\/kolbi.cz\/blog\/?p=346"},"modified":"2025-01-02T15:01:14","modified_gmt":"2025-01-02T14:01:14","slug":"setuserfta-userchoice-hash-defeated-set-file-type-associations-per-user","status":"publish","type":"post","link":"https:\/\/kolbi.cz\/blog\/2017\/10\/25\/setuserfta-userchoice-hash-defeated-set-file-type-associations-per-user\/","title":{"rendered":"SetUserFTA: UserChoice Hash defeated &#8211; Set File Type Associations per User or Group on Windows 8\/10\/11 and 2012\/2016\/2019\/2022"},"content":{"rendered":"<h1><span style=\"color: #003366;\">SetUserFTA has now its own domain: <a style=\"color: #003366;\" href=\"https:\/\/setuserfta.com\">https:\/\/setuserfta.com<\/a> and this page will only remain for historical reasons.<\/span><\/h1>\n<p>SetUserFTA sets User File Type Associations per command line or script on Windows 8\/10\/11 and Server 2012\/2016\/2019\/2022.<\/p>\n<p><span style=\"color: #ff0000;\"><strong>ATTENTION: if SetUserFTA does not work for http, https and .pdf, please read my blogpost about the<\/strong><\/span> <a href=\"https:\/\/kolbi.cz\/blog\/2024\/04\/03\/userchoice-protection-driver-ucpd-sys\/\">UserChoice Protection Driver<\/a><\/p>\n<h1>the story:<\/h1>\n<p>recently i had to fight a lot with windows file type associations. microsoft changed the way how it works drastically and it is a pain for an administrator to set or to roam FTA&#8217;s. if you followed my blog, you noticed that i already have two posts about FTA on server 2016. hopefully this one will be the last &#8211; because its the missing piece of the puzzle!<\/p>\n<p>i will just quote microsoft on this issue (or feature?):<\/p>\n<blockquote><p><em>In Pre-Win 8, apps could set the default handler for a file type\/protocol by manipulating the registry, this means you could easily have a script or a group policy manipulating the registry. However In Win 8, the registry changes are verified by a hash (unique per user and app)\u00a0 that detects tampering by apps. In the absence of a valid hash, we ignore the default in the registry.<\/em><\/p><\/blockquote>\n<p>Microsoft <a href=\"https:\/\/blogs.technet.microsoft.com\/windowsinternals\/2017\/10\/25\/windows-10-how-to-configure-file-associations-for-it-pros\" target=\"_blank\" rel=\"noopener\">offers a solution<\/a> with GPO, but it is Computer-based and not User-based &#8211; and rather complicated. this means, you can not associate your Users on the same Server\/Client with different file types. for example:<\/p>\n<p>you have a PDF viewer and a PDF editing software on your XenApp server. Now you want that a certain group opens their PDF&#8217;s in the editor and the others only in the viewer (for licensing reasons for example). this is NOT possible anymore and Microsoft states &#8220;it is by design&#8221; and &#8220;this is a security measure&#8221;.<\/p>\n<p>the hash is secret. Microsoft will not share it with you and obviously doesnt even share it with Citrix &#8211; this made me angry and angry me doesnt like a broken system. because i am into reverse engineering and security, i decided to look for the hash algorithm &#8211; and yes, i succeeded.<\/p>\n<p>but ever thought about why microsoft is doing this? is it really about malware hijacking or maybe it is all about &#8220;setting our defaults and you must accept them&#8221;? why not simply display a popup where the user has to confirm an FTA change?<\/p>\n<blockquote><p>&lt;TL&gt;&lt;DR&gt;<\/p>\n<p style=\"padding-left: 30px;\">a filetype is protected by a hash in the user registry &#8211; for example:<\/p>\n<p style=\"padding-left: 30px;\">HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.txt\\UserChoice\\Hash<\/p>\n<p style=\"padding-left: 30px;\">if the secret hash doesn&#8217;t match, the file type association is not being used and the system default kicks in.<\/p>\n<p style=\"padding-left: 30px;\"><strong>SetUserFTA generates this secret hash for a supplied extension.<\/strong><\/p>\n<p>&lt;\/TL&gt;&lt;\/DR&gt;<\/p><\/blockquote>\n<h1>how to use SetUserFTA:<\/h1>\n<p>i made it very easy for you and the only thing you have to supply is the extension and the ProgId (optional since Version 1.1, a groupname). it works just like assoc.exe:<\/p>\n<blockquote><p><strong>SetUserFTA.exe extension progid (optional:Groupname)<\/strong><\/p>\n<p>or<\/p>\n<p><strong>SetUserFTA.exe configfile<\/strong><\/p>\n<p>and since v1.7<\/p>\n<p><strong>SetUserFTA.exe get<\/strong><\/p>\n<p>will show all protected filetypes, just like <a href=\"https:\/\/kolbi.cz\/blog\/2017\/12\/09\/getuserfta-display-user-file-type-associations-on-windows-10-and-server-2016\/\" target=\"_blank\" rel=\"noopener\">GetUserFTA<\/a><\/p>\n<p><strong>SetUserFTA.exe del extension<\/strong><\/p>\n<p>will delete an association from the user registry<\/p><\/blockquote>\n<p>Example:<\/p>\n<p><strong>SetUserFTA.exe .pdf AcroExch.Document.DC<\/strong><\/p>\n<p>this will associate .pdf file with Acrobat Reader for the current user.<\/p>\n<p><strong>SetUserFTA.exe .pdf AcroExch.Document.DC &#8220;Adobe Acrobat Users&#8221;<\/strong><\/p>\n<p>this will associate .pdf files with Acrobat Reader\u00a0<em>only if the current user is member of the &#8220;Adobe Acrobat Users&#8221; group.\u00a0if the group contains spaces, <strong>you must use quotes<\/strong>.<\/em><\/p>\n<p><strong>SetUserFTA.exe \\\\mydomain.local\\fileshare\\SetUserFTAconfig.txt<\/strong><\/p>\n<p>this will read all associations from the config file and set them. the file can be on a share or locally. just add every filetype on a new line like this:<\/p>\n<pre>.pdf, AcroExch.Document.DC, GRP_Adobe_Reader<\/pre>\n<p>values have to be separated by a comma. the group is optional.<br \/>\nusing a config file, group names with spaces\u00a0<em>must<strong> not <\/strong>use quotes (but using SetUserFTA per command line they have to)<\/em>.<\/p>\n<p><strong>Note:<\/strong> <em>you can supply a domain with the group name like &#8220;DOMAIN\\Adobe Reader&#8221; or even in UPN format.\u00a0<\/em><\/p>\n<p>a valid config file could look like this (<strong>since v1.7 you can add comments by starting a line with #<\/strong>):<\/p>\n<p><a href=\"http:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/configfile-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-428 size-full\" src=\"http:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/configfile-1.png\" alt=\"\" width=\"776\" height=\"180\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/configfile-1.png 776w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/configfile-1-300x70.png 300w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/configfile-1-768x178.png 768w\" sizes=\"auto, (max-width: 776px) 100vw, 776px\" \/><\/a><\/p>\n<p>to create such a config file, you can run &#8220;<strong>SetUserFTA get &gt;config.txt<\/strong>&#8220;. since version 1.4 SetUserFTA also supports protocol handlers in the config file (<strong>mailto, https, http, etc<\/strong>) &#8211; but <em>http<\/em> and <em>https<\/em> will be ignored on Windows 1607. use <a href=\"\/blog\/2017\/11\/10\/setdefaultbrowser-set-the-default-browser-per-user-on-windows-10-and-server-2016-build-1607\/\" target=\"_blank\" rel=\"noopener\"><strong>SetDefaultBrowser<\/strong> <\/a>instead.<\/p>\n<p>you can find the ProgId&#8217;s also in the registry or with <strong>assoc.exe<\/strong>. the easiest way to get what you need, is to manually associate a software with a filetype and then use &#8220;SetUserFTA get&#8221; or check this registry key for the values (replace .log with your extension):<\/p>\n<blockquote><p>HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\<span style=\"color: #ff0000;\"><strong>.log<\/strong><\/span>\\UserChoice<\/p><\/blockquote>\n<p>SetUserFTA will get the current users SID, the registry timestamp and calculates the hash. it will write it (including the ProgId and the extension) to the user registry under the subkey referenced above.<\/p>\n<h1>how can i deploy this?<\/h1>\n<p>here are some ideas (if i missed a good one, please let me know):<\/p>\n<ul>\n<li>use the logon script feature in a GPO (my favorite way)<\/li>\n<li>powershell login script in a GPO<\/li>\n<li>a legacy bat\/cmd logonscript<\/li>\n<li>the Run or RunOnce registry key in HKEY_CURRENT_USER<\/li>\n<li>the startup folder in the startmenu<\/li>\n<li>any software deployment solution like SCCM<\/li>\n<li>a scheduled task<\/li>\n<li>GPO: User Configuration\\Administrative Templates\\System\\Run These Programs at User Logon<\/li>\n<li><a href=\"https:\/\/jkindon.com\/2018\/01\/02\/file-type-association-with-wem-and-setuserfta\/\" target=\"_blank\" rel=\"noopener\">Citrix WEM<\/a>\u00a0(blog post by James Kindon)<\/li>\n<li><a href=\"https:\/\/www.ivandemes.com\/export-import-file-type-associations-fta-successfully-using-uem\/\" target=\"_blank\" rel=\"noopener\">VMware UEM<\/a>\u00a0(blog post by Ivan de Mes)<\/li>\n<\/ul>\n<p>its up to you. be creative \ud83d\ude09<\/p>\n<p><strong>IMPORTANT<\/strong>: SetUserFTA must run in the users context &#8211; no administrative or system privileges. sometimes the timing can be important as well &#8211; make sure it runs after the profile of the user is loaded.<\/p>\n<p><strong>Example:<\/strong><\/p>\n<p><a href=\"http:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-392\" src=\"http:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo.png\" alt=\"\" width=\"1212\" height=\"854\" srcset=\"https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo.png 1212w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo-300x211.png 300w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo-768x541.png 768w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo-1024x722.png 1024w, https:\/\/kolbi.cz\/blog\/wp-content\/uploads\/2017\/10\/SetUserFTA_gpo-1170x824.png 1170w\" sizes=\"auto, (max-width: 1212px) 100vw, 1212px\" \/><\/a><\/p>\n<h1>Tips:<\/h1>\n<p>here are some tips which can help you to find the associations that you need:<\/p>\n<ul>\n<li><strong>ProgIDTool:<\/strong> <a href=\"https:\/\/kolbi.cz\/blog\/2024\/06\/05\/progidtool-display-delete-export-and-register-file-type-progids\/\">My own little tool to manage File Type ProgID&#8217;s.<\/a><\/li>\n<li><strong>assoc.exe | find &#8220;.txt&#8221;<\/strong> &#8211; this will list the ProgID for txt files (only from HKLM)<\/li>\n<li><strong>ftype.exe | find &#8220;txtfile&#8221;<\/strong> &#8211; will list the executable associated with the ProgID txtfile (only from HLKM)<\/li>\n<li><span lang=\"EN-US\"><strong>reg.exe query HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\<span style=\"color: #ff6600;\">.txt<\/span>\\UserChoice \/v ProgId<\/strong> &#8211; gets the ProgId of the User FTA for your file extension<\/span><\/li>\n<li>if you encounter a ProgId that looks like &#8220;<strong>Applications\\uedit64.exe<\/strong>&#8220;, you need to deploy the corresponding entry from &#8220;HKEY_CURRENT_USER\\SOFTWARE\\Classes&#8221; as well. to roam it with UPM in a Citrix environment you can use my <a href=\"\/blog\/2017\/10\/14\/user-file-type-association-roaming-on-server-2016-with-citrix-user-profile-manager\/\">workaround<\/a>.<\/li>\n<li>you can override HKLM associations (ProgId&#8217;s) in HKCU. for example: HKEY_CLASSES_ROOT\\.vsdx can be imported to HKEY_CURRENT_USER\\SOFTWARE\\Classes\\.vdx and then it will has precedence. if you do that, you need to roam it properly (UsrClass.dat).<\/li>\n<li>if you still see the OpenWith dialog (especially after adding new applications: &#8220;<strong>keep using this app<\/strong>&#8220;) you can disable this feature with this registry key:[HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer]<br \/>\n\u201cNoNewAppAlert\u201d=dword:00000001<br \/>\nthis registry key also works with HKEY_CURRENT_USER!<br \/>\nthe GPO\u00a0<strong><em>Do not show the \u2018new application installed\u2019 notification<\/em><\/strong> (Windows Components, File Explorer) will only work on HKLM &#8211; it sets the exact same registry key<\/li>\n<\/ul>\n<h1>F.A.Q.<\/h1>\n<p><strong>where did you get the hash algorithm from?<\/strong><\/p>\n<blockquote><p>i reverse engineered it.<\/p><\/blockquote>\n<p><strong>does this mean you did reverse engineer windows itself to recover the algorithm?<\/strong><\/p>\n<blockquote><p>exactly.<\/p><\/blockquote>\n<p><strong>which tools did you use for that?<\/strong><\/p>\n<blockquote><p><a href=\"https:\/\/technet.microsoft.com\/de-de\/sysinternals\/processmonitor.aspx\" target=\"_blank\" rel=\"noopener\">procmon<\/a>, <a href=\"https:\/\/x64dbg.com\" target=\"_blank\" rel=\"noopener\">x64dbg<\/a> and <a href=\"https:\/\/www.hex-rays.com\/products\/ida\/\" target=\"_blank\" rel=\"noopener\">IDA Pro<\/a><\/p><\/blockquote>\n<p><strong>which language have you used to code the app?<\/strong><\/p>\n<blockquote><p>v1.0 &#8211; v1.1.1: assembly. compiled in Tasm (Borland Turbo Assembler) &#8211; i know, very oldschool.<br \/>\nv1.2 and up: gcc and Microsoft Macro Assembler (to create an obj file).<br \/>\nv1.4 is now fully coded in C\/gcc<br \/>\nv1.7 is compiled in tcc<br \/>\nv1.7.1 is using gcc again, because tcc caused to many antivirus false positives<\/p><\/blockquote>\n<p><strong>by assembler you mean machine code?<\/strong><\/p>\n<blockquote><p>yes.<\/p><\/blockquote>\n<p><strong>which platforms does this work on?<\/strong><\/p>\n<blockquote><p>i have tested it on windows 8\/10 and server 2012\/2016\/2019 up to build 1809.<\/p><\/blockquote>\n<p><strong>is it 32bit compatible?<\/strong><\/p>\n<blockquote><p>yes. x64 and x86 (the binary is 32bit).<\/p><\/blockquote>\n<p><strong>can i have the source code?<\/strong><\/p>\n<blockquote><p>no. you can however ask for a quote and select the source code option if you want to implement the functionality in your own product.<\/p><\/blockquote>\n<p><strong>is unicode supported?<\/strong><\/p>\n<blockquote><p>group names can contain unicode characters, but extensions or ProgId&#8217;s not. the &#8220;get&#8221; parameter supports unicode already. SetUserFTA 2.0 will support 100% unicode.<\/p><\/blockquote>\n<p><strong>can it also generate hashes for protocols (http, mailto, etc)?<\/strong><\/p>\n<blockquote><p>yes, but http and https wont work on 1607 or lower. please use my <a href=\"\/blog\/2017\/11\/10\/setdefaultbrowser-set-the-default-browser-per-user-on-windows-10-and-server-2016-build-1607\/\" target=\"_blank\" rel=\"noopener\">SetDefaultBrowser<\/a> instead.<\/p><\/blockquote>\n<p><strong>are there any other limitations?<\/strong><\/p>\n<blockquote><p>not at the moment. version 1.2 adds verbose output and some basic error handling.<\/p><\/blockquote>\n<p><strong>can i break something with your app?<\/strong><\/p>\n<blockquote><p>not really. the only thing that can go wrong are the file type associations, but it will only affect the current user and not the machine. the del parameter is destructive, but if you do something wrong, it can be fixed by using SetUserFTA again with proper parameters.<\/p><\/blockquote>\n<p><strong>which privileges are needed to run this app?<\/strong><\/p>\n<blockquote><p>just plain user privileges.<\/p><\/blockquote>\n<p><span style=\"color: #ff0000;\">The download is not available anymore since SetUserFTA is now a commercial product. Please visit <a href=\"https:\/\/setuserfta.com\">https:\/\/setuserfta.com<\/a> for more information.\u00a0<\/span><\/p>\n<p>If you plan to use SetUserFTA in a commercial or professional (non-private) environment, you can request a quote on this link: <a href=\"https:\/\/setuserfta.com\/request-a-quote\/\">https:\/\/setuserfta.com\/request-a-quote\/\u00a0<\/a><\/p>\n<p><span style=\"color: #ff0000;\"><strong>ATTENTION: if SetUserFTA does not work for http, https and .pdf, please read my blogpost about the<\/strong><\/span> <a href=\"https:\/\/kolbi.cz\/blog\/2024\/04\/03\/userchoice-protection-driver-ucpd-sys\/\">UserChoice Protection Driver<\/a><\/p>\n<p><b>Version 1.1 &#8211; adds support for group membership checking<br \/>\nVersion 1.2 &#8211; is completely rewritten in C. it also offers now verbose output on errors<br \/>\nVersion 1.3\u00a0&#8211; new funtionality: multiple file type associations with a configuration file<br \/>\nVersion 1.4\u00a0&#8211; support for protocols like mailto, https, http, etc (only for Windows 1703 and newer)<br \/>\nVersion 1.5 &#8211; support for Windows 8.x and Server 2012\/R2<br \/>\n<\/b><b>Version 1.6 &#8211; added protocols (except http and https) support on 1607 or lower builds<br \/>\nVersion 1.7 &#8211; get and del parameters added, # char for comments in config files, EULA<br \/>\nVersion 1.7.1 &#8211; fixes false positive antivirus detections<br \/>\nVersion 1.8.1 &#8211; works with Microsoft UCPD.sys active. Available from <a href=\"https:\/\/setuserfta.com\">https:\/\/setuserfta.com<\/a> as personal edition.<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>SetUserFTA has now its own domain: https:\/\/setuserfta.com and this page will only remain for historical reasons. SetUserFTA sets User File Type Associations per command line <a class=\"mh-excerpt-more\" href=\"https:\/\/kolbi.cz\/blog\/2017\/10\/25\/setuserfta-userchoice-hash-defeated-set-file-type-associations-per-user\/\" title=\"SetUserFTA: UserChoice Hash defeated &#8211; Set File Type Associations per User or Group on Windows 8\/10\/11 and 2012\/2016\/2019\/2022\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":392,"comment_status":"closed","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,14,6,5],"tags":[21,23,15,16,22,19,20,18],"class_list":["post-346","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-citrix","category-security","category-windows","category-xenapp","tag-acrobat","tag-association","tag-commandline","tag-euc","tag-filetype","tag-hash","tag-pdf","tag-userchoice"],"_links":{"self":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/346","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=346"}],"version-history":[{"count":93,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions"}],"predecessor-version":[{"id":1222,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/posts\/346\/revisions\/1222"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/media\/392"}],"wp:attachment":[{"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/media?parent=346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/categories?post=346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kolbi.cz\/blog\/wp-json\/wp\/v2\/tags?post=346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}