Skip to content

re-ws.pl

ReverseEngineering WorkStation

  • Home
  • Tutorials
  • Random
  • About

Mounting encrypted Android emulator image

Posted on July 8, 2019 - February 21, 2025 by Kamil (aka. v3l0c1r4pt0r)
fastboot icon

Android emulator is really nice way to play with Android’s internals. Unfortunately at least those emulators, which have Play Store preinstalled, also don’t have root access via adb root command. What is more, latest emulators started encrypting userdata partition, even if no lock mechanism is configured and there is no way to undo the encryption from inside the Android.

In this article, I will show how to gain access to emulator’s partitions from outside the emulator.

Note: I didn’t need to write anything, so I didn’t try to reencrypt the partition.

Note: This tutorial was written for Android version < 10. Android 10 introduced completely new encryption scheme, so there is not chance of porting this to anything recent.

AVD structure

Before getting into encryption itself, let’s see quick summary of how to find emulator data and what to expect inside. On Linux all AVDs are stored at:

.android/avd/$NAME.avd

where $NAME is name of the target AVD. Inside there are a few .img files. In a good old days, inside there were all the data of the emulated devices. Now, they seem to be only base for the real partition image. These real device files are called almost the same, but with .qcow2 extension. In my case the interesting part looks like below:

cache.img
cache.img.qcow2
encryptionkey.img
encryptionkey.img.qcow2
sdcard.img
sdcard.img.qcow2
userdata.img
userdata-qemu.img
userdata-qemu.img.qcow2

Interesting part is userdata-qemu and encryptionkey.

Mounting qcow2

qcow2 is format provided by qemu. Fortunately, along the support for emulated devices, there is a tool called qemu-nbd, which allows to use qcow2 images in a similar way as losetup handles normal images. At first, we have to make sure nbd device is loaded into kernel:

sudo modprobe nbd max_part=8

Inserting it should cause nbd devices to appear under /dev filesystem:

$ ls -1 /dev/nbd*
/dev/nbd0
/dev/nbd1
/dev/nbd10
/dev/nbd11
/dev/nbd12
/dev/nbd13
/dev/nbd14
/dev/nbd15
/dev/nbd2
/dev/nbd3
/dev/nbd4
/dev/nbd5
/dev/nbd6
/dev/nbd7
/dev/nbd8
/dev/nbd9

Now, we can connect our image to it with command like:

sudo qemu-nbd --connect=/dev/nbd0 userdata-qemu.img.qcow2

By the way following partition have to be connected. It will be needed in the next step:

sudo qemu-nbd --connect=/dev/nbd1 encryptionkey.img.qcow2

cryptfs footer

The mentioned partition contains is so called crypt footer. It stores parameters of encryption. Sometimes it may happen that it is appended to the partition itself (I don’t know on what it depends).

It would be easier to handle it from regular file, so let’s dump it:

dd if=/dev/nbd1 of=footer

Some tools I was using shows some information about the contents of this footer. It looks more or less like that:

Magic          : 0xD0B5B1C4
Major Version  : 1
Minor Version  : 3
Footer Size    : 104 bytes
Flags          : 0x00000000
Key Size       : 128 bits
Failed Decrypts: 0
Crypto Type    : aes-cbc-essiv:sha256
Encrypted Key  : 0xE94C81922869235354DEF01FA4D04C97
Salt           : 0x921600CF57725700CB286378C333A019
----------------

Meanwhile, I also created quick HDCB script to see it in hexdump:

00000000  c4 b1 b5 d0 01 00 03 00  30 09 00 00 00 00 00 00  |........0.......|
00000010  10 00 00 00 01 00 00 00  00 00 c0 00 00 00 00 00  |................|
00000020  00 00 00 00 61 65 73 2d  63 62 63 2d 65 73 73 69  |....aes-cbc-essi|
00000030  76 3a 73 68 61 32 35 36  00 00 00 00 00 00 00 00  |v:sha256........|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000060  00 00 00 00 00 00 00 00  e9 4c 81 92 28 69 23 53  |.........L..(i#S|
00000070  54 de f0 1f a4 d0 4c 97  00 00 00 00 00 00 00 00  |T.....L.........|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 00 00 00 00 00 00 00  92 16 00 cf 57 72 57 00  |............WrW.|
000000a0  cb 28 63 78 c3 33 a0 19  00 10 00 00 00 00 00 00  |.(cx.3..........|
000000b0  00 20 00 00 00 00 00 00  00 10 00 00 02 0f 03 01  |. ..............|
000000c0  00 00 c0 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000008e0  00 00 00 00 00 00 00 00  00 00 00 00 5d d2 5c e6  |............].\.|
000008f0  af 3b 29 0b e9 0a 2b 0e  db 19 e8 da d9 f8 50 10  |.;)...+.......P.|
00000900  a7 ed 14 ef 1a 82 67 26  22 b8 fc bf 2a f4 ac 5b  |......g&"...*..[|
00000910  a4 13 70 82 29 bf 50 b0  76 d5 a6 01 56 15 4e 69  |..p.).P.v...V.Ni|
00000920  70 29 84 2a 00 72 3e 72  a6 6a c9 74 00 00 00 00  |p).*.r>r.j.t....|
00000930  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00001000  44 cd 50 e9 00 00 00 00  00 00 00 00 00 00 00 00  |D.P.............|
00001010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000

[algo] [failures] [flags] [fs_size] [kdf] [keysize] [magic] [major]
[master_key] [minor] [N] [offset] [p] [r] [reserved] [salt] [size] 

 

