Mounting VMDK on macOS
The libvmdk library allows you to access the VMware Virtual Disk (VMDK) format.
This post covers how to use the tools from the libvmdk
library to manage VMDK files via Terminal on macOS.
I frequently use VMDK files in the Mac Forensics training courses I teach (together with my dear friend and colleague F.C.). These files are a convenient way to share with students disk images specifically created with virtual machines for homeworks, CTF challenges, etc. The images are designed to be mounted on macOS systems for further investigation by students.
From my experience, the tools from libvmdk
, such as vmdkmount
, are effective for handling VMDK files through the command line, though their installation and use on macOS can be tricky.
This post explains how to build and use the libvmdk
tools on macOS from releases, with a focus on resolving common issues when using the vmdkmount
tool.
The instructions have been tested on a M2 MacBook Pro running macOS Sonoma 14.5 with macFUSE 4.8.0 and libvmdk-alpha-20240510.tar.gz.
However, they are adaptable for other recent macOS versions and libvmdk
releases.
Building a libvmdk release on macOS
Download the latest release from libvmdk releases, which at the time of this post is libvmdk-alpha-20240510.
Please verify online that the version of
libvmdk
you’re downloading is still available. If not, you’ll need to replace the URL above.
One strong dependency which must be installed prior to configuring libvmdk
is macFUSE.
It can be installed via Homebrew:
% brew install macfuse
Since macFUSE requires a kernel extension to function, you’ll need to enable it System Settings > Privacy & Security after installation.
Once libvmdk
is downloaded and macFUSE is installed, extract the archive with tar xvf libvmdk-alpha-20240510.tar.gz
, navigate to the extracted folder libvmdk-20240510
, and run ./configure
to configure the package.
Previously, I encountered no issues with libvmdk-20221124
, but with libvmdk-20240510
, the configuration process fails to detect macFUSE.
Below is part of the output when running ./configure
:
This happens even though macFUSE is installed in your system, with the related package available at /usr/local/lib/pkgconfig/fuse.pc
.
This .pc
file contains the following information:
prefix=/usr/local
2 exec_prefix=${prefix}
3 libdir=${exec_prefix}/lib
4 includedir=${prefix}/include
5
6 Name: fuse
7 Description: Filesystem in Userspace
8 Version: 2.9.9
9 Libs: -L${libdir} -lfuse -pthread
10 Libs.private: -liconv -framework CoreFoundation -framework DiskArbitration
11 Cflags: -I${includedir}/fuse -D_FILE_OFFSET_BITS=64
The .pc
file is used by pkg-config to retrieve the metadata for compiling and linking a program to a library.
The configuration of libvmdk
relies on pkg-config but cannot locate fuse.pc
.
To resolve this, add the package path as follows:
% export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ && ./configure
The PKG_CONFIG_PATH
environment variable specifies additional paths where pkg-config will search for its .pc
files.
Running ./configure
again with the path of the folder containing fuse.pc
enables FUSE support for libvmdk
:
With the FUSE support enabled, you can compile the package with make
and install it using make install
.
Specifically, the new programs available on your system will be:
vmdkinfo
: Provides information about a VMDK image file.vmdkmount
: Mounts a VMDK image file.
Let’s explore how to use vmdkmount
on a Mac more efficiently.
Using vmdkmount to Mount a VMDK
The vmdkmount
command-line tool works as follows:
vmdkmount [ -X extended_options ] image mount_point
where extended_options
are options (if any) passed to the subsystem, image
is the VMDK image file, and mount_point
is the desired mount location.
On a Mac, vmdkmount
sometimes requires additional attention.
For instance, if you want to mount a VMDK renamed to nash.vmdk
, located at /Volumes/nash/nash.vmdk
, using /tmp/mp
as the mount point, you might try the following:
However, the tool fails to open the source image because vmdkmount
does not support renaming for stream optimized images (see the open issue 34 on the GitHub repository of libvmdk
).
The workaround is to either rename the image back to its original name (which can be determined using vmdkinfo
) or navigate to the folder containing nash.vmdk
and mount the image from there:
Additionally, when running vmdkmount
on macOS, it appears that macFUSE requires a volume icon, which you’ll need to specify during the mount process (see the closed issue 117 on the GitHub repository of libvmdk
):
To address this, pass the volume icon (volicon=/path/to/volume_icon
) via the extended options (-X
) of vmdkmount
:
Consequently, when you want to mount a renamed VMDK on a Mac, you need to execute the following commands:
cd /path/to/parent_of_vmdk
% vmdkmount -X volicon=/Library/Filesystems/macfuse.fs/Contents/Resources/Volume.icns image.vmdk /path/to/MountPoint
Mounting VMDK from Any Directory on macOS
As shown, mounting VMDK images on macOS can be tricky.
It is more convenient to create an alias which can be used to run vmdkmount
to mount an image from any directory and without providing extended options.
Since creating an alias with arguments can be problematic, you can create a function that accepts the path to the image and the path to the mount point as arguments.
This function handles issues like renaming stream optimized images and the icon path error.
The vmdkmount2
function below serves this purpose:
# Alias for vmdkmount working from any directory.
vmdkmount2() {
local vmdk_path="$(dirname $1)"
local vmdk_file="$(basename $1)"
local mount_point="$2"
local cur_dir="$PWD"
cd "${vmdk_path}"
mkdir -p "${mount_point}"
vmdkmount -X volicon=/Library/Filesystems/macfuse.fs/Contents/Resources/Volume.icns "${vmdk_file}" "${mount_point}"
cd "${cur_dir}"
}
To define the vmdkmount2
function in your environment for login shells, you can append this function (for example, within a file named as vmdkmount2.sh
) to .zprofile
:
% cat vmdkmount2.sh >> ~/.zprofile
Once you have defined vmdkmount2
, you can easily mount a VMDK image on Mac as follows:
% vmdkmount2 /path/to/image.vmdk /path/to/MountPoint
Once the VMDK is mounted on your Mac, you can attach the virtual disk to the system using hdiutil attach
with the option -imagekey diskimage-class=CRawDiskImage
:
The output of hdiutil
shows that new volumes from the VMDK are now available.
These volumes can be mounted, for example, with diskutil
, allowing you to interact with them as needed.
I find the libvmdk
tools, vmdkmount
and vmdkinfo
, to be invaluable when working with VMDK images on macOS.
I have created a GitHub gist containing the vmdkmount2
function.
You can use this to quickly update your .zprofile
and have this helper function readily available.