mirror of
https://github.com/pbatard/rufus.git
synced 2025-05-09 12:31:57 -04:00
[wue] add setup wrapper to add bypasses for in-place upgrades of Windows 11 24H2
* Per https://forums.mydigitallife.net/threads/win-11-boot-and-upgrade-fix-kit-v5-0-released.83724/ Windows 11 24H2 requires new registry bypasses to be applied to perform in-place upgrade on non officially supported platforms, and those need to be enacted before running setup.exe. * In order to streamline this, and because those registry bypasses require elevation, we rename setup.exe to setup.dll and add our own setup.exe wrapper to set the registry and then call the original setup.exe (through setup.dll). * See https://github.com/pbatard/rufus/issues/2568 * Also fix some MinGW build warnings. * Also fix the annoyance of TortoiseGit/Notepad++ altering the copyright symbol of rufus.rc.
This commit is contained in:
parent
98a42a235f
commit
c800448c62
12 changed files with 96 additions and 32 deletions
|
@ -32,6 +32,7 @@ s/^\([ \t]*\)*\(FILE\|PRODUCT\)VERSION\([ \t]*\)\([0-9]*\),\([0-9]*\),[0-9]*,\(.
|
|||
s/^\([ \t]*\)VALUE\([ \t]*\)"\(File\|Product\)Version",\([ \t]*\)"\(.*\)\..*"[ \t]*/\1VALUE\2"\3Version",\4"\5.@@BUILD@@"/
|
||||
s/^\(.*\)"Rufus \(.*\)\..*"\(.*\)/\1"Rufus \2.@@BUILD@@"\3/
|
||||
s/^\([ \t]*\)Version="\([0-9]*\)\.\([0-9]*\)\.[0-9]*\.\([0-9]*\)"\(.*\)/\1Version="\2.\3.@@BUILD@@.\4"\5/
|
||||
s/\xef\xbf\xbd/\xa9/
|
||||
_EOF
|
||||
|
||||
# First run sed to substitute our variable in the sed command file
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Rufus: The Reliable USB Formatting Utility - Windows 11 setup.exe wrapper
|
||||
Rufus: The Reliable USB Formatting Utility - Windows 11 Setup wrapper
|
||||
|
||||
# Description
|
||||
|
||||
|
@ -18,12 +18,26 @@ Our solution then is to have Rufus rename the original 'setup.exe' to 'setup.dll
|
|||
insert a small 'setup.exe' that'll perform elevation, add the registry key, and
|
||||
launch the original setup, which is exactly what this project does.
|
||||
|
||||
Now, obviously, the fact that we "inject" a setup executable may leave people
|
||||
uncomfortable about the possibility that we might use this as a malware vector,
|
||||
which is also why we make sure that the one we sign and embed in Rufus does get
|
||||
built using GitHub Actions and can be validated to not have been tampered through
|
||||
SHA-256 validation (Since we produce SHA-256 hashes during the build process per:
|
||||
Oh and it should be noted that, the issues you might see with Setup not restarting
|
||||
in the foreground after it updates, or not being able to launch at all for a while
|
||||
if you happen to cancel before starting the installation, have *NOTHING* to do with
|
||||
using this setup wrapper, but come from Microsoft themselves. You can validate that
|
||||
these issues exist even when running setup.exe without the wrapper...
|
||||
|
||||
# Security considerations
|
||||
|
||||
Obviously, the fact that we "inject" a setup executable may leave people uncomfortable
|
||||
about the possibility that we might use this as a malware vector, which is also why we
|
||||
make sure that the one we sign and embed in Rufus does get built using GitHub Actions
|
||||
and can be validated to not have been tampered through SHA-256 validation (Since we
|
||||
produce SHA-256 hashes during the build process per:
|
||||
https://github.com/pbatard/rufus/blob/master/.github/workflows/setup.yml).
|
||||
|
||||
Also note that, since these are the only platforms Windows 11 supports, we only
|
||||
build for x64 and ARM64.
|
||||
Per the https://github.com/pbatard/rufus/actions/runs/11195726475 GitHub Actions
|
||||
workflow run, the SHA-256 for the executables (before signature was applied) were:
|
||||
* 4e99f49b456781c92d2010a626706557df69334c6fc71ac129625f41fa311dd8 *./setup_x64.exe
|
||||
* a0d7dea2228415eb5afe34419a31eeda90f9b51338f47bc8a5ef591054277f4b *./setup_arm64.exe
|
||||
|
||||
You will also find the VirusTotal reports for the current signed executable at:
|
||||
* https://www.virustotal.com/gui/file/a74dbfc0e2a5b2e3fd4ad3f9fdaea0060c5d29a16151b9a570a9bd653db966a7/detection
|
||||
* https://www.virustotal.com/gui/file/629fdda27e200ec98703a7606ca4e2d0e44c578341779e4d5c447d45fc860c69/detection
|
||||
|
|
|
@ -104,7 +104,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
if (dwAttrib == INVALID_FILE_ATTRIBUTES || dwAttrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
MessageBoxA(NULL, "ERROR: 'setup.dll' was not found", "Windows setup error", MB_OK | MB_ICONWARNING);
|
||||
|
||||
// Apply the registry bypasses to enable Windows 11 24H2 in-place upgrade
|
||||
// Apply the registry bypasses to enable Windows 11 24H2 in-place upgrade. Credits to:
|
||||
// https://forums.mydigitallife.net/threads/win-11-boot-and-upgrade-fix-kit-v5-0-released.83724/
|
||||
RegDeleteNode(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\CompatMarkers");
|
||||
RegDeleteNode(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Shared");
|
||||
RegDeleteNode(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\TargetVersionUpgradeExperienceIndicators");
|
||||
|
|
BIN
res/setup/setup_arm64.exe
Normal file
BIN
res/setup/setup_arm64.exe
Normal file
Binary file not shown.
BIN
res/setup/setup_x64.exe
Normal file
BIN
res/setup/setup_x64.exe
Normal file
Binary file not shown.
|
@ -2091,7 +2091,7 @@ BOOL IsRevokedBySbat(uint8_t* buf, uint32_t len)
|
|||
|
||||
// Look for a .sbat section
|
||||
sbat = GetPeSection(buf, ".sbat", &sbat_len);
|
||||
if (sbat == NULL || sbat < buf || sbat >= buf + len)
|
||||
if (sbat == NULL || sbat < (char*)buf || sbat >= (char*)buf + len)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; sbat[i] != '\0'; ) {
|
||||
|
|
33
src/parser.c
33
src/parser.c
|
@ -1554,18 +1554,20 @@ sbat_entry_t* GetSbatEntries(char* sbatlevel)
|
|||
BOOL eol, eof;
|
||||
char* version_str;
|
||||
uint32_t i, num_entries;
|
||||
sbat_entry_t* sbat_entries;
|
||||
sbat_entry_t* _sbat_entries;
|
||||
|
||||
if (sbatlevel == NULL)
|
||||
return FALSE;
|
||||
return NULL;
|
||||
|
||||
num_entries = 0;
|
||||
for (i = 0; sbatlevel[i] != '\0'; i++)
|
||||
if (sbatlevel[i] == '\n')
|
||||
num_entries++;
|
||||
|
||||
sbat_entries = calloc(num_entries + 2, sizeof(sbat_entry_t));
|
||||
if (sbat_entries == NULL)
|
||||
if (num_entries == 0)
|
||||
return NULL;
|
||||
_sbat_entries = calloc(num_entries + 2, sizeof(sbat_entry_t));
|
||||
if (_sbat_entries == NULL)
|
||||
return NULL;
|
||||
|
||||
num_entries = 0;
|
||||
|
@ -1581,7 +1583,7 @@ sbat_entry_t* GetSbatEntries(char* sbatlevel)
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
sbat_entries[num_entries].product = &sbatlevel[i];
|
||||
_sbat_entries[num_entries].product = &sbatlevel[i];
|
||||
for (; sbatlevel[i] != ',' && sbatlevel[i] != '\0' && sbatlevel[i] != '\n'; i++);
|
||||
if (sbatlevel[i] == '\0' || sbatlevel[i] == '\n')
|
||||
break;
|
||||
|
@ -1595,22 +1597,35 @@ sbat_entry_t* GetSbatEntries(char* sbatlevel)
|
|||
i++;
|
||||
// Allow the provision of an hex version
|
||||
if (version_str[0] == '0' && version_str[1] == 'x')
|
||||
sbat_entries[num_entries].version = strtoul(version_str, NULL, 16);
|
||||
_sbat_entries[num_entries].version = strtoul(version_str, NULL, 16);
|
||||
else
|
||||
sbat_entries[num_entries].version = strtoul(version_str, NULL, 10);
|
||||
_sbat_entries[num_entries].version = strtoul(version_str, NULL, 10);
|
||||
if (!eol)
|
||||
for (; sbatlevel[i] != '\0' && sbatlevel[i] != '\n'; i++);
|
||||
if (sbat_entries[num_entries].version != 0)
|
||||
if (_sbat_entries[num_entries].version != 0)
|
||||
num_entries++;
|
||||
}
|
||||
|
||||
return sbat_entries;
|
||||
return _sbat_entries;
|
||||
}
|
||||
|
||||
/*
|
||||
* PE parsing functions
|
||||
*/
|
||||
|
||||
// Return the arch of a PE executable buffer
|
||||
uint16_t GetPeArch(uint8_t* buf)
|
||||
{
|
||||
IMAGE_DOS_HEADER* dos_header = (IMAGE_DOS_HEADER*)buf;
|
||||
IMAGE_NT_HEADERS* pe_header;
|
||||
|
||||
if (buf == NULL)
|
||||
return IMAGE_FILE_MACHINE_UNKNOWN;
|
||||
|
||||
pe_header = (IMAGE_NT_HEADERS*)&buf[dos_header->e_lfanew];
|
||||
return pe_header->FileHeader.Machine;
|
||||
}
|
||||
|
||||
// Return the address and (optionally) the length of a PE section from a PE buffer
|
||||
uint8_t* GetPeSection(uint8_t* buf, const char* name, uint32_t* len)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
#define IDR_LC_RUFUS_LOC 500
|
||||
#define IDR_XT_HOGGER 501
|
||||
#define IDR_UEFI_NTFS 502
|
||||
#define IDR_SETUP_X64 503
|
||||
#define IDR_SETUP_ARM64 504
|
||||
// The following should match the ArchType array values + 600
|
||||
#define IDR_MD5_BOOT 600
|
||||
#define IDR_MD5_BOOTIA32 601
|
||||
|
|
10
src/rufus.c
10
src/rufus.c
|
@ -1401,10 +1401,12 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
{
|
||||
int i, r, username_index = -1;
|
||||
FILE *fd;
|
||||
DWORD len;
|
||||
uint32_t len;
|
||||
uint8_t* buf = NULL;
|
||||
WPARAM ret = BOOTCHECK_CANCEL;
|
||||
BOOL in_files_dir = FALSE, esp_already_asked = FALSE;
|
||||
BOOL is_windows_to_go = ((image_options & IMOP_WINTOGO) && (ComboBox_GetCurItemData(hImageOption) == IMOP_WIN_TO_GO));
|
||||
const char* msg;
|
||||
const char* grub = "grub";
|
||||
const char* core_img = "core.img";
|
||||
const char* ldlinux = "ldlinux";
|
||||
|
@ -1603,10 +1605,6 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
|
||||
// Check UEFI bootloaders for revocation
|
||||
if (IS_EFI_BOOTABLE(img_report)) {
|
||||
uint8_t* buf = NULL;
|
||||
uint32_t len;
|
||||
const char* msg;
|
||||
|
||||
for (i = 0; i < ARRAYSIZE(img_report.efi_boot_path) && img_report.efi_boot_path[i][0] != 0; i++) {
|
||||
static const char* revocation_type[] = { "UEFI DBX", "Windows SSP", "Linux SBAT", "Windows SVN" };
|
||||
len = ReadISOFileToBuffer(image_path, img_report.efi_boot_path[i], &buf);
|
||||
|
@ -1720,7 +1718,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
if ((partition_type == PARTITION_STYLE_MBR) && HAS_SYSLINUX(img_report)) {
|
||||
if (SL_MAJOR(img_report.sl_version) < 5) {
|
||||
IGNORE_RETVAL(_chdirU(app_data_dir));
|
||||
for (i = 0; i<NB_OLD_C32; i++) {
|
||||
for (i = 0; i < NB_OLD_C32; i++) {
|
||||
if (img_report.has_old_c32[i]) {
|
||||
if (!in_files_dir) {
|
||||
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
||||
|
|
|
@ -831,6 +831,7 @@ extern HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAcce
|
|||
DWORD dwFlagsAndAttributes, LONGLONG fileSize);
|
||||
extern uint32_t ResolveDllAddress(dll_resolver_t* resolver);
|
||||
extern sbat_entry_t* GetSbatEntries(char* sbatlevel);
|
||||
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);
|
||||
|
|
14
src/rufus.rc
14
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.2199"
|
||||
CAPTION "Rufus 4.6.2200"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -305,6 +305,8 @@ BEGIN
|
|||
"IDR_FD_EGA18_CPX RCDATA ""../res/freedos/EGA18.CPX""\r\n"
|
||||
"IDR_XT_HOGGER RCDATA ""../res/hogger/hogger.exe""\r\n"
|
||||
"IDR_UEFI_NTFS RCDATA ""../res/uefi/uefi-ntfs.img""\r\n"
|
||||
"IDR_SETUP_X64 RCDATA ""../res/setup/setup_x64.exe""\r\n"
|
||||
"IDR_SETUP_ARM64 RCDATA ""../res/setup/setup_arm64.exe""\r\n"
|
||||
"IDR_MD5_BOOTIA32 RCDATA ""../res/md5/bootia32.efi""\r\n"
|
||||
"IDR_MD5_BOOTX64 RCDATA ""../res/md5/bootx64.efi""\r\n"
|
||||
"IDR_MD5_BOOTARM RCDATA ""../res/md5/bootarm.efi""\r\n"
|
||||
|
@ -397,8 +399,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,6,2199,0
|
||||
PRODUCTVERSION 4,6,2199,0
|
||||
FILEVERSION 4,6,2200,0
|
||||
PRODUCTVERSION 4,6,2200,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -416,13 +418,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "4.6.2199"
|
||||
VALUE "FileVersion", "4.6.2200"
|
||||
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.2199"
|
||||
VALUE "ProductVersion", "4.6.2200"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -490,6 +492,8 @@ IDR_FD_EGA17_CPX RCDATA "../res/freedos/EGA17.CPX"
|
|||
IDR_FD_EGA18_CPX RCDATA "../res/freedos/EGA18.CPX"
|
||||
IDR_XT_HOGGER RCDATA "../res/hogger/hogger.exe"
|
||||
IDR_UEFI_NTFS RCDATA "../res/uefi/uefi-ntfs.img"
|
||||
IDR_SETUP_X64 RCDATA "../res/setup/setup_x64.exe"
|
||||
IDR_SETUP_ARM64 RCDATA "../res/setup/setup_arm64.exe"
|
||||
IDR_MD5_BOOTIA32 RCDATA "../res/md5/bootia32.efi"
|
||||
IDR_MD5_BOOTX64 RCDATA "../res/md5/bootx64.efi"
|
||||
IDR_MD5_BOOTARM RCDATA "../res/md5/bootarm.efi"
|
||||
|
|
30
src/wue.c
30
src/wue.c
|
@ -790,10 +790,14 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
|
|||
char boot_wim_path[] = "?:\\sources\\boot.wim", key_path[64];
|
||||
char appraiserres_dll_src[] = "?:\\sources\\appraiserres.dll";
|
||||
char appraiserres_dll_dst[] = "?:\\sources\\appraiserres.bak";
|
||||
char setup_exe[] = "?:\\setup.exe";
|
||||
char setup_dll[] = "?:\\setup.dll";
|
||||
char *mount_path = NULL, path[MAX_PATH];
|
||||
uint8_t* buf = NULL;
|
||||
uint16_t setup_arch;
|
||||
HKEY hKey = NULL, hSubKey = NULL;
|
||||
LSTATUS status;
|
||||
DWORD dwDisp, dwVal = 1;
|
||||
DWORD dwDisp, dwVal = 1, dwSize;
|
||||
|
||||
assert(unattend_xml_path != NULL);
|
||||
uprintf("Applying Windows customization:");
|
||||
|
@ -832,6 +836,30 @@ BOOL ApplyWindowsCustomization(char drive_letter, int flags)
|
|||
StrArrayAdd(&modified_files, appraiserres_dll_src, TRUE);
|
||||
}
|
||||
}
|
||||
// Apply the 'setup.exe' wrapper for Windows 11 24H2 in-place upgrades
|
||||
if (img_report.win_version.build >= 26000) {
|
||||
setup_exe[0] = drive_letter;
|
||||
setup_dll[0] = drive_letter;
|
||||
dwSize = read_file(setup_exe, &buf);
|
||||
if (dwSize != 0) {
|
||||
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");
|
||||
} else if (!MoveFileExU(setup_exe, setup_dll, 0)) {
|
||||
uprintf("Could not rename '%s': %s", setup_exe, WindowsErrorString());
|
||||
} else {
|
||||
uprintf("Renamed '%s' → '%s'", setup_exe, setup_dll);
|
||||
uprintf("Created '%s' bypass wrapper (from embedded)", setup_exe);
|
||||
buf = GetResource(hMainInstance, MAKEINTRESOURCEA(setup_arch == IMAGE_FILE_MACHINE_AMD64 ? IDR_SETUP_X64 : IDR_SETUP_ARM64),
|
||||
_RT_RCDATA, "setup.exe", &dwSize, FALSE);
|
||||
if (buf == NULL)
|
||||
uprintf("Could not access embedded 'setup.exe'");
|
||||
else
|
||||
write_file(setup_exe, buf, dwSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateProgressWithInfoForce(OP_PATCH, MSG_325, 0, PATCH_PROGRESS_TOTAL);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue