Changing the boot entries of a Windows ISO using mkisofs to use cdboot_noprompt.efi instead of cdboot.efi
1
vote
2
answers
1962
views
When you boot a Windows 10 ISO, you will get this misleading prompt:
Why is it misleading? Because this message comes from the Windows ISO itself after you actually already booted from it.
This prompt is a feature that is supposed to prevent you from accidentally booting in your Windows image.
Now I have a very specific use-case in which this prompt makes it impossible for me to automatically create and install a UEFI-based Windows 10 VM.
So I've done some digging and on Windows you can create a Windows ISO without the prompt by specifying a

noprompt
image on the boot entry like so:
$setfsboot="C:\01_TEMP\ISO\etfsboot.com"
$sefisys ="C:\01_TEMP\ISO\efisys_noprompt.bin"
Oscdimg -bootdata:2#p0,eb$setfsboot#pEF,e,b$sefisys -u1
-udfver102 C:\winpe_amd64\media C:\winpe_amd64\winpeamd64.iso
**Quick explanation**
-bootdata:2#p0,eb$setfsboot#pEF,e,b$sefisys
- 2
means there are 2 boot entries
- #
separator
- p0,eb$setfsboot
is the default boot entry (for legacy BIOS boot)
- #
separator
- pEF,e,b$sefisys
is the fallback boot entry (for UEFI boot)
Documentation for OSCdimg
Now I'm trying to achieve the same thing on Linux using mkisofs, which is very tricky because just in order to make a UEFI-bootable Windows ISO, you need the upstream version of mkisofs
(see this post by mkey ) (Which can be obtained here .) The versions of mkisofs
that come with Linux distributions apparently lack some features and have ancient bugs in them that never got fixed.
I've tried removing efi/microsoft/boot/cdboot.efi
and then renaming efi/microsoft/boot/cdboot_noprompt.efi
to efi/microsoft/boot/cdboot.efi
in order to trick the ISO, but that didn't work unfortunately.
At the moment I use this code to extract a boot image from the ISO directly:
BOOT_LOAD_SEG="$(dumpet -i "${WIN10_IMG}" | grep "Media load segment: " | cut -d ':' -f2 | cut -d ' ' -f2)"
BOOT_LOAD_SIZE="$(dumpet -i "${WIN10_IMG}" | grep "Load Sectors: " | grep -o "[^:]*$" | cut -d ' ' -f2 | head -1)"
EFI_STARTING_SECTOR="$(dumpet -i "${WIN10_IMG}" | grep "Load LBA: " | grep -o "[^:]*$" | cut -d ' ' -f2 | tail -1)"
echo "EFI_STARTING_SECTOR: $EFI_STARTING_SECTOR"
sudo dd if="${WIN10_IMG}" of="${TMP}/efi.dmp" bs=2048 count=1 skip="${EFI_STARTING_SECTOR}"
EFI_BOOT_LOAD_SIZE="$(file "${TMP}/efi.dmp" | grep -oP 'sectors (\d+)' | cut -d ' ' -f2)"
echo "EFI_BOOT_LOAD_SIZE: ${EFI_BOOT_LOAD_SIZE}"
sudo dd if="${WIN10_IMG}" of="${ISO_FILES}/efi/win_efi_boot.img" bs=2048 count="${EFI_BOOT_LOAD_SIZE}" skip="${EFI_STARTING_SECTOR}"
In the last command above, the extracted image is placed in the folder containing the files extracted from the ISO.
Then using the -eltorito-boot "efi/win_efi_boot.img"
flag for mkisofs
, I tell it to use that for the boot entry.
I have written a script that automatically sets up everything you need in order to get to the point where I am right now.
If you take a look at STEP 5
in the script you can see my attempt to change the file names, but I think, I may have to change STEP 4
instead, but I just don't know how.
#!/usr/bin/env bash
#You might have to install a few dependencies for schily tools to compile.
#On Fedora this did the trick for me: sudo dnf install e2fsprogs-devel imake gcc-c++
############ STEP 1 download Windows 10 ISO from Microsoft ##############
WIN10_IMG="$(pwd)/windows10.iso"
WIN10_IMG_ARCH="x64"
if [ ! -f "$WIN10_IMG" ]; then # if the windows10.iso has not been downloaded yet
if [[ "$WIN10_IMG_ARCH" == "x86" ]] || [[ "$WIN10_IMG_ARCH" == "i386" ]] ; then
echo "Retrieving the x86 Windows 10 iso URL..."
WINDOWS_10_ISO_URL=$(curl -LsI -o /dev/null -w %{url_effective} "https://tb.rg-adguard.net/dl.php?go=7e583fea ") # This strange looking URL actually redirects to a legit software-download.microsoft.com URL
else
echo "Retrieving the x64 Windows 10 iso URL..."
WINDOWS_10_ISO_URL=$(curl -LsI -o /dev/null -w %{url_effective} "https://tb.rg-adguard.net/dl.php?go=3dd1ce66 ") # This strange looking URL actually redirects to a legit software-download.microsoft.com URL
fi
echo "Download URL: $WINDOWS_10_ISO_URL"
echo "Making sure the URL comes from a trusted Microsoft domain..."
if [[ $WINDOWS_10_ISO_URL == https://software-download.microsoft.com/* ]] ; then
echo "Downloading the Windows 10 installation iso..."
wget "$WINDOWS_10_ISO_URL" -O "$WIN10_IMG"
else
echo "URL validation failed. Please download the Windows 10 iso manually."
exit 1
fi
fi
#########################################################################
############## STEP 2 download and build the schily tools ###############
SCHILY_VERSION="2021-06-07"
SCHILY_ARCHIVE="schily-${SCHILY_VERSION}.tar.bz2"
SCHILY_DIR="./schily-tools"
if [ ! -f "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" ]; then # if the mkisofs of Schily Tools has not been built yet
sudo rm -rf "${SCHILY_DIR}"
wget "https://altushost-swe.dl.sourceforge.net/project/schilytools/${SCHILY_ARCHIVE} " -O "${SCHILY_ARCHIVE}"
tar -xf "${SCHILY_ARCHIVE}"
rm "${SCHILY_ARCHIVE}"
mv "schily-${SCHILY_VERSION}" "${SCHILY_DIR}"
cd "${SCHILY_DIR}"
./Gmake.linux
cd ..
if [ ! -f "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" ]; then
echo "Building Schily Tools failed"
exit 1
fi
fi
#########################################################################
################# STEP 3 Extract the files from the ISO #################
TMP="./tmp"
ISO_FILES="${TMP}/iso-files"
ISO_MP="${TMP}/iso-mountpoint"
if [ ! -f "${ISO_FILES}/setup.exe" ]; then # If the Windows ISO hasn't been extracted yet
sudo rm -rf "${TMP}"
mkdir -p "${ISO_FILES}"
mkdir -p "${ISO_MP}"
sudo mount -t udf "${WIN10_IMG}" "${ISO_MP}"
sudo cp -Rva ${ISO_MP}/* "${ISO_FILES}"
sudo umount "${ISO_MP}"
fi
#########################################################################
################## STEP 4 Extract the EFI boot image ####################
# Extract boot load segment address and size
BOOT_LOAD_SEG="$(dumpet -i "${WIN10_IMG}" | grep "Media load segment: " | cut -d ':' -f2 | cut -d ' ' -f2)"
BOOT_LOAD_SIZE="$(dumpet -i "${WIN10_IMG}" | grep "Load Sectors: " | grep -o "[^:]*$" | cut -d ' ' -f2 | head -1)"
EFI_STARTING_SECTOR="$(dumpet -i "${WIN10_IMG}" | grep "Load LBA: " | grep -o "[^:]*$" | cut -d ' ' -f2 | tail -1)"
echo "EFI_STARTING_SECTOR: $EFI_STARTING_SECTOR"
sudo dd if="${WIN10_IMG}" of="${TMP}/efi.dmp" bs=2048 count=1 skip="${EFI_STARTING_SECTOR}"
EFI_BOOT_LOAD_SIZE="$(file "${TMP}/efi.dmp" | grep -oP 'sectors (\d+)' | cut -d ' ' -f2)"
echo "EFI_BOOT_LOAD_SIZE: ${EFI_BOOT_LOAD_SIZE}"
sudo dd if="${WIN10_IMG}" of="${ISO_FILES}/efi/win_efi_boot.img" bs=2048 count="${EFI_BOOT_LOAD_SIZE}" skip="${EFI_STARTING_SECTOR}"
#########################################################################
######## STEP 5 Make changes to the files extracted from the ISO ########
# Make some arbitrary changes to the iso files
#sudo rm -rf "${ISO_FILES}/efi/microsoft/boot/cdboot.efi"
#sudo mv "${ISO_FILES}/efi/microsoft/boot/cdboot_noprompt.efi" "${ISO_FILES}/efi/microsoft/boot/cdboot.efi"
#sudo rm -rf "${ISO_FILES}/efi/microsoft/boot/efisys.bin"
#sudo mv "${ISO_FILES}/efi/microsoft/boot/efisys_noprompt.bin" "${ISO_FILES}/efi/microsoft/boot/efisys.bin"
#########################################################################
###### STEP 6 Build a new ISO using the extracted/modified files ########
sudo rm -f "${WIN10_IMG}.tmp.iso"
sudo "${SCHILY_DIR}/mkisofs/OBJ/x86_64-linux-gcc/mkisofs" \
-no-emul-boot \
-b boot/etfsboot.com \
-boot-load-seg "${BOOT_LOAD_SEG}" \
-boot-load-size "${BOOT_LOAD_SIZE}" \
-eltorito-alt-boot \
-no-emul-boot \
-eltorito-boot "efi/win_efi_boot.img" \
-boot-load-size 1 \
-iso-level 4 \
-UDF \
-o "${WIN10_IMG}.tmp.iso" \
"${ISO_FILES}"
#########################################################################
############ STEP 7 Remove the files exxtracted from the ISO ############
#sudo rm -f "${TMP}"
#########################################################################
Asked by Forivin
(1193 rep)
Jul 28, 2021, 12:40 AM
Last activity: Sep 13, 2023, 02:34 PM
Last activity: Sep 13, 2023, 02:34 PM