Mounting HFS+ Hybrid Disks on Linux

http://www.64Lines.com »» Mounting HFS+ Hybrid Disks on Linux «

Overview

Recently I have faced a situation where I had an ISO file that contained hybrid data, a typical disc generated in OSX. Its format was ISO9660, but it also had an HFS+ partition which would be visible when the disk is inserted into a compatible system such as a Mac running OSX. My challenge was: I had to edit the iso, but I did not have access to a running instance of OSX.

My idea was: if I can mount this ISO as a read-write device I will be able to edit it in place, then burn a copy back. However there was a problem: this disk would only be mounted as a regular ISO9660 file and was never showing the hidden partition. After spending a fair amount of time on Google I could not find any solution to this problem, but I did come up with an idea: if the partition start can be isolated on the disk, I can likely mount it using a few special tools. Therefore the challenge became finding the HFS+ partition within this file...

Finding an HSF+ Partition

How do you find an HFS+ partition? Well according to docs at http://developer.apple.com/technotes/tn/tn1150.html#VolumeHeader an HFS+ partition starts with 1024 reserved bytes for boot code followed by the VolumeHeader structure. The first 4 bytes of the VolumeHeader structure are a signature and a version number. Essentially "H+" followed by version 4 (or HX followed by 5 for HFSX). Therefore we are looking for the following hexadecimal sequence within the file: "48 2b 00 04" (or "48 58 00 05" for HFSX).

Therefore the task is now to find this sequence in the file, and remember that we are dealing with typical storage blocks here so the sequence will likely be at a block boundary and an address that ends with "0x00". The easiest way to do this in a typical Linux environment is combining hexdump with grep. Here is the shell command I used to find the correct sequence:

hexdump -C image.iso | grep "48 2b 00 04"

In my case I got the following line displayed on the screen:

0001d400  48 2b 00 04 00 00 01 00  48 2b 4c 78 00 00 00 00  |H+......H+Lx....|
Notice the first number is "0001d400", it ends in "00" and it is our VolumeHeader block. However the real start of the partition is 1024 before that address, therefore 0x0001d400 - 1024 gives us 0x0001d000, and when converted to decimal notation: 118784 (for quick conversions try "0x00FF to decimal" in Google). This is our magic number, the partition starts there and now we need to mount it!

Mounting the Partition

Typically mounting an ISO within linux looks like "mount -o loop image.iso /mnt/cdrom/", the "-o loop" specifies to create a virtual block device out of the image file and then mount it. This special command allows the iso to be accessed as if it was a regular disk, however this is not enough for our needs - we need to access the disk starting at position 118784. That's where the losetup tool comes in handy, this tool allows you to setup the loop device manually with extra parameters. In this case lets setup the ISO as a block device starting with the offset 118784:

losetup -o 118784 /dev/loop0 image.iso

Now that the loop device is setup, all we need to do is mount it:

mount -t hfsplus /dev/loop0 /mnt/cdrom/

And that's it, if you have done everything correctly and subtracted the 1024 bytes form the VolumeHeader position - your file system should be mounted at the mount point and editable as needed.

Some Final Comments

Note that this method most likely invalidates the MD5 hash of the whole ISO, therefore a standard tool might complain about the modified file before burning it - therefore do it at your own risk. Also significant modifications to the ISO would likely displace other portions of the disk that are not HSF+, I assume there is some padding in there to accept a few changes, deleting data should certainly work, and perhaps minor modifications would be fine as well. My task was simply overwriting one file with another existing file on the disk.

I have also tested this method on actual CDs without making an iso image. If you have a hybrid disk and want to mount the HFS+ filesystem on it, just substitute the occurrences of image.iso with the cdrom device. The easiest way to find the correct device is to let your system auto mount it (mounting the non-HFS partition) and then running “mount” in your terminal, you will see which “/dev/*” device is used for the mount point.


 ________________________________________ 
/ 'Cow says: Thank you for visiting. You \
| are browsing: Mounting HFS+ Hybrid     |
| Disks on Linux. You have been to 1     |
\ pages on this site today.'             /
 ---------------------------------------- 
       \   ,__,
        \  (oo)____
           (__)    )\
              ||--|| *

Check out the other 64Lines.com articles, tutorials, and tools

All article content is copyright of Michael Petrov, 2006©.
The source code presented in the articles is distributed as freeware, please feel free to use it in your own projects - both commercial and non commercial.
Valid HTML 4.01 Transitional Valid CSS!