Decryption

Finally, it is possible to decrypt partition contents. What we need to know is:

  1. Password. If there is no screen lock set, it should default to ‘default_password’ and this is what worked in my case
  2. Partition size in bytes. If unknown, it could be calculated from footer (I marked it on hexdump as fs_size and is given in sectors, where size of sector is 512 bytes)

For this step android-fde repository is required. I made small improvement to it to make block devices working. Otherwise, it would be required to dump nbd image to file. It can be cloned from Github using:

git clone https://github.com/v3l0c1r4pt0r/android-fde.git -b blockdev

Then we can do:

android-fde/pydroidfde/decrypt.py \
  -p default_password \
  -S 6442450944 \
  /dev/nbd0 footer userdata-qemu.img

where -S is for giving partition size, nbd0 is my userdata partiton and userdata-qemu.img is output file.

After few minutes of decryption, it can be mounted easily using losetup and mount commands:

sudo losetup /dev/loop0 userdata-qemu.img
sudo mount /dev/loop0 /mnt

Contents of userdata partition should appear in /mnt.

When done, it is good idea to unmount everything.

Posted in TutorialsTagged Android, English, Linux, software

Post navigation

Printing pictures like its 1873 using Oki 3321 dot-matrix printer
New VCI+A-BT (DS150E) ST-Link pinout

8 Comments

  1. Vladimir says:
    February 24, 2020 at 20:37

    What about encrypting it back? Is it possible to create on-the-fly block device for encryption?

    Reply
    1. Kamil (aka. v3l0c1r4pt0r) says:
      February 24, 2020 at 21:02

      In principle it is possible to encrypt it back. I’m only worried that no tool might exist for the job. The same problem might be with both – encryption from file and mounting on the fly. Looking at the length of decrypt.py script, it shouldn’t be very complicated to do the other way round, though.

      Reply
  2. Flo says:
    May 7, 2020 at 16:38

    Hello,

    I tried your setup on Ubuntu 20 LTS, it failed on the python script. Could you check that? I want to decrypt an Android 10 system.

    Reply
    1. Kamil (aka. v3l0c1r4pt0r) says:
      May 7, 2020 at 18:29

      What error exactly did you get? Maybe with Android 10 there is some change to encryption scheme? I don’t have any device with Android 10 to check if I can reproduce the issue. The script was not mine, I just did some tweaks for my use case. Maybe the original script was fixed already?

      Reply
      1. Flo says:
        May 8, 2020 at 15:08

        I don’t remember the exact error message, but it said something like “invalid key size” when I tried to decrypt the system.

        I don’t have an android 10 device either, I tried to break into a emulated device (I use Android Studio)
        As long as your computer supports hardware virtualisation, you could simply download Android studio and try to decrypt the emulated system. Since the original script wasn’t updated for a long time, i guess it just doesn’t work anymore on modern systems.

        Reply
        1. Kamil (aka. v3l0c1r4pt0r) says:
          May 9, 2020 at 07:09

          Script complaining about key size indeed sounds like a lack of support. You still can try comparing major and minor number of the footer. But if really it is greater than what I have, there is not much we can do. In such case, somebody has to make a research about new format and rewrite the script.

          Reply
  3. x says:
    January 14, 2021 at 00:46

    Hi. Is it possible to read and write to the system.img.qcow2 disk of Android 11 AVDs? The android-fde project does not appear to support file-based encryption.

    Reply
    1. Kamil (aka. v3l0c1r4pt0r) says:
      January 14, 2021 at 07:52

      Most likely, they changed format of encrypted container. For virtual systems I don’t see any way of preventing you from accessing the container, other than software support. And software must already be open source, like whole AOSP. So, it’s only a matter of adding the support to a tool of your choice.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Tags

Android assembly busybox C CAN can-hacking cc-factory cmake compiler docker Dreamspark electronics English gcc hacking hardware JavaCard JCOP kernel KiCAD library Linux PC PCB pinout PKI polski programming Python radio Raspberry Pi Reverse Engineering RTL-SDR SDC SDM SDR smart card software tor tty UART UEFi Windows X.509 Xperia Pro

Recent Posts

  • PHP build for use bundled in Android applications
  • Running graphical apps inside Docker containers
  • Plugin architecture demo for Python projects
  • Authorizing adb connections from Android command line (and making other service calls from cli)
  • How to recover torrent from rtorrent meta files

Recent Comments

  • pomi on Playing with GF-07 GPS device
  • pomi on Playing with GF-07 GPS device
  • Hamdy Abumgata on Playing with GF-07 GPS device
  • Mousum Gogoi on Playing with GF-07 GPS device
  • Eason on Sniffing USB traffic with DSLogic logic analyzer into pcap file

Categories

  • News
  • Random
  • Reversing LKV373A
  • Setting up new v3 Hidden Service with ultimate security
  • Tutorials
  • Uncategorized
  • Understanding JCOP

Links

  • Me @ github
  • LKV373A Wiki
  • DevTomek

Archives

  • December 2024
  • November 2024
  • May 2024
  • July 2023
  • October 2022
  • August 2022
  • July 2021
  • June 2021
  • May 2021
  • December 2020
  • November 2020
  • October 2020
  • August 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • February 2019
  • November 2018
  • October 2018
  • June 2018
  • May 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • September 2017

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
Proudly powered by WordPress | Theme: micro, developed by DevriX.