diff --git a/.github/workflows/vs2022.yml b/.github/workflows/vs2022.yml index 963477fe..aefd1f61 100644 --- a/.github/workflows/vs2022.yml +++ b/.github/workflows/vs2022.yml @@ -50,6 +50,11 @@ jobs: with: msbuild-architecture: x64 + - name: Install UPX + uses: crazy-max/ghaction-upx@v3 + with: + install-only: true + - name: Set ALPHA id: set_alpha shell: bash @@ -76,6 +81,10 @@ jobs: move .\${{ matrix.TARGET_PLATFORM }}\Release\rufus.exe .\rufus_${{ matrix.TARGET_PLATFORM }}.exe move .\${{ matrix.TARGET_PLATFORM }}\Release\rufus.pdb .\rufus_${{ matrix.TARGET_PLATFORM }}.pdb + - name: Compress executables + if: ${{ matrix.TARGET_PLATFORM != 'arm64' }} + run: upx --lzma --best .\rufus_${{ matrix.TARGET_PLATFORM }}.exe + - name: Display SHA-256 run: sha256sum ./rufus_${{ matrix.TARGET_PLATFORM }}.exe diff --git a/.mingw/Makefile.am b/.mingw/Makefile.am index e8d55d27..a2170674 100644 --- a/.mingw/Makefile.am +++ b/.mingw/Makefile.am @@ -20,8 +20,7 @@ TARGET := $(word 1,$(subst -, ,$(TUPLE))) DEF_SUFFIX := $(if $(TARGET:x86_64=),.def,.def64) .PHONY: all -# Ideally, we would also have cfgmgr32-delaylib here, but it doesn't actually delay load... :( -all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib +all: crypt32-delaylib.lib dwmapi-delaylib.lib setupapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib %.def64: %.def $(AM_V_SED) "s/@.*//" $< >$@ diff --git a/.mingw/Makefile.in b/.mingw/Makefile.in index 8174663d..dd62b1df 100644 --- a/.mingw/Makefile.in +++ b/.mingw/Makefile.in @@ -368,8 +368,7 @@ uninstall-am: .PHONY: all -# Ideally, we would also have cfgmgr32-delaylib here, but it doesn't actually delay load... :( -all: dwmapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib +all: crypt32-delaylib.lib dwmapi-delaylib.lib setupapi-delaylib.lib version-delaylib.lib virtdisk-delaylib.lib wininet-delaylib.lib wintrust-delaylib.lib %.def64: %.def $(AM_V_SED) "s/@.*//" $< >$@ diff --git a/.mingw/crypt32.def b/.mingw/crypt32.def new file mode 100644 index 00000000..6d070db3 --- /dev/null +++ b/.mingw/crypt32.def @@ -0,0 +1,14 @@ +EXPORTS + CertFindCertificateInStore@24 + CertGetCertificateChain@32 + CertGetNameStringA@24 + CertCloseStore@8 + CertFreeCertificateContext@4 + CryptQueryObject@44 + CryptDecodeObjectEx@32 + CryptHashCertificate@28 + CryptMsgGetParam@20 + CryptMsgClose@4 + CryptMsgGetParam@20 + CryptMsgOpenToDecode@24 + CryptMsgUpdate@16 diff --git a/.mingw/setupapi.def b/.mingw/setupapi.def new file mode 100644 index 00000000..5707e1cc --- /dev/null +++ b/.mingw/setupapi.def @@ -0,0 +1,20 @@ +EXPORTS + CM_Locate_DevNodeA@12 + CM_Get_DevNode_Registry_PropertyA@24 + CM_Get_DevNode_Status@16 + CM_Get_Child@12 + CM_Get_Parent@12 + CM_Get_Sibling@12 + CM_Get_Device_IDA@16 + CM_Get_Device_ID_ListA@16 + CM_Get_Device_ID_List_SizeA@12 + SetupDiGetDeviceInstanceIdA@20 + SetupDiGetDeviceRegistryPropertyA@28 + SetupDiGetDeviceRegistryPropertyW@28 + SetupDiChangeState@8 + SetupDiGetClassDevsA@16 + SetupDiSetClassInstallParamsW@16 + SetupDiEnumDeviceInfo@12 + SetupDiEnumDeviceInterfaces@20 + SetupDiDestroyDeviceInfoList@4 + SetupDiGetDeviceInterfaceDetailA@24 diff --git a/.vs/rufus.vcxproj b/.vs/rufus.vcxproj index be8d8216..b558e0ea 100644 --- a/.vs/rufus.vcxproj +++ b/.vs/rufus.vcxproj @@ -168,7 +168,7 @@ true Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\arm - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -200,7 +200,7 @@ true Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64 - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) @@ -302,7 +302,7 @@ Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\arm /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) @@ -336,7 +336,7 @@ Windows C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\arm64 /BREPRO /DEPENDENTLOADFLAG:0x800 %(AdditionalOptions) - advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;ole32.dll;advapi32.dll;gdi32.dll;shell32.dll;comdlg32.dll;%(DelayLoadDLLs) + advapi32.dll;comctl32.dll;crypt32.dll;gdi32.dll;ole32.dll;dwmapi.dll;setupapi.dll;shell32.dll;shlwapi.dll;version.dll;virtdisk.dll;wininet.dll;wintrust.dll;%(DelayLoadDLLs) _UNICODE;UNICODE;%(PreprocessorDefinitions) diff --git a/configure b/configure index 1399f3a4..ce4d9bb1 100755 --- a/configure +++ b/configure @@ -4702,7 +4702,7 @@ fi printf "%s\n" "enabling Large File Support (ISO support)" >&6; } AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64 -D_OFF_T_ -D_off_t=off64_t -Doff_t=off64_t -Doff32_t=long" -# check for -Wno-pointer-sign compiler support (GCC >= 4) +# Check for -Wno-pointer-sign compiler support (GCC >= 4) saved_CFLAGS="${CFLAGS}" CFLAGS="$CFLAGS -Wno-pointer-sign" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4725,7 +4725,9 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="${saved_CFLAGS}" -AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags" +# NB: The DECLSPEC_IMPORT redefinition below is a temporary(?) workaround for MinGW32 delay-loading +# See https://github.com/pbatard/rufus/pull/2513 as well as https://sourceware.org/bugzilla/show_bug.cgi?id=14339 +AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -UDECLSPEC_IMPORT -DDECLSPEC_IMPORT=__attribute__\(\(visibility\(\\\"hidden\\\"\)\)\) -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags" diff --git a/configure.ac b/configure.ac index 2980290a..7225f028 100644 --- a/configure.ac +++ b/configure.ac @@ -57,14 +57,16 @@ fi AC_MSG_RESULT([enabling Large File Support (ISO support)]) AM_CFLAGS="$AM_CFLAGS -D_FILE_OFFSET_BITS=64 -D_OFF_T_ -D_off_t=off64_t -Doff_t=off64_t -Doff32_t=long" -# check for -Wno-pointer-sign compiler support (GCC >= 4) +# Check for -Wno-pointer-sign compiler support (GCC >= 4) saved_CFLAGS="${CFLAGS}" CFLAGS="$CFLAGS -Wno-pointer-sign" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], [nopointersign_cflags="-Wno-pointer-sign"], [nopointersign_cflags=""]) CFLAGS="${saved_CFLAGS}" -AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags" +# NB: The DECLSPEC_IMPORT redefinition below is a temporary(?) workaround for MinGW32 delay-loading +# See https://github.com/pbatard/rufus/pull/2513 as well as https://sourceware.org/bugzilla/show_bug.cgi?id=14339 +AM_CFLAGS="$AM_CFLAGS -DUNICODE -D_UNICODE -UNDEBUG -DCOBJMACROS -D__USE_MINGW_ANSI_STDIO=0 -UDECLSPEC_IMPORT -DDECLSPEC_IMPORT=__attribute__\(\(visibility\(\\\"hidden\\\"\)\)\) -std=gnu11 -Wshadow -Wall -Wformat-security -Wundef -Wunused -Wstrict-prototypes -Wno-restrict -Wno-array-bounds -Werror-implicit-function-declaration -Wbidi-chars=none $nopointersign_cflags" AC_SUBST([VISIBILITY_CFLAGS]) AC_SUBST([AM_CFLAGS]) diff --git a/loadcfg.py b/loadcfg.py new file mode 100644 index 00000000..4476c150 --- /dev/null +++ b/loadcfg.py @@ -0,0 +1,63 @@ +#!/bin/env python3 + +# PE Load Configuration section enabler for MinGW/gcc executables. +# The PE executable should have a IMAGE_LOAD_CONFIG_DIRECTORY## section +# in .rdata with a 16-byte IMAGE_DIRECTORY_ENTRY_MARKER marker. + +import os +import sys +import pefile + +IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10 +IMAGE_DIRECTORY_ENTRY_MARKER = b"_RUFUS_LOAD_CFG" + +if len(sys.argv) < 2: + raise RuntimeError("No executable path supplied") + +# Create a temp file as our source +pe_dst = sys.argv[1] +pe_src = sys.argv[1] + ".tmp" +os.replace(pe_dst, pe_src) + +# Open and parse PE +pe = pefile.PE(pe_src) + +# Find .rdata section +rdata_section = next( + (s for s in pe.sections if s.Name.rstrip(b'\x00') == b'.rdata'), + None +) +if not rdata_section: + raise RuntimeError(".rdata section not found") + +# Read the section's raw data to search for the target string +raw_data = rdata_section.get_data() + +# Look for the target data in the raw section data +offset = raw_data.find(IMAGE_DIRECTORY_ENTRY_MARKER) +if offset == -1: + raise RuntimeError("Load Config marker not found") + +# Move past our 16 bytes marker +offset += 0x10 +# Calculate the RVA and size of the Load Config section +load_config_rva = rdata_section.VirtualAddress + offset +print(f"RVA of Load Config: 0x{load_config_rva:X}") +load_config_size = pe.get_dword_at_rva(load_config_rva) +if (load_config_size < 0x20): + raise RuntimeError("Size of Load Config section is too small") +print(f"Size of Load Config: 0x{load_config_size:X}") + +# Update Load Config directory entry +pe.OPTIONAL_HEADER.DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress = load_config_rva +pe.OPTIONAL_HEADER.DATA_DIRECTORY[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size = load_config_size + +# Update the checksum +pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum() + +# Write the updated PE file and remove temp +pe.write(pe_dst) +os.remove(pe_src) + +# Can be validated with `DUMPBIN /LOADCONFIG <.exe>` or `objdump -x <.exe> | grep "Load Configuration"` +print(f"Successfully enabled Load Config section in '{pe_dst}'") diff --git a/src/Makefile.am b/src/Makefile.am index 65a5cf14..fbcef997 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,11 +1,9 @@ SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller syslinux/win libcdio/iso9660 libcdio/udf libcdio/driver wimlib ../res/loc # As far as I can tell, the following libraries are *not* vulnerable to side-loading, so we link using their regular version: -NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 -luuid -lntdll +NONVULNERABLE_LIBS = -lole32 -lgdi32 -lshlwapi -lcomctl32 -luuid -lntdll # The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement: # See https://github.com/pbatard/rufus/issues/2272 -# Oh, and don't bother trying to delay load cfgmgr32.dll, even with the DECLSPEC_IMPORT __attribute__((visibility("hidden"))) -# override. It just DOESN'T BLOODY WORK and you will waste HOURS on a wild goose chase!!! -VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib +VULNERABLE_LIBS = -lcrypt32-delaylib -ldwmapi-delaylib -lsetupapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib noinst_PROGRAMS = rufus diff --git a/src/Makefile.in b/src/Makefile.in index f219568c..5deb0e19 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -275,12 +275,10 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = ../.mingw bled ext2fs ms-sys syslinux/libfat syslinux/libinstaller syslinux/win libcdio/iso9660 libcdio/udf libcdio/driver wimlib ../res/loc # As far as I can tell, the following libraries are *not* vulnerable to side-loading, so we link using their regular version: -NONVULNERABLE_LIBS = -lsetupapi -lole32 -lgdi32 -lshlwapi -lcrypt32 -lcomctl32 -luuid -lntdll +NONVULNERABLE_LIBS = -lole32 -lgdi32 -lshlwapi -lcomctl32 -luuid -lntdll # The following libraries are vulnerable (or have an unknown vulnerability status), so we link using our delay-loaded replacement: # See https://github.com/pbatard/rufus/issues/2272 -# Oh, and don't bother trying to delay load cfgmgr32.dll, even with the DECLSPEC_IMPORT __attribute__((visibility("hidden"))) -# override. It just DOESN'T BLOODY WORK and you will waste HOURS on a wild goose chase!!! -VULNERABLE_LIBS = -ldwmapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib +VULNERABLE_LIBS = -lcrypt32-delaylib -ldwmapi-delaylib -lsetupapi-delaylib -lversion-delaylib -lvirtdisk-delaylib -lwininet-delaylib -lwintrust-delaylib AM_V_WINDRES_0 = @echo " RC $@";$(WINDRES) AM_V_WINDRES_1 = $(WINDRES) AM_V_WINDRES_ = $(AM_V_WINDRES_$(AM_DEFAULT_VERBOSITY)) diff --git a/src/dev.c b/src/dev.c index cbecdda2..7734f1b6 100644 --- a/src/dev.c +++ b/src/dev.c @@ -49,21 +49,6 @@ extern RUFUS_DRIVE rufus_drive[MAX_DRIVES]; extern BOOL enable_HDDs, enable_VHDs, use_fake_units, enable_vmdk, usb_debug; extern BOOL list_non_usb_removable_drives, its_a_me_mario; -/* - * CfgMgr32.dll interface. - * Note that, unlike what is the case with other DLLs, delay-loading of cfgmgr32 - * does *not* work with MinGW, so we have to go through direct hooking yet again... - */ -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, CHAR*, ULONG, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_ID_List_SizeA, (PULONG, PCSTR, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Device_ID_ListA, (PCSTR, PCHAR, ULONG, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Locate_DevNodeA, (PDEVINST, DEVINSTID_A, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Status, (PULONG, PULONG, DEVINST, ULONG)); -PF_TYPE_DECL(WINAPI, CONFIGRET, CM_Get_DevNode_Registry_PropertyA, (DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG)); - /* * Get the VID, PID and current device speed */ @@ -80,10 +65,7 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop if ((parent_path == NULL) || (device_id == NULL) || (props == NULL)) goto out; - PF_INIT_OR_OUT(CM_Locate_DevNodeA, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_DevNode_Registry_PropertyA, CfgMgr32); - - cr = pfCM_Locate_DevNodeA(&device_inst, device_id, 0); + cr = CM_Locate_DevNodeA(&device_inst, device_id, 0); if (cr != CR_SUCCESS) { uprintf("Could not get device instance handle for '%s': CR error %d", device_id, cr); goto out; @@ -91,7 +73,7 @@ static BOOL GetUSBProperties(char* parent_path, char* device_id, usb_device_prop props->port = 0; size = sizeof(props->port); - cr = pfCM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0); + cr = CM_Get_DevNode_Registry_PropertyA(device_inst, CM_DRP_ADDRESS, NULL, (PVOID)&props->port, &size, 0); if (cr != CR_SUCCESS) { uprintf("Could not get port for '%s': CR error %d", device_id, cr); goto out; @@ -214,8 +196,6 @@ int CycleDevice(int index) if ((index < 0) || (safe_strlen(rufus_drive[index].id) < 8)) return ERROR_INVALID_PARAMETER; - PF_INIT_OR_OUT(CM_Get_DevNode_Status, CfgMgr32); - // Need DIGCF_ALLCLASSES else disabled devices won't be listed. dev_info = SetupDiGetClassDevsA(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (dev_info == INVALID_HANDLE_VALUE) { @@ -238,7 +218,7 @@ int CycleDevice(int index) found = TRUE; // Detect if the device is already disabled - if (pfCM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) + if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED); // Disable the device @@ -287,7 +267,7 @@ int CycleDevice(int index) // successful, but leave the device in an actual disabled state... So we can end up // with zombie devices, that are effectively disabled, but that Windows still sees // as enabled... So we need to detect this. - if (pfCM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) { + if (CM_Get_DevNode_Status(&dev_status, &problem_code, dev_info_data.DevInst, 0) == CR_SUCCESS) { disabled = (dev_status & DN_HAS_PROBLEM) && (problem_code == CM_PROB_DISABLED); if (disabled) ret = ERROR_DEVICE_REINITIALIZATION_NEEDED; @@ -298,7 +278,6 @@ int CycleDevice(int index) SetupDiDestroyDeviceInfoList(dev_info); if (!found) uprintf("Could not find a device to cycle!"); -out: return ret; } @@ -518,14 +497,6 @@ BOOL GetDevices(DWORD devnum) uint64_t drive_size = 0; usb_device_props props; - PF_INIT_OR_OUT(CM_Get_Child, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_Parent, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_Sibling, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_Device_IDA, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_Device_ID_ListA, CfgMgr32); - PF_INIT_OR_OUT(CM_Get_Device_ID_List_SizeA, CfgMgr32); - PF_INIT_OR_OUT(CM_Locate_DevNodeA, CfgMgr32); - IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); ClearDrives(); StrArrayCreate(&dev_if_path, 128); @@ -555,19 +526,19 @@ BOOL GetDevices(DWORD devnum) if (SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { // Find the Device IDs for all the children of this hub - if (pfCM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) { + if (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) { device_id[0] = 0; s = StrArrayAdd(&dev_if_path, devint_detail_data->DevicePath, TRUE); uuprintf(" Hub[%d] = '%s'", s, devint_detail_data->DevicePath); - if ((s>= 0) && (pfCM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) { + if ((s>= 0) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) { ToUpper(device_id); if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; } uuprintf(" Found ID[%03d]: %s", k, device_id); - while (pfCM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { + while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { device_id[0] = 0; - if (pfCM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) { + if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) { ToUpper(device_id); if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; @@ -595,7 +566,7 @@ BOOL GetDevices(DWORD devnum) // Also compute the uasp_start index if (strcmp(usbstor_name[s], "UASPSTOR") == 0) uasp_start = s; - if (pfCM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], ulFlags) != CR_SUCCESS) + if (CM_Get_Device_ID_List_SizeA(&list_size[s], usbstor_name[s], ulFlags) != CR_SUCCESS) list_size[s] = 0; if (list_size[s] != 0) full_list_size += list_size[s]-1; // remove extra NUL terminator @@ -630,7 +601,7 @@ BOOL GetDevices(DWORD devnum) for (s = 0, i = 0; s < ARRAYSIZE(usbstor_name); s++) { list_start[s] = i; if (list_size[s] > 1) { - if (pfCM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) + if (CM_Get_Device_ID_ListA(usbstor_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) continue; if (usb_debug) { uprintf("Processing IDs belonging to '%s':", usbstor_name[s]); @@ -737,17 +708,17 @@ BOOL GetDevices(DWORD devnum) // a lookup table, but there shouldn't be that many USB storage devices connected... // NB: Each of these Device IDs should have a child, from which we get the Device Instance match. for (device_id = devid_list; *device_id != 0; device_id += strlen(device_id) + 1) { - if (pfCM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) { + if (CM_Locate_DevNodeA(&parent_inst, device_id, 0) != CR_SUCCESS) { uuprintf("Could not locate device node for '%s'", device_id); continue; } - if (pfCM_Get_Child(&device_inst, parent_inst, 0) != CR_SUCCESS) { + if (CM_Get_Child(&device_inst, parent_inst, 0) != CR_SUCCESS) { uuprintf("Could not get children of '%s'", device_id); continue; } if (device_inst != dev_info_data.DevInst) { // Try the siblings - while (pfCM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { + while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { if (device_inst == dev_info_data.DevInst) { uuprintf("NOTE: Matched instance from sibling for '%s'", device_id); break; @@ -788,8 +759,8 @@ BOOL GetDevices(DWORD devnum) // for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods) // so try to see if we can match the grandparent. if ( ((uintptr_t)htab_devid.table[j].data == 0) - && (pfCM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) - && (pfCM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { + && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) + && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { device_id = str; method_str = "[GP]"; ToUpper(device_id); diff --git a/src/net.c b/src/net.c index 76aadcda..a47f076e 100644 --- a/src/net.c +++ b/src/net.c @@ -24,12 +24,6 @@ #endif #include -// Temporary workaround for MinGW32 delay-loading -// See https://github.com/pbatard/rufus/pull/2513 -#if defined(__MINGW32__) -#undef DECLSPEC_IMPORT -#define DECLSPEC_IMPORT __attribute__((visibility("hidden"))) -#endif #include #include #include diff --git a/src/rufus.c b/src/rufus.c index e5f0df56..5b0b7761 100755 --- a/src/rufus.c +++ b/src/rufus.c @@ -22,14 +22,6 @@ #include #endif -// Temporary workaround for MinGW32 delay-loading -// See https://github.com/pbatard/rufus/pull/2513 as well as -// https://sourceware.org/bugzilla/show_bug.cgi?id=14339 -#if defined(__MINGW32__) -#undef DECLSPEC_IMPORT -#define DECLSPEC_IMPORT __attribute__((visibility("hidden"))) -#endif - #include #include #include @@ -4219,3 +4211,30 @@ out: return 0; } + +/* + * The following adds a Load Configuration section in .rdata for MinGW, that can then be referenced + * by a PE post processing script to emulate the /DEPENDENTLOADFLAG:0x800 behaviour of MSVC. + * See https://github.com/pbatard/rufus/blob/master/loadcfg.py for such a script. + * Note however that, per https://github.com/pbatard/rufus/issues/2701#issuecomment-2874788564 + * /DEPENDENTLOADFLAG is far from being the ultimate solution to stop DLL side-loading vulnerabilities... + */ +#if defined(__MINGW32__) +// MinGW produces a warning since we don't use this section in the code => silence it. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" +// Add a 16-byte marker for scripts to easily locate this section. +static const char _load_config_marker[16] __attribute__((aligned(16))) __attribute__((section(".rdata"))) = "_RUFUS_LOAD_CFG"; +#if defined(_M_AMD64) +static const IMAGE_LOAD_CONFIG_DIRECTORY64 _load_config __attribute__((aligned(16))) __attribute__((section(".rdata"))) = { + .Size = sizeof(IMAGE_LOAD_CONFIG_DIRECTORY64), + .DependentLoadFlags = LOAD_LIBRARY_SEARCH_SYSTEM32 +}; +#else +static const IMAGE_LOAD_CONFIG_DIRECTORY32 _load_config __attribute__((aligned(16))) __attribute__((section(".rdata"))) = { + .Size = sizeof(IMAGE_LOAD_CONFIG_DIRECTORY32), + .DependentLoadFlags = LOAD_LIBRARY_SEARCH_SYSTEM32 +}; +#endif +#pragma GCC diagnostic pop +#endif diff --git a/src/rufus.h b/src/rufus.h index 174e2a64..ad884e23 100644 --- a/src/rufus.h +++ b/src/rufus.h @@ -58,14 +58,13 @@ #endif #define COMPANY_NAME "Akeo Consulting" #define STR_NO_LABEL "NO_LABEL" -// Yes, there exist characters between these seemingly empty quotes! -#define LEFT_TO_RIGHT_MARK "‎" -#define RIGHT_TO_LEFT_MARK "‏" -#define LEFT_TO_RIGHT_EMBEDDING "‪" -#define RIGHT_TO_LEFT_EMBEDDING "‫" -#define POP_DIRECTIONAL_FORMATTING "‬" -#define LEFT_TO_RIGHT_OVERRIDE "‭" -#define RIGHT_TO_LEFT_OVERRIDE "‮" +#define LEFT_TO_RIGHT_MARK "\u200e" +#define RIGHT_TO_LEFT_MARK "\u200f" +#define LEFT_TO_RIGHT_EMBEDDING "\u202a" +#define RIGHT_TO_LEFT_EMBEDDING "\u202b" +#define POP_DIRECTIONAL_FORMATTING "\u202c" +#define LEFT_TO_RIGHT_OVERRIDE "\u202d" +#define RIGHT_TO_LEFT_OVERRIDE "\u202e" #define DRIVE_ACCESS_TIMEOUT 15000 // How long we should retry drive access (in ms) #define DRIVE_ACCESS_RETRIES 150 // How many times we should retry #define DRIVE_INDEX_MIN 0x00000080 diff --git a/src/rufus.rc b/src/rufus.rc index d4f1775a..0c24d45b 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.8.2243" +CAPTION "Rufus 4.8.2244" FONT 9, "Segoe UI Symbol", 400, 0, 0x0 BEGIN LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP @@ -407,8 +407,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 4,8,2243,0 - PRODUCTVERSION 4,8,2243,0 + FILEVERSION 4,8,2244,0 + PRODUCTVERSION 4,8,2244,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -426,13 +426,13 @@ BEGIN VALUE "Comments", "https://rufus.ie" VALUE "CompanyName", "Akeo Consulting" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "4.8.2243" + VALUE "FileVersion", "4.8.2244" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", " 2011-2025 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html" VALUE "OriginalFilename", "rufus-4.8.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "4.8.2243" + VALUE "ProductVersion", "4.8.2244" END END BLOCK "VarFileInfo" diff --git a/src/vhd.h b/src/vhd.h index fccf4ca7..a0ce4182 100644 --- a/src/vhd.h +++ b/src/vhd.h @@ -19,12 +19,6 @@ #include #include -// Temporary workaround for MinGW32 delay-loading -// See https://github.com/pbatard/rufus/pull/2513 -#if defined(__MINGW32__) -#undef DECLSPEC_IMPORT -#define DECLSPEC_IMPORT __attribute__((visibility("hidden"))) -#endif #include #pragma once diff --git a/src/xml.c b/src/xml.c index 91c0c54c..4791788b 100644 --- a/src/xml.c +++ b/src/xml.c @@ -240,8 +240,8 @@ char *ezxml_decode(char *s, char **ent, char t) l = (d = (long)(s - r)) + c + (long)(e ? strlen(e) : 0); // new length r = (r == m) ? strcpy(malloc(l), r) : _realloc(r, l); e = strchr((s = r + d), ';'); // fix up pointers - if (!e) return r; } + if (!e) return r; memmove(s + c, e + 1, strlen(e)); // shift rest of string strncpy_s(s, c, ent[b], _TRUNCATE); // copy in replacement text