diff --git a/res/loc/rufus.loc b/res/loc/rufus.loc
index 0849e65b..32744328 100644
--- a/res/loc/rufus.loc
+++ b/res/loc/rufus.loc
@@ -609,6 +609,7 @@ t MSG_346 "Restrict Windows to S-Mode (INCOMPATIBLE with online account bypass)"
 t MSG_347 "Expert Mode"
 t MSG_348 "Extracting archive files: %s"
 t MSG_349 "Use Rufus MBR"
+t MSG_350 "Use 'Windows UEFI CA 2023' signed bootloaders [EXPERIMENTAL]"
 # The following messages are for the Windows Store listing only and are not used by the application
 t MSG_900 "Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc."
 t MSG_901 "Official site: %s"
diff --git a/src/msapi_utf8.h b/src/msapi_utf8.h
index 7532c262..e0510f41 100644
--- a/src/msapi_utf8.h
+++ b/src/msapi_utf8.h
@@ -26,6 +26,8 @@
 #include <stdio.h>
 #include <shlobj.h>
 #include <ctype.h>
+#include <aclapi.h>
+#include <accctrl.h>
 #include <commdlg.h>
 #include <shellapi.h>
 #include <shlwapi.h>
@@ -89,6 +91,9 @@ static __inline char* wchar_to_utf8(const wchar_t* wstr)
 	int size = 0;
 	char* str = NULL;
 
+	if (wstr == NULL)
+		return NULL;
+
 	// Convert the empty string too
 	if (wstr[0] == 0)
 		return (char*)calloc(1, 1);
@@ -568,6 +573,52 @@ static __inline const char* PathFindFileNameU(const char* szPath)
 	return &szPath[i];
 }
 
