Extracting Android Factory Images on macOS
There seem to be a plethora of tutorials for how to extract factory images on Linux and Windows without much crossover into macOS.
Thankfully, the method for extracting a factory image on macOS so we can peruse the filesystem is really similar to Linux. The problem is, we need some way to mount the extracted image to an extended filesystem. macOS doesn’t support this out of the box, so we’ll use OSXFuse to make it happen.
FUSE implements a mechanism that makes it possible to implement a fully functional file system in a user-space program on macOS.
Now, in order to access ext4, we’ll also need an ext4 implementation for macOS Fuse (aptly named, ext4fuse).
This is a read-only implementation of ext4 for FUSE. The main reason this exists is to be able to read linux partitions from OSX.
If you’re curious about ext4 vs ext3 vs ext2 Linux file systems, take a look at this handy summary.
Finally, in order to extract the image file (before mounting it with OSX Fuse), we’re going to use imgtool. In many Linux tutorials you’ll see references to simg2img; this replaces that for macOS (although a Linux binary exists as well).
Think of it as the inverse of mkbootimg (from the AOSP), coupled with simg2img (the sparse image extractor). Another bonus feature it provides is unpacking the Linux bzimage kernels.
It was developed by the legendary Jonathan Levin. He is brilliant.
WHAT TO DO
Download whatever image file you want to extract. Google makes theirs readily available here. I’ll be using “taimen” for Pixel2 XL for this tutorial. Unzip the downloaded image file, navigate within that unzipped directory, and unzip the inner directory (in this example, named image-taimen-opd1.170816.010.zip ) as well. We want to get to the system.img file within that second zipped directory.
Download imgtool and unpack the .tgz:
tar -xvzf <imgtool.tgz path> -C /path/where/to/extract
Then, navigate to the directory where imgtool was unzipped where you’ll see a bunch of fun C files.
We’re going to use imgtool on the image file downloaded from Google (or wherever yours is from). I like using a split-screen in iTerm so I don’t forget where my image lives.
Extract the image file with imgtool:
./imgtool <path-to-factory-image>/system.img extract
You should now see a new directory within imgtool called “extracted”: imgtool/extracted/image.img Within this directory is a new image file. This is the image you’ll mount in order to access the filesystem.
brew cask install osxfuse
Restart your computer. Painful, I know.
brew install ext4fuse
Create a directory to hold the mounted image:
sudo mkdir /Volumes/Linux
Mount the extracted image to that directory:
sudo ext4fuse ../imgtool/extracted/image.img /Volumes/Linux -o allow_other
Including the allow_other option is really important here: it allows users other than the superuser account to access the filesystem.
Navigate to /Volumes/Linux and you should be able to see the system dump!
When you’re done working with the mounted image, you won’t be able to just delete the directory you’ve created. You’ll have to unmount it:
diskutil unmount /Volumes/Linux
Do you have another way of extracting image files in macOS? Would love to hear what your approach is! Leave a comment below.