A friend came to me with a broken Samsung Galaxy S4, its screen would never turn on, but it was reacting to receiving charge and being plugged into the computer. That friend wanted to recover all data on that phone. Too bad android does not auto mount storage when plugged in.
Rule 1: Make backups
Rule 2: Help your fellow non-neckbeards with your extensive unix knowledge
If you find yourself without backups and half a broken phone this might be the guide for you.
Prerequisites
Preferably a Computer running Linux, but some of the upcoming tasks can be handled by W*ndows too.
Install the Android SDK Platform Tools to your computer. this includes the android debug bridge, fastboot and some other tools.
sudo pacman -S android-tools android-udev
sudo dnf install android-tools
Step 1 - Connect to Android Debug Bridge
ADB allows you to reboot the phone into recovery, to get a shell, to pull the flash data off of it.
Before anything, we want to get the phone into recovery mode. This enables us to use ADB by side-stepping a prompt in android, whether or not we want to trust our pc’s ADB request. This is impossible if your screen and/or touch digitizer is broken.
In case of the Galaxy S4, after power off, we need to hold VolUp+Power+Home until the Samsung logo shows up. This is different for every phone.
Alternatively, if we already have adb setup in android, we can run:
adb reboot bootloader
And from there select recovery mode on the phone screen, using its buttons.
As soon as we are in recovery mode, connect the phone to a pc.
To check whether the device is recognized, run adb devices
.
It should show a device identifier and its current state:
unauthorized, device or recovery
roman@pc~: adb devices
List of devices attached
ZY******XJ recovery
If the device is in recovery
state, we can begin the recovery process.
Step 2 - Investigating device under test
Depending on make and model,
there are different paths that we would need to adb pull
from.
To begin our investigation, let us gain a shell with adb shell
.
Now we can list directories present on the root of our android system.
roman@pc~: adb shell
~ # _
~ # ls
boot init.recovery.qcom.rc selinux_version
cache init.recovery.usb.rc sepolicy
charger license service_contexts
data oem sideload
default.prop preload supersu
dev proc sys
efs property_contexts system
etc recovery tmp
external_sd res twres
file_contexts root ueventd.qcom.rc
fstab.qcom sbin ueventd.rc
init sdcard usb-otg
init.rc seapp_contexts
~ #
Our best bet is looking at /dev
and more so /dev/block
.
~ # ls /dev/block
bootdevice loop7 mmcblk0p15 mmcblk0p22 mmcblk0p8 ram13 ram7
loop0 mmcblk0 mmcblk0p16 mmcblk0p23 mmcblk0p9 ram14 ram8
loop1 mmcblk0p1 mmcblk0p17 mmcblk0p24 platform ram15 ram9
loop2 mmcblk0p10 mmcblk0p18 mmcblk0p3 ram0 ram2
loop3 mmcblk0p11 mmcblk0p19 mmcblk0p4 ram1 ram3
loop4 mmcblk0p12 mmcblk0p2 mmcblk0p5 ram10 ram4
loop5 mmcblk0p13 mmcblk0p20 mmcblk0p6 ram11 ram5
loop6 mmcblk0p14 mmcblk0p21 mmcblk0p7 ram12 ram6
~ #
We see that there is this mmcblk0
block device that has a lot of partitions.
Now is a good time to consult the internet to figure out how our phone was partitioned.
Every partition here has a purpose,
one of those being the data partition that houses all of the user data, media etc…
If you are stuck here, try reading the phone’s fstab: cat /etc/fstab
.
Step 3 - Backing it all up
From what I have seen so far,
most phone vendors position the user partition at the end of the block device.
For my Samsung Galaxy S4 mini, it is mmcblk0p24
.
Using adb pull
we can copy the entire partition over to our PC.
roman@pc~: adb pull /dev/block/mmcblk0p24
[ ?] /dev/block/mmcblk0p24: 615907328/?
When the transfer finishes, it should read:
roman@pc~: adb pull /dev/block/mmcblk0p24
/dev/block/mmcblk0p24: 1 file pulled, 0 skipped. 7.9 MB/s (5821677056 bytes in 698.935s)
roman@pc~: ll mmcblk0p24
.rw-r--r-- 5,8G roman roman 21 Apr 21:22 mmcblk0p24
From here on out it is smooth sailing, as we now only need to mount the copied partition, and backup our files. We can unplug the phone and turn it off.
Since this is just a regular ext4 partition contained in a single file, we can proceed and mount it like this:
mkdir /mnt/test
sudo mount -o rw mmcblk0p24 /mnt/test
There is one problem though, we do not have permissions for a lot of files. Some are owned by me, root or some random user/group-id that was present on the phone, but not on my linux machine, where this mount lives.
roman@pc~: ll /mnt/test
.rw-------@ 2 root root 1 Jan 1970 .layout_version
.rw-rw----@ 1 roman root 20 Apr 01:18 .psm.info
drwx------@ - root root 27 Feb 2018 adb
drwxrwxr-x@ - roman roman 15 Jul 2021 anr
drwxrwx--x@ - roman roman 20 Apr 01:24 app
drwx------@ - root root 27 Feb 2018 app-asec
drwxrwx---@ - 1013 1005 27 Feb 2018 audio
drwxr-xr-x@ - 2000 2000 27 Feb 2018 bootchart
Since we only care about getting the data off the partition, we can recursively modify the uid and gid of every file on the partition.
sudo chmod -R roman:roman /mnt/test/.
roman@pc~: ll /mnt/test/
.rw-------@ 2 roman roman 1 Jan 1970 .layout_version
.rw-rw----@ 1 roman roman 20 Apr 01:18 .psm.info
drwx------@ - roman roman 27 Feb 2018 adb
Now we are ready to finally copy all our data to a safer location. Again, depending on make and model, the location of your “internal Storage” is different. Some phones save it to any of these paths:
/mnt/test/media/0/
/mnt/test/sdcard/
/mnt/test/sdcard1/
/mnt/test/storage/emulated
/mnt/test/storage/self/primary/
Additional Notes
Every device I tested this on behaved slightly different. This includes the Samsung S4 mini, Motorola G4 Plus, Xiaomi Redmi Note 7, and my current Motorola one fusion+.
Some phones (my Xiaomi Note 7) print a help menu in the adb shell:
lavender:/ # help
usage: help [-ah] [command]
Show usage information for toybox commands.
Run "toybox" with no arguments for a list of available commands.
-h HTML output
-a All commands
lavender:/ # toybox
acpi base64 basename blkid blockdev cal cat chattr chcon chgrp chmod
chown chroot chrt cksum clear cmp comm cp cpio cut date dd df diff
dirname dmesg dos2unix du echo egrep env expand expr fallocate false
fgrep file find flock fmt free freeramdisk fsfreeze getenforce getfattr
grep groups gunzip gzip head help hostname hwclock id ifconfig inotifyd
insmod install ionice iorenice iotop kill killall ln load_policy log
logname losetup ls lsattr lsmod lsof lspci lsusb makedevs md5sum microcom
mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount mountpoint
mv nbd-client nc netcat netstat nice nl nohup od partprobe paste patch
pgrep pidof pivot_root pkill pmap printenv printf ps pwd pwdx readlink
realpath renice restorecon rev rfkill rm rmdir rmmod runcon sed sendevent
seq setenforce setfattr setprop setsid sha1sum sha224sum sha256sum
sha384sum sha512sum sleep sort split start stat stop strings stty
swapoff swapon sync sysctl tac tail tar taskset tee time timeout top
touch tr traceroute traceroute6 true truncate tty tunctl ulimit umount
uname uniq unix2dos uptime usleep uudecode uuencode vconfig vmstat
wc which whoami xargs xxd yes zcat
lavender:/ #
There are lots and lots of partitions on newer phones.
Phone - Codename | Storage | Partitions | Partition | Size |
---|---|---|---|---|
Samsung S4 mini | 8GB | 24 | mmcblk0p24 | 5.8GB |
Samsung S4 | 16GB | 29 | mmcblk0p29 | like 12GB? |
Moto G4 Plus - athene | 32GB | 48 | mmcblk0p48 | 25.3GB |
Xiaomi Note 7 - lavender | 64GB | 66 | mmcblk0p66 | 55GB |
Moto one fusion+ - liber | 128GB | see below |
Seems like my newest phone uses a different type of storage/flash.
It looks like it only has one partition mmcblk0p1
in device mode.
liber:/ $ ls /dev/block
bootdevice dm-20 loop11 loop25 ram1 sda sdb2 sdc2 sde19 sdf10 sdf3
by-name dm-21 loop12 loop26 ram10 sda1 sdb20 sdd sde2 sdf11 sdf4
dm-0 dm-22 loop13 loop27 ram11 sda2 sdb21 sdd1 sde20 sdf12 sdf5
dm-1 dm-23 loop14 loop3 ram12 sdb sdb22 sdd2 sde21 sdf13 sdf6
dm-10 dm-24 loop15 loop4 ram13 sdb1 sdb23 sde sde22 sdf14 sdf7
dm-11 dm-3 loop16 loop5 ram14 sdb10 sdb24 sde1 sde23 sdf15 sdf8
dm-12 dm-4 loop17 loop6 ram15 sdb11 sdb3 sde10 sde3 sdf16 sdf9
dm-13 dm-5 loop18 loop7 ram2 sdb12 sdb4 sde11 sde4 sdf17 vold
dm-14 dm-6 loop19 loop8 ram3 sdb13 sdb5 sde12 sde5 sdf18 zram0
dm-15 dm-7 loop2 loop9 ram4 sdb14 sdb6 sde13 sde6 sdf19
dm-16 dm-8 loop20 mapper ram5 sdb15 sdb7 sde14 sde7 sdf2
dm-17 dm-9 loop21 mmcblk0 ram6 sdb16 sdb8 sde15 sde8 sdf20
dm-18 loop0 loop22 mmcblk0p1 ram7 sdb17 sdb9 sde16 sde9 sdf21
dm-19 loop1 loop23 platform ram8 sdb18 sdc sde17 sdf sdf22
dm-2 loop10 loop24 ram0 ram9 sdb19 sdc1 sde18 sdf1 sdf23
liber:/ $
It beats me what device there really is the userdata partition.