Overview
This will demonstrate how to mount a VirtualBox VDI hard disk image natively in Mac OS X. Why? It’s a convenient way to add and remove files in the VDI image. With some creativity you could also create a backup of the files inside the VDI image, rather than just the image itself. To do this, I will use the Mac OS X utility hdiutil. No additional software is required.
First, a standard disclaimer! By following this procedure your data is at risk! You accept ALL risk by following this procedure. You are not forced to do this. When in doubt, make a backup of the original VDI image first. If you are not comfortable using the Mac OS X command line, do not attempt!
Second, you will most likely only want to use this with statically sized VDI files, and not the dynamically sized ones – especially if you are going to write to the image!
Third, make sure the virtual host the VDI image is attached to, is NOT running!
How To
OS X’s hdituil can mount the images natively. However, the VDI image header includes information that hdiutil doesnt want. You will need to find the start location of the data. From the OS X command line, change to the directory where the VDI is stored. Quick and dirty, you can use hexdump. Or you can find the header size by examining the 4 bytes at 0x158 (344), in this case the bytes are in reverse order (00 00 20 00).
Visual hex dump:
>$ hexdump -C ./DOSTools.vdi | more 00000000 3c 3c 3c 20 4f 72 61 63 6c 65 20 56 4d 20 56 69 |<<< Oracle VM Vi| 00000010 72 74 75 61 6c 42 6f 78 20 44 69 73 6b 20 49 6d |rtualBox Disk Im| 00000020 61 67 65 20 3e 3e 3e 0a 00 00 00 00 00 00 00 00 |age >>>.........| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 7f 10 da be 01 00 01 00 90 01 00 00 01 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000150 00 00 00 00 00 00 10 00 00 00 20 00 00 00 00 00 |.......... .....| 00000160 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 |................| 00000170 00 00 40 06 00 00 00 00 00 00 10 00 00 00 00 00 |..@.............| 00000180 64 00 00 00 16 00 00 00 66 b0 36 e4 f3 25 5f 44 |d.......f.6..%_D| 00000190 b8 c3 c4 b9 0c 66 c4 46 38 87 9b c2 5e 40 2a 49 |.....f.F8...^@*I| 000001a0 82 1f 79 be 28 b4 13 47 00 00 00 00 00 00 00 00 |..y.(..G........| 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001c0 00 00 00 00 00 00 00 00 cb 00 00 00 10 00 00 00 |................| 000001d0 3f 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 |?...............| 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00100000 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 |................| 00100010 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 |................| 00100020 08 00 00 00 09 00 00 00 0a 00 00 00 0b 00 00 00 |................| 00100030 0c 00 00 00 0d 00 00 00 0e 00 00 00 0f 00 00 00 |................| 00100040 10 00 00 00 11 00 00 00 12 00 00 00 13 00 00 00 |................| 00100050 14 00 00 00 15 00 00 00 ff ff ff ff ff ff ff ff |................| 00100060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| * 00100190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00200000 fa 33 c0 8e d0 bc 00 7c 8b f4 50 07 50 1f fb fc |.3.....|..P.P...| 00200010 bf 00 06 b9 00 01 f2 a5 ea 1d 06 00 00 be be 07 |................| 00200020 b3 04 80 3c 80 74 0e 80 3c 00 75 1c 83 c6 10 fe |...<.t..<.u.....| 00200030 cb 75 ef cd 18 8b 14 8b 4c 02 8b ee 83 c6 10 fe |.u......L.......| 00200040 cb 74 1a 80 3c 00 74 f4 be 8b 06 ac 3c 00 74 0b |.t..<.t.....<.t.| 00200050 56 bb 07 00 b4 0e cd 10 5e eb f0 eb fe bf 05 00 |V.......^.......| 00200060 bb 00 7c b8 01 02 57 cd 13 5f 73 0c 33 c0 cd 13 |..|...W.._s.3...| 00200070 4f 75 ed be a3 06 eb d3 be c2 06 bf fe 7d 81 3d |Ou...........}.=| 00200080 55 aa 75 c7 8b f5 ea 00 7c 00 00 49 6e 76 61 6c |U.u.....|..Inval| 00200090 69 64 20 70 61 72 74 69 74 69 6f 6e 20 74 61 62 |id partition tab| 002000a0 6c 65 00 45 72 72 6f 72 20 6c 6f 61 64 69 6e 67 |le.Error loading| 002000b0 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 65 | operating syste| 002000c0 6d 00 4d 69 73 73 69 6e 67 20 6f 70 65 72 61 74 |m.Missing operat| 002000d0 69 6e 67 20 73 79 73 74 65 6d 00 00 00 00 00 00 |ing system......| 002000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
Data bytes show that data starts at 0x200000, and is confirmed visually.
hdiutil attach requires start offset definition in sectors. Divide byte offset by sector size to get sector number. 0x200000 (2097152) / 0x200 (512) = 0x1000 (4096).
Create a symlink to the VDI image since hdiutil doesn’t like the vdi extension:
>$ ln -s DOSTools.vdi DOSTools.img
Verify the symlink was created correctly (not required):
>$ ls -al
total 65592
drwx------ 8 user staff 272 Feb 1 20:57 .
drwxr-xr-x 5 user staff 170 Jan 31 22:46 ..
-rw------- 1 user staff 10319 Feb 1 00:06 DOS 6.22.vbox
-rw------- 1 user staff 10319 Feb 1 00:06 DOS 6.22.vbox-prev
-rwx------ 1 user staff 8388608 Feb 1 00:06 DOS 6.22.vdi
lrwxr-xr-x 1 user staff 12 Feb 1 20:57 DOSTools.img -> DOSTools.vdi
-rwx------ 1 user staff 25165824 Feb 1 00:06 DOSTools.vdi
drwx------ 6 user staff 204 Jan 31 23:53 Logs
Mount the image using Mac OS X hdiutil command using the hdid agent, and the data start offset calculated previously (0x1000). Remove the -readonly parameter if you want to write to the image:
>$ hdiutil attach -agent hdid -section 0x1000 -readonly DOSTools.img /dev/disk2 FDisk_partition_scheme /dev/disk2s1 DOS_FAT_16 /Volumes/TOOLS
Now access it as needed. You can see the two directories in my image (UTILS and APPS):
>$ ls -al /Volumes/TOOLS total 40 drwxrwxrwx@ 1 user staff 16384 Jan 31 13:17 . drwxrwxrwt@ 4 root admin 136 Feb 1 20:58 .. drwxrwxrwx 1 user staff 2048 Jan 31 13:28 UTILS drwxrwxrwx 1 user staff 2048 Jan 31 13:22 APPS
When done, unmount the image:
>$ hdiutil detach /dev/disk2 "disk2" unmounted. "disk2" ejected.
Hi. I’m getting ‘hdiutil: attach failed – no mountable file systems’.
If I add a few extra flags to hidutil …
$ hdiutil attach -agent hdid -section 0x1000 -readonly PHPMaker_Win7.img -nomount
/dev/disk2 FDisk_partition_scheme
/dev/disk2s1 Windows_NTFS
/dev/disk2s2 Windows_NTFS
If I add -debug -verbose …
2017-09-12 10:11:43.329 diskimages-helper[18225:7663085] _mountDevEntries: (DiskArb version)
2017-09-12 10:11:43.329 diskimages-helper[18225:7663085] _mountDevEntries: disk2 {
DAAppearanceTime = “526900172.09876”;
DABusName = “/”;
DABusPath = “IODeviceTree:/”;
DADeviceModel = “Disk Image”;
DADevicePath = “IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@3/IODiskImageBlockStorageDeviceOutKernel”;
DADeviceProtocol = “Virtual Interface”;
DADeviceRevision = “10.12v444.50.16”;
DADeviceUnit = 3;
DADeviceVendor = Apple;
DAMediaBSDMajor = 1;
DAMediaBSDMinor = 5;
DAMediaBSDName = disk2;
DAMediaBSDUnit = 2;
DAMediaBlockSize = 512;
DAMediaContent = “FDisk_partition_scheme”;
DAMediaEjectable = 1;
DAMediaIcon = {
CFBundleIdentifier = “com.apple.iokit.IOStorageFamily”;
IOBundleResourceFile = “Removable.icns”;
};
DAMediaKind = IOMedia;
DAMediaLeaf = 0;
DAMediaName = “Apple read/write (part) Media”;
DAMediaPath = “IOService:/IOResources/IOHDIXController/IOHDIXHDDriveOutKernel@3/IODiskImageBlockStorageDeviceOutKernel/IOBlockStorageDriver/Apple read/write (part) Media”;
DAMediaRemovable = 1;
DAMediaSize = 8086618112;
DAMediaWhole = 1;
DAMediaWritable = 0;
DAVolumeMountable = 0;
DAVolumeNetwork = 0;
}
2017-09-12 10:11:43.329 diskimages-helper[18225:7663085] _mountDevEntries: skipping disk2 because it doesn’t look mountable
Any ideas?
I believe based on the trace, you are trying to mount an NTFS image. I don’t think NTFS filesystems are supported natively. You may need something like OSXFuse or TuxeraNTFS.
A dynamically allocated VDI seems to the the issue:
VBoxManage clonemedium disk original.vdi new.vdi –variant fixed
I also installed Tuxera NTFS, but that was probably unnecessary in retrospect since I just needed read access.