+static __inline char* PathCombineU(char* lpDest, char* lpDir, char* lpFile)
+{
+	wchar_t* wret = NULL;
+	DWORD err = ERROR_INVALID_DATA;
+	wchar_t wlpDest[MAX_PATH];
+	wconvert(lpDir);
+	wconvert(lpFile);
+	wret = PathCombineW(wlpDest, wlpDir, wlpFile);
+	err = GetLastError();
+	wfree(lpDir);
+	wfree(lpFile);
+	if (wret == NULL)
+		return NULL;
+	wchar_to_utf8_no_alloc(wlpDest, lpDest, MAX_PATH);
+	SetLastError(err);
+	return lpDest;
+}
+
+static __inline HANDLE FindFirstFileU(char* lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
+{
+	HANDLE ret = INVALID_HANDLE_VALUE;
+	WIN32_FIND_DATAW wFindFileData = { 0 };
+	wconvert(lpFileName);
+	ret = FindFirstFileW(wlpFileName, &wFindFileData);
+	if (ret != INVALID_HANDLE_VALUE) {
+		memcpy(lpFindFileData, &wFindFileData, offsetof(WIN32_FIND_DATAW, cFileName));
+		wchar_to_utf8_no_alloc(wFindFileData.cFileName, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
+		wchar_to_utf8_no_alloc(wFindFileData.cAlternateFileName, lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName));
+	}
+	wfree(lpFileName);
+	return ret;
+}
+
+static __inline BOOL FindNextFileU(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
+{
+	BOOL ret = FALSE;
+	WIN32_FIND_DATAW wFindFileData = { 0 };
+	ret = FindNextFileW(hFindFile, &wFindFileData);
+	if (ret) {
+		memcpy(lpFindFileData, &wFindFileData, offsetof(WIN32_FIND_DATAW, cFileName));
+		wchar_to_utf8_no_alloc(wFindFileData.cFileName, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
+		wchar_to_utf8_no_alloc(wFindFileData.cAlternateFileName, lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName));
+	}
+	return ret;
+}
+
 // This function differs from regular GetTextExtentPoint in that it uses a zero terminated string
 static __inline BOOL GetTextExtentPointU(HDC hdc, const char* lpString, LPSIZE lpSize)
 {
@@ -819,6 +870,28 @@ static __inline BOOL SetFileAttributesU(const char* lpFileName, DWORD dwFileAttr
 	return ret;
 }
 
+static __inline DWORD GetNamedSecurityInfoU(const char* lpObjectName, SE_OBJECT_TYPE ObjectType,
+	SECURITY_INFORMATION SecurityInfo, PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl,
+	PACL* ppSacl, PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+	DWORD ret;
+	wconvert(lpObjectName);
+	ret = GetNamedSecurityInfoW(wlpObjectName, ObjectType, SecurityInfo, ppsidOwner, ppsidGroup,
+		ppDacl, ppSacl, ppSecurityDescriptor);
+	wfree(lpObjectName);
+	return ret;
+}
+
+static __inline DWORD SetNamedSecurityInfoU(const char* lpObjectName, SE_OBJECT_TYPE ObjectType,
+	SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
+{
+	DWORD ret;
+	wconvert(lpObjectName);
+	ret = SetNamedSecurityInfoW(wlpObjectName, ObjectType, SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
+	wfree(lpObjectName);
+	return ret;
+}
+
 static __inline int SHCreateDirectoryExU(HWND hwnd, const char* pszPath, SECURITY_ATTRIBUTES *psa)
 {
 	int ret = ERROR_INVALID_DATA;
diff --git a/src/parser.c b/src/parser.c
index 94ece799..ca48c61e 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1267,7 +1267,7 @@ out:
 }
 
 /*
- * Replace all 'c' characters in string 'src' with the substring 'rep'
+ * Replace all 'c' characters in string 'src' with the substring 'rep'.
  * The returned string is allocated and must be freed by the caller.
  */
 char* replace_char(const char* src, const char c, const char* rep)
@@ -1300,6 +1300,30 @@ char* replace_char(const char* src, const char c, const char* rep)
 	return res;
 }
 
+/*
+ * Remove all instances of substring 'sub' form string 'src.
+ * The returned string is allocated and must be freed by the caller.
+ */
+char* remove_substr(const char* src, const char* sub)
+{
+	size_t i, j, str_len = safe_strlen(src), sub_len = safe_strlen(sub);
+	char* res;
+
+	if ((src == NULL) || (sub == NULL) || (sub_len > str_len))
+		return NULL;
+
+	res = (char*)calloc(str_len + 1, 1);
+	if (res == NULL)
+		return NULL;
+	for (i = 0, j = 0; i <= str_len; ) {
+		if (i <= str_len - sub_len && memcmp(&src[i], sub, sub_len) == 0)
+			i += sub_len;
+		else
+			res[j++] = src[i++];
+	}
+	return res;
+}
+
 /*
  * Internal recursive call for get_data_from_asn1(). Returns FALSE on error, TRUE otherwise.
  */
@@ -1697,8 +1721,7 @@ uint8_t* RvaToPhysical(uint8_t* buf, uint32_t rva)
 static BOOL FoundResourceRva = FALSE;
 uint32_t FindResourceRva(const wchar_t* name, uint8_t* root, uint8_t* dir, uint32_t* len)
 {
-	uint32_t rva;
-	WORD i;
+	uint32_t i, rva;
 	IMAGE_RESOURCE_DIRECTORY* _dir = (IMAGE_RESOURCE_DIRECTORY*)dir;
 	IMAGE_RESOURCE_DIRECTORY_ENTRY* dir_entry = (IMAGE_RESOURCE_DIRECTORY_ENTRY*)&_dir[1];
 	IMAGE_RESOURCE_DIR_STRING_U* dir_string;
@@ -1711,7 +1734,7 @@ uint32_t FindResourceRva(const wchar_t* name, uint8_t* root, uint8_t* dir, uint3
 	if (root == dir)
 		FoundResourceRva = FALSE;
 
-	for (i = 0; i < _dir->NumberOfNamedEntries + _dir->NumberOfIdEntries; i++) {
+	for (i = 0; i < (uint32_t)_dir->NumberOfNamedEntries + _dir->NumberOfIdEntries; i++) {
 		if (!FoundResourceRva && i < _dir->NumberOfNamedEntries) {
 			dir_string = (IMAGE_RESOURCE_DIR_STRING_U*)(root + dir_entry[i].NameOffset);
 			if (dir_string->Length != wcslen(name) ||
diff --git a/src/rufus.c b/src/rufus.c
index 4ba8c378..8e083734 100755
--- a/src/rufus.c
+++ b/src/rufus.c
@@ -1586,6 +1586,10 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
 				StrArrayAdd(&options, lmprintf(MSG_335), TRUE);
 				MAP_BIT(UNATTEND_DISABLE_BITLOCKER);
 				if (expert_mode) {
+					if (!appstore_version && img_report.win_version.build >= 26100) {
+						StrArrayAdd(&options, lmprintf(MSG_350), TRUE);
+						MAP_BIT(UNATTEND_USE_MS2023_BOOTLOADERS);
+					}
 					StrArrayAdd(&options, lmprintf(MSG_346), TRUE);
 					MAP_BIT(UNATTEND_FORCE_S_MODE);
 				}
@@ -1597,7 +1601,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
 				i = remap16(i, map, TRUE);
 				unattend_xml_path = CreateUnattendXml(arch, i);
 				// Remember the user preferences for the current session.
-				unattend_xml_mask &= ~(remap16(0x1ff, map, TRUE));
+				unattend_xml_mask &= ~(remap16(UNATTEND_FULL_MASK, map, TRUE));
 				unattend_xml_mask |= i;
 				WriteSetting32(SETTING_WUE_OPTIONS, (UNATTEND_DEFAULT_MASK << 16) | unattend_xml_mask);
 			}
diff --git a/src/rufus.h b/src/rufus.h
index 24a4dfb0..9240784a 100644
--- a/src/rufus.h
+++ b/src/rufus.h
@@ -629,6 +629,8 @@ typedef struct {
 #define UNATTEND_SET_USER                   0x00040
 #define UNATTEND_DISABLE_BITLOCKER          0x00080
 #define UNATTEND_FORCE_S_MODE               0x00100
+#define UNATTEND_USE_MS2023_BOOTLOADERS     0x00200
+#define UNATTEND_FULL_MASK                  0x003FF
 #define UNATTEND_DEFAULT_MASK               0x000FF
 #define UNATTEND_WINDOWS_TO_GO              0x10000		// Special flag for Windows To Go
 
@@ -636,10 +638,15 @@ typedef struct {
 #define UNATTEND_SPECIALIZE_DEPLOYMENT_MASK (UNATTEND_NO_ONLINE_ACCOUNT)
 #define UNATTEND_OOBE_SHELL_SETUP_MASK      (UNATTEND_NO_DATA_COLLECTION | UNATTEND_SET_USER | UNATTEND_DUPLICATE_LOCALE)
 #define UNATTEND_OOBE_INTERNATIONAL_MASK    (UNATTEND_DUPLICATE_LOCALE)
-#define UNATTEND_OOBE_MASK                  (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK | UNATTEND_DISABLE_BITLOCKER)
+#define UNATTEND_OOBE_MASK                  (UNATTEND_OOBE_SHELL_SETUP_MASK | UNATTEND_OOBE_INTERNATIONAL_MASK | UNATTEND_DISABLE_BITLOCKER | UNATTEND_USE_MS2023_BOOTLOADERS)
 #define UNATTEND_OFFLINE_SERVICING_MASK     (UNATTEND_OFFLINE_INTERNAL_DRIVES | UNATTEND_FORCE_S_MODE)
 #define UNATTEND_DEFAULT_SELECTION_MASK     (UNATTEND_SECUREBOOT_TPM_MINRAM | UNATTEND_NO_ONLINE_ACCOUNT | UNATTEND_OFFLINE_INTERNAL_DRIVES)
 
+/* Used with ListDirectoryContent */
+#define LIST_DIR_TYPE_FILE			0x01
+#define LIST_DIR_TYPE_DIRECTORY		0x02
+#define LIST_DIR_TYPE_RECURSIVE		0x80
+
 /* Hash tables */
 typedef struct htab_entry {
 	uint32_t used;
@@ -786,6 +793,7 @@ extern char* get_token_data_buffer(const char* token, unsigned int n, const char
 extern char* insert_section_data(const char* filename, const char* section, const char* data, BOOL dos2unix);
 extern char* replace_in_token_data(const char* filename, const char* token, const char* src, const char* rep, BOOL dos2unix);
 extern char* replace_char(const char* src, const char c, const char* rep);
+extern char* remove_substr(const char* src, const char* sub);
 extern void parse_update(char* buf, size_t len);
 extern void* get_data_from_asn1(const uint8_t* buf, size_t buf_len, const char* oid_str, uint8_t asn1_type, size_t* data_len);
 extern int sanitize_label(char* label);
@@ -835,6 +843,8 @@ extern uint16_t GetPeArch(uint8_t* buf);
 extern uint8_t* GetPeSection(uint8_t* buf, const char* name, uint32_t* len);
 extern uint8_t* RvaToPhysical(uint8_t* buf, uint32_t rva);
 extern uint32_t FindResourceRva(const wchar_t* name, uint8_t* root, uint8_t* dir, uint32_t* len);
+extern DWORD ListDirectoryContent(StrArray* arr, char* dir, uint8_t type);
+extern BOOL TakeOwnership(LPCSTR lpszOwnFile);
 #define GetTextWidth(hDlg, id) GetTextSize(GetDlgItem(hDlg, id), NULL).cx
 
 DWORD WINAPI HashThread(void* param);
diff --git a/src/rufus.rc b/src/rufus.rc
index f63f9294..7236b2c2 100644
--- a/src/rufus.rc
+++ b/src/rufus.rc
@@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 IDD_DIALOG DIALOGEX 12, 12, 232, 326
 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
 EXSTYLE WS_EX_ACCEPTFILES
-CAPTION "Rufus 4.6.2200"
+CAPTION "Rufus 4.6.2201"
 FONT 9, "Segoe UI Symbol", 400, 0, 0x0
 BEGIN
     LTEXT           "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -399,8 +399,8 @@ END
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 4,6,2200,0
- PRODUCTVERSION 4,6,2200,0
+ FILEVERSION 4,6,2201,0
+ PRODUCTVERSION 4,6,2201,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -418,13 +418,13 @@ BEGIN
             VALUE "Comments", "https://rufus.ie"
             VALUE "CompanyName", "Akeo Consulting"
             VALUE "FileDescription", "Rufus"
-            VALUE "FileVersion", "4.6.2200"
+            VALUE "FileVersion", "4.6.2201"
             VALUE "InternalName", "Rufus"
             VALUE "LegalCopyright", "� 2011-2024 Pete Batard (GPL v3)"
             VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
             VALUE "OriginalFilename", "rufus-4.6.exe"
             VALUE "ProductName", "Rufus"
-            VALUE "ProductVersion", "4.6.2200"
+            VALUE "ProductVersion", "4.6.2201"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/src/stdfn.c b/src/stdfn.c
index ec4933a0..c299967b 100644
--- a/src/stdfn.c
+++ b/src/stdfn.c
@@ -25,6 +25,8 @@
 #include <sddl.h>
 #include <gpedit.h>
 #include <assert.h>
+#include <accctrl.h>
+#include <aclapi.h>
 
 #include "re.h"
 #include "rufus.h"
@@ -1242,3 +1244,73 @@ BOOL UnmountRegistryHive(const HKEY key, const char* pszHiveName)
 
 	return (status == ERROR_SUCCESS);
 }
+
+/*
+ * Take administrative ownership of a file or directory, and grant all access rights.
+ */
+BOOL TakeOwnership(LPCSTR lpszOwnFile)
+{
+	BOOL ret = FALSE;
+	HANDLE hToken = NULL;
+	PSID pSIDAdmin = NULL;
+	PACL pOldDACL = NULL, pNewDACL = NULL;
+	PSECURITY_DESCRIPTOR pSD = NULL;
+	SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
+	EXPLICIT_ACCESS ea = { 0 };
+
+	if (lpszOwnFile == NULL)
+		return FALSE;
+
+	// Create a SID for the BUILTIN\Administrators group.
+	if (!AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID,
+		DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSIDAdmin))
+		goto out;
+
+	// Open a handle to the access token for the calling process.
+	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
+		goto out;
+
+	// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
+	if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
+		goto out;
+
+	// Set the owner in the object's security descriptor.
+	if (SetNamedSecurityInfoU(lpszOwnFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION,
+		pSIDAdmin, NULL, NULL, NULL) != ERROR_SUCCESS)
+		goto out;
+
+	// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
+	if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
+		goto out;
+
+	// Get a pointer to the existing DACL.
+	if (GetNamedSecurityInfoU(lpszOwnFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+		NULL, NULL, &pOldDACL, NULL, &pSD) != ERROR_SUCCESS)
+		goto out;
+
+	// Initialize an EXPLICIT_ACCESS structure for the new ACE
+	// with full control for Administrators.
+	ea.grfAccessPermissions = GENERIC_ALL;
+	ea.grfAccessMode = GRANT_ACCESS;
+	ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+	ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+	ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+	ea.Trustee.ptstrName = (LPTSTR)pSIDAdmin;
+
+	// Create a new ACL that merges the new ACE into the existing DACL.
+	if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS)
+		goto out;
+
+	// Try to modify the object's DACL.
+	if (SetNamedSecurityInfoU(lpszOwnFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
+		NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS)
+		goto out;
+
+	ret = TRUE;
+
+out:
+	FreeSid(pSIDAdmin);
+	LocalFree(pNewDACL);
+	safe_closehandle(hToken);
+	return ret;
+}
diff --git a/src/stdio.c b/src/stdio.c
index 40045751..a6c257b4 100644
--- a/src/stdio.c
+++ b/src/stdio.c
@@ -203,7 +203,7 @@ void DumpBufferHex(void *buf, size_t size)
 			uprintf("%s\n", line);
 		line[0] = 0;
 		sprintf(&line[strlen(line)], "  %08x  ", (unsigned int)i);
-		for(j=0,k=0; k<16; j++,k++) {
+		for(j = 0,k = 0; k < 16; j++,k++) {
 			if (i+j < size) {
 				sprintf(&line[strlen(line)], "%02x", buffer[i+j]);
 			} else {
@@ -212,7 +212,7 @@ void DumpBufferHex(void *buf, size_t size)
 			sprintf(&line[strlen(line)], " ");
 		}
 		sprintf(&line[strlen(line)], " ");
-		for(j=0,k=0; k<16; j++,k++) {
+		for(j = 0,k = 0; k < 16; j++,k++) {
 			if (i+j < size) {
 				if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
 					sprintf(&line[strlen(line)], ".");
@@ -920,3 +920,60 @@ BOOL ExtractZip(const char* src_zip, const char* dest_dir)
 	bled_exit();
 	return (extracted_bytes > 0);
 }
+
+// Returns a list of all the files or folders from a directory
+DWORD ListDirectoryContent(StrArray* arr, char* dir, uint8_t type)
+{
+	WIN32_FIND_DATAA FindFileData = { 0 };
+	HANDLE hFind;
+	DWORD dwError, dwResult;
+	char mask[MAX_PATH + 1], path[MAX_PATH + 1];
+
+	if (arr == NULL || dir == NULL || (type & 0x03) == 0)
+		return ERROR_INVALID_PARAMETER;
+
+	if (PathCombineU(mask, dir, "*") == NULL)
+		return GetLastError();
+
+	hFind = FindFirstFileU(mask, &FindFileData);
+	if (hFind == INVALID_HANDLE_VALUE)
+		return GetLastError();
+
+	dwResult = ERROR_FILE_NOT_FOUND;
+	do {
+		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+			if (strcmp(FindFileData.cFileName, ".") == 0 ||
+				strcmp(FindFileData.cFileName, "..") == 0 ||
+				(type & LIST_DIR_TYPE_RECURSIVE) == 0)
+				continue;
+			if (PathCombineU(path, dir, FindFileData.cFileName) == NULL)
+				break;
+			// Append a trailing backslash to directories
+			if (path[strlen(path) - 1] != '\\') {
+				path[strlen(path) + 1] = '\0';
+				path[strlen(path)] = '\\';
+			}
+			if (type & LIST_DIR_TYPE_DIRECTORY)
+				StrArrayAdd(arr, path, TRUE);
+			dwError = ListDirectoryContent(arr, path, type);
+			if (dwError != NO_ERROR && dwError != ERROR_FILE_NOT_FOUND) {
+				SetLastError(dwError);
+				break;
+			}
+		} else {
+			if (type & LIST_DIR_TYPE_FILE) {
+				if (PathCombineU(path, dir, FindFileData.cFileName) == NULL)
+					break;
+				StrArrayAdd(arr, path, TRUE);
+			}
+			dwResult = NO_ERROR;
+		}
+	} while (FindNextFileU(hFind, &FindFileData));
+
+	dwError = GetLastError();
+	FindClose(hFind);
+
+	if (dwError != ERROR_NO_MORE_FILES)
+		return dwError;
+	return dwResult;
+}
diff --git a/src/wue.c b/src/wue.c
index 6318aede..46db5bfd 100644
--- a/src/wue.c
+++ b/src/wue.c
@@ -51,6 +51,7 @@ extern uint32_t wim_nb_files, wim_proc_files, wim_extra_files;
 extern BOOL validate_md5sum;
 extern uint64_t md5sum_totalbytes;
 extern StrArray modified_files;
+extern const char* efi_archname[ARCH_MAX];
 
 /// <summary>
 /// Create an installation answer file containing the sections specified by the flags.
@@ -162,43 +163,56 @@ char* CreateUnattendXml(int arch, int flags)
 					free(tzstr);
 				}
 			}
-			if (flags & UNATTEND_SET_USER) {
-				for (i = 0; (i < ARRAYSIZE(unallowed_account_names)) && (stricmp(unattend_username, unallowed_account_names[i]) != 0); i++);
-				if (i < ARRAYSIZE(unallowed_account_names)) {
-					uprintf("WARNING: '%s' is not allowed as local account name - Option ignored", unattend_username);
-				} else if (unattend_username[0] != 0) {
-					uprintf("• Use '%s' for local account name", unattend_username);
-					// If we create a local account in unattend.xml, then we can get Windows 11
-					// 22H2 to skip MSA even if the network is connected during installation.
-					fprintf(fd, "      <UserAccounts>\n");
-					fprintf(fd, "        <LocalAccounts>\n");
-					fprintf(fd, "          <LocalAccount wcm:action=\"add\">\n");
-					fprintf(fd, "            <Name>%s</Name>\n", unattend_username);
-					fprintf(fd, "            <DisplayName>%s</DisplayName>\n", unattend_username);
-					fprintf(fd, "            <Group>Administrators;Power Users</Group>\n");
-					// Sets an empty password for the account (which, in Microsoft's convoluted ways,
-					// needs to be initialized to the Base64 encoded UTF-16 string "Password").
-					// The use of an empty password has both the advantage of not having to ask users
-					// to type in a password in Rufus (which they might be weary of) as well as allowing
-					// automated logon during setup.
-					fprintf(fd, "            <Password>\n");
-					fprintf(fd, "              <Value>UABhAHMAcwB3AG8AcgBkAA==</Value>\n");
-					fprintf(fd, "              <PlainText>false</PlainText>\n");
-					fprintf(fd, "            </Password>\n");
-					fprintf(fd, "          </LocalAccount>\n");
-					fprintf(fd, "        </LocalAccounts>\n");
-					fprintf(fd, "      </UserAccounts>\n");
-					// Since we set a blank password, we'll ask the user to change it at next logon.
+			if (flags & UNATTEND_SET_USER || flags & UNATTEND_USE_MS2023_BOOTLOADERS) {
+				if (flags & UNATTEND_SET_USER) {
+					for (i = 0; (i < ARRAYSIZE(unallowed_account_names)) && (stricmp(unattend_username, unallowed_account_names[i]) != 0); i++);
+					if (i < ARRAYSIZE(unallowed_account_names)) {
+						uprintf("WARNING: '%s' is not allowed as local account name - Option ignored", unattend_username);
+					} else if (unattend_username[0] != 0) {
+						uprintf("• Use '%s' for local account name", unattend_username);
+						// If we create a local account in unattend.xml, then we can get Windows 11
+						// 22H2 to skip MSA even if the network is connected during installation.
+						fprintf(fd, "      <UserAccounts>\n");
+						fprintf(fd, "        <LocalAccounts>\n");
+						fprintf(fd, "          <LocalAccount wcm:action=\"add\">\n");
+						fprintf(fd, "            <Name>%s</Name>\n", unattend_username);
+						fprintf(fd, "            <DisplayName>%s</DisplayName>\n", unattend_username);
+						fprintf(fd, "            <Group>Administrators;Power Users</Group>\n");
+						// Sets an empty password for the account (which, in Microsoft's convoluted ways,
+						// needs to be initialized to the Base64 encoded UTF-16 string "Password").
+						// The use of an empty password has both the advantage of not having to ask users
+						// to type in a password in Rufus (which they might be weary of) as well as allowing
+						// automated logon during setup.
+						fprintf(fd, "            <Password>\n");
+						fprintf(fd, "              <Value>UABhAHMAcwB3AG8AcgBkAA==</Value>\n");
+						fprintf(fd, "              <PlainText>false</PlainText>\n");
+						fprintf(fd, "            </Password>\n");
+						fprintf(fd, "          </LocalAccount>\n");
+						fprintf(fd, "        </LocalAccounts>\n");
+						fprintf(fd, "      </UserAccounts>\n");
+						// Since we set a blank password, we'll ask the user to change it at next logon.
+						fprintf(fd, "      <FirstLogonCommands>\n");
+						fprintf(fd, "        <SynchronousCommand wcm:action=\"add\">\n");
+						fprintf(fd, "          <Order>%d</Order>\n", order++);
+						fprintf(fd, "          <CommandLine>net user &quot;%s&quot; /logonpasswordchg:yes</CommandLine>\n", unattend_username);
+						fprintf(fd, "        </SynchronousCommand>\n");
+						// Some people report that using the `net user` command above might reset the password expiration to 90 days...
+						// To alleviate that, blanket set passwords on the target machine to never expire.
+						fprintf(fd, "        <SynchronousCommand wcm:action=\"add\">\n");
+						fprintf(fd, "          <Order>%d</Order>\n", order++);
+						fprintf(fd, "          <CommandLine>net accounts /maxpwage:unlimited</CommandLine>\n");
+						fprintf(fd, "        </SynchronousCommand>\n");
+						fprintf(fd, "      </FirstLogonCommands>\n");
+					}
+				}
+				if (flags & UNATTEND_USE_MS2023_BOOTLOADERS) {
+					uprintf("• Use 'Windows UEFI CA 2023' signed bootloaders");
+					// TODO: Validate that we can have multiple <FirstLogonCommands> sections
 					fprintf(fd, "      <FirstLogonCommands>\n");
 					fprintf(fd, "        <SynchronousCommand wcm:action=\"add\">\n");
 					fprintf(fd, "          <Order>%d</Order>\n", order++);
-					fprintf(fd, "          <CommandLine>net user &quot;%s&quot; /logonpasswordchg:yes</CommandLine>\n", unattend_username);
-					fprintf(fd, "        </SynchronousCommand>\n");
-					// Some people report that using the `net user` command above might reset the password expiration to 90 days...
-					// To alleviate that, blanket set passwords on the target machine to never expire.
-					fprintf(fd, "        <SynchronousCommand wcm:action=\"add\">\n");
-					fprintf(fd, "          <Order>%d</Order>\n", order++);
-					fprintf(fd, "          <CommandLine>net accounts /maxpwage:unlimited</CommandLine>\n");
+					// TODO: Validate the actual value on a machine where updates have been applied
+					fprintf(fd, "          <CommandLine>reg add HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Secureboot /v AvailableUpdates /t REG_DWORD /d 0x3c0 /f\n");
 					fprintf(fd, "        </SynchronousCommand>\n");
 					fprintf(fd, "      </FirstLogonCommands>\n");
 				}
@@ -845,7 +859,7 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
 					setup_arch = GetPeArch(buf);
 					free(buf);
 					if (setup_arch != IMAGE_FILE_MACHINE_AMD64 && setup_arch != IMAGE_FILE_MACHINE_ARM64) {
-						uprintf("WARNING: Unsupported arch 0x%x -- in-place upgrade wrapper can not be added");
+						uprintf("WARNING: Unsupported arch 0x%x -- in-place upgrade wrapper will not be added", setup_arch);
 					} else if (!MoveFileExU(setup_exe, setup_dll, 0)) {
 						uprintf("Could not rename '%s': %s", setup_exe, WindowsErrorString());
 					} else {
@@ -865,7 +879,8 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
 		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 0, PATCH_PROGRESS_TOTAL);
 		// We only need to mount boot.wim if we have windowsPE data to deal with. If
 		// not, we can just copy our unattend.xml in \sources\$OEM$\$$\Panther\.
-		if (flags & UNATTEND_WINPE_SETUP_MASK) {
+		// We also need to mount it if we use the 'Windows UEFI CA 2023' signed bootloaders.
+		if (flags & UNATTEND_WINPE_SETUP_MASK || flags & UNATTEND_USE_MS2023_BOOTLOADERS) {
 			if (validate_md5sum)
 				md5sum_totalbytes -= _filesizeU(boot_wim_path);
 			uprintf("Mounting '%s[%d]'...", boot_wim_path, wim_index);
@@ -969,6 +984,62 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
 		}
 		UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 103, PATCH_PROGRESS_TOTAL);
 	}
+
+	if (flags & UNATTEND_USE_MS2023_BOOTLOADERS) {
+		if_not_assert(mount_path != NULL)
+			goto out;
+		static_sprintf(path, "%s\\Windows\\Boot\\EFI_EX\\bootmgfw_EX.efi", mount_path);
+		if (!PathFileExistsU(path)) {
+			uprintf("Could not find 2023 signed UEFI bootloader - Ignoring option");
+		} else {
+			char path2[MAX_PATH], *rep;
+			StrArray files, dirs;
+			// Replace /EFI/Boot/boot###.efi
+			for (i = 1; i < ARRAYSIZE(efi_archname); i++) {
+				static_sprintf(path2, "%c:\\efi\\boot\\boot%s.efi", drive_letter, efi_archname[i]);
+				if (!PathFileExistsA(path2))
+					continue;
+				if (!CopyFileU(path, path2, FALSE))
+					uprintf("WARNING: Could not replace 'boot%s.efi': %s", efi_archname[i], WindowsErrorString());
+				break;
+			}
+			// Replace /bootmgr.efi
+			static_sprintf(path, "%s\\Windows\\Boot\\EFI_EX\\bootmgr_EX.efi", mount_path);
+			static_sprintf(path2, "%c:\\bootmgr.efi", drive_letter);
+			if (!CopyFileU(path, path2, FALSE))
+				uprintf("WARNING: Could not replace 'bootmgr.efi': %s", WindowsErrorString());
+			// Microsoft "secures" the Windows\Boot\ dir through their SUPER OBNOXIOUS AND
+			// WORTHLESS use of DACLs + read-only flags, so we first need to re-take control
+			// of all directories under there recursively.
+			StrArrayCreate(&dirs, 64);
+			StrArrayCreate(&files, 64);
+			static_sprintf(path, "%s\\Windows\\Boot\\", mount_path);
+			StrArrayAdd(&dirs, path, TRUE);
+			static_sprintf(path, "%s\\Windows\\Boot\\EFI_EX\\", mount_path);
+			StrArrayAdd(&dirs, path, TRUE);
+			ListDirectoryContent(&dirs, path, LIST_DIR_TYPE_DIRECTORY | LIST_DIR_TYPE_RECURSIVE);
+			for (i = 0; i < (int)dirs.Index; i++) {
+				rep = remove_substr(dirs.String[i], "_EX");
+				assert(rep != NULL);
+				TakeOwnership(rep);
+				safe_free(rep);
+			}
+			// Now that we should be able to write to the destination directories, copy the content.
+			ListDirectoryContent(&files, path, LIST_DIR_TYPE_FILE | LIST_DIR_TYPE_RECURSIVE);
+			for (i = 0; r && i < (int)files.Index; i++) {
+				rep = remove_substr(files.String[i], "_EX");
+				assert(rep != NULL);
+				TakeOwnership(rep);
+				if (!CopyFileU(files.String[i], rep, FALSE) && rep != NULL)
+					uprintf("WARNING: Could not replace '%s': %s", &rep[strlen(mount_path) + 1], WindowsErrorString());
+				safe_free(rep);
+			}
+			StrArrayDestroy(&dirs);
+			StrArrayDestroy(&files);
+			uprintf("Replaced EFI bootloader files with 'Windows UEFI CA 2023' signed versions");
+		}
+	}
+
 	r = TRUE;
 
 out: