Customizing a Windows 7 install ISO

I’m told that if you want to pass additional files to Windows when it is installing, you have to put them on the actual install CD/ISO. However modifying ISOs is a palaver: they are write-once filesystems. The recommended way to modify them — using multisession support — doesn’t work for virtualization because the virtual CD drives don’t support it (nor do quite a few real CD drives).

You can unpack and repack an ISO file like this (and because we’re using libguestfs, root is not required):

$ mkdir /tmp/cd
$ cd /tmp/cd
$ guestfish --ro -a ../win.iso -m /dev/sda tar-out / - | tar xf -
$ mkisofs -o ../new-win.iso [...options...] .

If you add your own files into the /tmp/cd directory between the third and fourth steps then they will appear on the new ISO.

That’s the easy bit. The problem is that the new ISO will not be bootable, so you won’t be able to use it to install Windows from. Making it bootable involves an exploration of the command line options to “mkisofs” and a quick excursion into the ISO format.

It’s a good idea first to find out what format the existing Windows 7 ISO is in. Firstly I mount it up in guestfish to take a look around:

$ guestfish --ro -a ../en_windows_7_enterprise_x64_dvd_x15-70749.iso 

Welcome to guestfish, the libguestfs filesystem interactive shell for
editing virtual machine filesystems.

Type: 'help' for a list of commands
      'man' to read the manual
      'quit' to quit the shell

><fs> run
><fs> list-filesystems
/dev/vda: udf
><fs> mount-ro /dev/vda /
><fs> ll /
total 1164
dr-xr-xr-x  7 4294967295 4294967295    548 Jul 14  2009 .
drwxr-xr-x 20        500        500   4096 Nov  4 14:16 ..
-r-xr-xr-x  1 4294967295 4294967295    122 Jul 14  2009 autorun.inf
dr-xr-xr-x  4 4294967295 4294967295    568 Jul 14  2009 boot
-r-xr-xr-x  1 4294967295 4294967295 383562 Jul 14  2009 bootmgr
-r-xr-xr-x  1 4294967295 4294967295 667712 Jul 14  2009 bootmgr.efi
dr-xr-xr-x  3 4294967295 4294967295    100 Jul 14  2009 efi
-r-xr-xr-x  1 4294967295 4294967295 106760 Jul 14  2009 setup.exe
dr-xr-xr-x 10 4294967295 4294967295  10940 Jul 14  2009 sources
dr-xr-xr-x  5 4294967295 4294967295    200 Jul 14  2009 support
dr-xr-xr-x  3 4294967295 4294967295     92 Jul 14  2009 upgrade
><fs> exit

The format is UDF, the DVD replacement for ISO 9660. There is no obvious “cdboot.img” file which is what we will need in order to boot this thing.

Now look at the same disk with isoinfo:

$ isoinfo -d -i ../en_windows_7_enterprise_x64_dvd_x15-70749.iso
[lots of stuff]
Eltorito validation header:
    Hid 1
    Arch 0 (x86)
    ID 'Microsoft Corporation'
    Key 55 AA
    Eltorito defaultboot header:
        Bootid 88 (bootable)
        Boot media 0 (No Emulation Boot)
        Load segment 0
        Sys type 0
        Nsect 8
        Bootoff 2DE 734

What is interesting is that it’s an El Torito no-emulation bootable disk. The boot image required to boot it is 8 sectors long (“Nsect 8”) starting at sector number 734 (“Bootoff” in decimal).

CD sectors are 2048 bytes, so we can grab the boot image directly:

$ dd if=../en_windows_7_enterprise_x64_dvd_x15-70749.iso \
    of=boot.img bs=2048 count=8 skip=734

Now with all the information collected above, we can (with a great deal of experimentation) come up with a mkisofs command line that makes a bootable image:

$ mkisofs -o ../new-win.iso -b boot.img -no-emul-boot -c BOOT.CAT \
    -iso-level 2 -udf \
    -J -l -D -N -joliet-long -relaxed-filenames .

10 Comments

Filed under Uncategorized

10 responses to “Customizing a Windows 7 install ISO

  1. Alexander Williams

    This was was a really slick way to convert a bootable iso from ISO-13346 to ISO-9660. Thanks.

  2. Pingback: Windows 7 DVD Doesn’t Boot from USB DVD ROM Drive | Tech :: Stuff

  3. Chris

    Wow Thanks !

    4 years later it proved still usefull as I was looking for a way to (temporarily, for a specific need) re-install Win 7 Starter on my EeePC. I have the valid key of my PC, but not the recovery partition.

    The only modification I had to do was to change the bootoff value : 735 (instead of 734) on Win 7 SP1 iso.

    Thanks again.

  4. Gary Chen

    Great this was very helpful! Thanks so much!

  5. kr0llx

    Great.
    Saved my day.

    Thank you

  6. There is a tool to extract the boot image: geteltorito. And I think that while the offset is in logical blocks (2048 is correct) …. the image size is 8 _512 Byte_ sectors.

  7. TerraFLOPPS

    I not used UDF, bs=2048 count=2 skip=735, work for me

  8. Rüdiger Block

    Thank you very much! Brilliant post, very helpfull.

    The offset for windows 2008 r2 is 831 !

  9. This post was great! I was finally able to get a bootable windows ISO installed. After getting it to work and doing more testing I was able to determine that the boot image is already on the windows ISO as a file you can point to directly, For windows 10 (And I think earlier versions as well) it is located at /boot/etfsboot.com on the original ISO. So you don’t really need to use DD to create a boot image, I did however have to include the param: -boot-load-size 8 in the mkisofs command along with changing the path to the boot image to with the -b param.

    Also I did this on a mac and used the hdiutil program which provides a subset of options that mkisofs does, but has enough that I was able to get it to work. I used:

    hdiutil makehybrid -iso -udf -eltorito-boot ~/win10/boot/etfsboot.com -no-emul-boot -boot-load-size 8 -o ~/win10.iso ~/win10/

    where ~/win10/ contained all the files from the original ISO image, I then dropped in the files I needed into the ~/win10/ folder, ran the hdiutil program and I had a bootable modified windows ISO image.

  10. vitaliel

    Thanks for the post,

    I was able to build an win8.1 image with below commands:

    dd if=Win8.1_x32.iso of=boot.img bs=2048 count=8 skip=1460

    genisoimage -b boot.img -no-emul-boot -boot-load-size 8 -iso-level 2 -udf -joliet -D -N -relaxed-filenames -o w81_new.iso tmp-dvd/

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.