I am looking for tools for Ubuntu that can be used to EDIT ISO Images. Including ISO images that are bootable like Ubuntu and Windows ISOs. Not only edit but save the edited ISO and can still boot when burned on an USB Drive or CD/DVD.
I have used ISO Master to add files to ISOs before. It is suitable for what you require because it retains the state of whether or not the ISO is bootable. I have used it in the past to add other content (like music) to a live disk. Note, however, that after making changes to an ISO file, you can only "Save As", i.e. another ISO file will be created, so make sure you have enough disk space for both.
PowerISO just released a Linux version of their ISO editing software. Like ISO Master, it retains the state of whether or not the ISO is bootable. However, it allows you to save directly to the original file (by deleting it first), so there is no need to have enough disk space for both files. I also find its interface to be easier and more intuitive to use than ISO Master.
The common answer to this is to unpack the iso file, modify it, and pack it again. It looks like "ISO Master", as mentioned in dv3500ea's answer, is a good front-end to do that.
- you don't have enough space for that
- you only want to make a surgical modification instead of rewriting the whole thing
- you want to modify a storage device that contains an isofs filesystem (a.k.a. iso9660) without copying the whole device, or
- if you think this unpacking/repacking thing is just not hacky enough
Then this answer is for you!
In summary, we will replace an existing file in the isofs filesystem with our desired file. Our desired file must be smaller than the existing (target) file, and trailing whitespace (or garbage) must be acceptable. This actually requires only two commands, but be careful: a typo can destroy the target filesystem completely, or even overwrite the source file. Backups are your friend!
In my case, I wanted to store a script in a live boot so I don't have to retype it every time. The script is at
script.py and my target (a USB stick) is at
/dev/sdc. The size of the script is 202 bytes, so our first step is to find a file larger than 202 bytes, so we can overwrite it. After mounting it at
/mnt, I found a suitable file at
We can't just overwrite
info.txt on the mountpoint, it will complain that it's a read-only filesystem. We are root, though, so let's show 'em what that means! We need to figure out where
info.txt is on the filesystem. Find some string that is (probably) unique to
info.txt, for example
This is the official distribution CD of X., and search for it on the disk:
$ sudo strings -a -t d /dev/sdc | grep 'CD of X.' 2573588480 This is the official distribution CD of X. See INSTALL for how to [...]
Alternatively, this can also be done with grep, which is a lot faster, but then you need to specify it from the beginning:
$ sudo grep -oba 'This is ...' /dev/sdc.
Now that we know where it is, we just need to replace those bytes with our file:
$ sudo dd if=script.py of=/dev/sdc conv=notrunc bs=1 seek=2573588480 count=202
- copies bytes from the input file (
if) to the output file (
of), and it does not care that the output file is actually a device, because "everything is a file".
conv=notrunctells it not to truncate the output file, because we only want to overwrite a few bytes, not overwrite the file from a certain point onward.
bs=1sets the block size to 1. You usually want a block size of 4k or higher, but this both avoids having to do (inline) math and lets us specify the location exact to the byte.
seek=Nseeks to a certain point in the output file (note that
seek=Nis different from
skipskips bytes from the input file!). We set it, of course, to where the target text is.
count=Ncopy only this many bytes. I think this can be omitted because it will notice the end of the input file, but I left it in just to be sure.
And voila, the file is overwritten!
But wait, the target file was larger than our script, so on the USB stick, the file is now something like: "while do if run() blah; blah(); yright 2007 X Inc.". There is trailing garbage. Two ways to fix this: make our input file longer (add spaces), or add a comment symbol at the end. Note that many editors add a newline at the end, so you might want to set
N-1 bytes (if your file is now 203 bytes, and you notice that the last byte is a newline, set count to 202). You can check a file for newlines by using
xxd script.py | tail and checking if the last byte is
0a (or, in weird cases,
The process is identical for an
.iso file, just mentally replace
Note that when you check the target in your mountpoint to see whether it worked, you might need to use
strings again (this time searching for your script) since the file is probably still in read cache.