Run-As Like the Wind: Getting private app data off non-rooted devices using adb run-as and a debuggable app
"You're some kind of big, fat, smart-bug aren't you?"One of the most important things about writing bugs is making them descriptive but concise. Screenshots, video, debug logging, and hardware snapshots are all fairly standard or available to Android testers these days and can save you enormously on text when communicating what constitutes the bug. Sometimes though, the app gets into a weird state due to some transient data issue where you may not own the API or the complexity with forcing the app data into a certain state is prohibitively high. In those cases it is very handy to directly inspect the data the app has in its own directories.
~Johnny Rico, Starship Troopers (1997)
Getting at this data is trivial on emulators and rooted devices but due to file system permissions, this data is otherwise completely private to the app itself. If you're like me, you tend to test using devices rather than emulators and you probably prefer not to root your devices since they are from a pool of shared devices used across your team or throughout your organization. This creates a slight problem when it comes to accessing those private files. Thankfully, there is a clever tool called "run-as". Here's how it helps.
Run-as allows you to execute commands in the shell with the same permissions owned by the app. It checks whether the user calling it is either root or using adb so you need to enable USB or WiFi adb debugging access on your device first. The syntax for running commands with "run-as" is identical to normal shell commands so you will be in familiar territory. Just prepend your normal command with "run-as com.example.app" where "com.example.app" is the package name for your app. A little caution though: this only works if your app is debuggable so this technique isn't valid for release packaged builds.
So how does "run-as" help you pull private application files? Alex P from Stack Overflow provides the following suggestion for accessing your app's database files. Because I intend to use this technique regularly, I've slapped together this quick script for pulling all relevant files from all attached devices which I'm using for my tests. Another caveat: Somewhere in Android 4.2, run-as got broken. This was patched for most devices but Samsung in particular continues to have problems from 4.2 devices ever since. They may have done this intentionally as this has been reported a long time ago and remains broken even on my test Galaxy S5 running 4.4.