How to extract the database(s) from a non-debuggable / signed Android App

The other day a device hit my desk….

One of our production Retail Execution (ITX) apps running on it was stuck in a loop — the bug was forwarded to the relevant development team, however, there where important transactions (about a days work for the sales rep) still in the device database that needed to be extracted.

So while I did this, I thought I would do a quick writeup for others who face the same issue in future.

Note: Step 1 & 2 are for those of you who do not know about adb and how to connect a device to your Mac. If you already have adb connected and your device in developer mode, skip to Step 3.

Step 1 — Setup your Mac

You will need the following installed:

This will also install Android Debug Bridge (adb) and add it to your path.

To test, open terminal and type adb --version

Step 2 — Setup the Android device

  1. Enable Developer Options

Go to Settings → About device → Software info

Then tap on Build Number seven times (you will see a toast message notifying you of how many more times to tap)

You will now see a Develop Options option on your settings menu like the following :

Ensure that the USB Debugging option is selected.

2. Plug your device into your computer with a USB cable

If adb is running, you should see a permission popup on your device:

Grant your Mac permission (optionally Always Allow)

Once done, you should see the device available under adb devices :

Step 3 — Identify and pull the APK

First shell into the device:

adb shell

Then identify the apk you want to pull:

pm list packages
Some of the app APK packages on the device

To make it easier (and you sort of know the bundle id of the app you are looking for) you can pipe the above command to grep:

pm list packages | grep atajo
A single hit for the app APK I am looking for

To pull the APK, run :

adb backup -noapk com.app.your.package.name

Your device will prompt you for a (optional) password to encrypt the backup with. In this case, I chose to skip creating a password because it makes the next steps easier.

Once pulled, you will see a mybackup.ab file in your current directory. This is basically a Java deflated (compressed) tar file. So to inflate (decompress) it into something your Mac understands, you have two options depending on your setup:

You can use openssl to extract the archive :

dd if=mybackup.ab bs=24 skip=1|openssl zlib -d > mybackup.tar; 
tar -xvf mybackup.tar

If you get an error like :

openssl:Error: 'zlib' is an invalid command.

You can alternatively use Python like so :

dd if=backup.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -\n

Either way, you should now have a apps directory in the current directory. The app contents was extracted there:

The database and app files all in a directory named after the bundle id.

Step 4 — View the database

Disclaimer: This particular app had an encrypted database — I deliberately left out the decryption step as it is proprietary to the company the app belongs to.

I have been using SQLiteBrowser for a few years now, and it is still the best SQLite database explorer I know of for Mac.

So the next step is to simply find the database you want to query in the above db directory, and open it in the SQLiteBrowser app:

All the database files available to be opened
The database I was looking for.

Now you can query anything you want.

Step 5: Disabling Developer Options (Optional)

The only way to remove “Developer Options” from the Settings menu again is by clearing the App Cache of the Settings app.

Go to Settings → Application → All and select the Settings app. Once selected, hit Clear Cache — Don’t worry about the warning, it will literally just remove the change that resulted in Developer Options being visible.

And that’s it. Great Success! Thanks for reading.

cloud developer || hardware hacker