Reputation: 185
I'm trying to mount the userdata-qemu.img.qcow2 file created by the Android emulator. The following procedure does not work:
sudo qemu-nbd -c /dev/nbd0 ~/.android/avd/Pixel_C_API_27.avd/userdata-qemu.img.qcow2
First command runs well, but running
sudo qemu-nbd -c /dev/nbd0 ~/.android/avd/Pixel_C_API_27.avd/userdata-qemu.img.qcow2
results in this output:
Fehler: /dev/nbd0: unbekannte Partitionstabelle
Modell: Unbekannt (unknown)
Festplatte /dev/nbd0: 3146MB
Sektorgröße (logisch/physisch): 512B/512B
Partitionstabelle: unknown
Disk-Flags:
Basically it cannot recognize a partition table in the image file. You may wonder what's the output of
fdisk /dev/nbd0 -l
so here it is:
Medium /dev/nbd0: 3 GiB, 3145728000 Bytes, 6144000 Sektoren
Einheiten: sectors von 1 * 512 = 512 Bytes
Sektorengröße (logisch/physisch): 512 Bytes / 512 Bytes
I/O Größe (minimal/optimal): 512 Bytes / 512 Bytes
As you could expect already, mounting fails of course, since no partitions can be recognized if the partition table itself cannot be recognized either. Thanks for any help!
Edit: I've just found out that the problem must have to do with Android's userdata encryption. As I've never changed any password the encryption password of the emulator's userdata partition would have to be the default one "default_password". How can I decrypt the image to be able to mount it?
Upvotes: 2
Views: 5466
Reputation: 1864
The question explicitly mentions API 27 (Android 8.1), so the drive in question would be encrypted using Full Disk Encryption (FDE). This also applies to API 28. The way it works is that a key is stored in a separate partition, and each 512-byte block of the main partition is encrypted using AES-128/256-CBC with ESSIV used to produce per-sector IV values. The stored key is encrypted in CBC, with the key-encrypting-key using the user's PIN/password (or default_password
if no PIN was set), hashed using either scrypt
or pbkdf2
.
You can find a utility for decrypting FDE-encrypted emulator images here.
If, however, you're reading this from the future, and your image uses API 30+ (Android 11+), then chances are the drive is encrypted using File Based Encryption (FBE) with metadata encryption. The metadata encryption is similar to FDE, except the blocks are 4096 bytes long, and encrypted using AES-256-XTS or Adiatnum. Additionally the encryption key is no longer encrypted using the user PIN. Instead, the encryption key partition is now a regular Ext4 partition, with several files in the folder /vold/metadata_encryption/key
. The file encrypted_key
contains the key encrypted using AES-256-GCM, and the file keymaster_key_blob
contains the encryption key for encrypted_key
(Specifically, in the 6th through 37th bytes).
One tiny caveat of metadata encryption is that it only encrypts blocks not previously encrypted by the filesystem contained in the drive. FBE uses a second layer of encryption for individual files and folders. This means that metadata encryption can't be "blindly" decrypted, as that would corrupt the file contents of any encrypted files. A two-step process would be needed where first the group descriptor and inode tables are decrypted, and only after checking which blocks belong to files (This can be done without decrypting any files or folders), the remaining blocks are decrypted.
If you're using API 29, the disk itself should not be encrypted, and can be mounted using the procedure in the OP. However, both the unencrypted disk in API 29, and the decrypted disk in API 30+, contain encrypted files and folders instead. These are encrypted using "Linux native file encryption", also known as "fscrypt". This wouldn't interfere with running fdisk or mounting the drive, since the format is natively supported by the filesystem driver, but encrypted files and folders would remain inaccessible until the matching keys are added the keyring. The locations of the keys are:
/unencrypted/key/encrypted_key
- Used to encrypt the folder containing the other two keysmisc/vold/user_keys/de/0/encrypted_key
- Used to encrypt files and folders that do not require PIN unlock to be accessible. For instance, it's used for application code, to allow applications to send notifications even when the device is locked.misc/vold/user_keys/ce/0/current/encrypted_key
- Used to encrypt files and folders that do require PIN unlock, such as private user data. The encryption key for this key is generated using a combination of the user PIN or hardware-generated token (e.g. for fingerprint unlock), and files in the system_de/0/spblob
and /misc/keystore
folders.A utility for decrypting all of the above, from metadata encryption to individual files, under the assumption that no PIN was set, can be found here.
Upvotes: 0
Reputation: 51
You can mount userdata-qemu.img.qcow2
using the following procedure
convert the image to a raw image
qemu-img convert -O raw userdata-qemu.img.qcow2 udata-raw.img
use losetup
to setup a loopback device for mounting
sudo losetup -f -P userdata.img
use losetup -l
to see what device was setup
losetup -l NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO /dev/loop0 0 0 0 0 /path/to/userdata.img 0
mount the drive
mkdir /tmp/mnt sudo mount /dev/loop0 /tmp/mnt
Then ls /tmp/mnt/
gives
app benchmarktest benchmarktest64 lost+found misc nativetest nativetest64
Upvotes: 2