Retrieve database or any other file from the Internal Storage using run-as

On a non-rooted android device, I can navigate to the data folder containing the database using the run-as command with my package name. Most files types I am content with just viewing, but with the database I would like to pull if from the android device.

Is there a download copy or move command from this part of adb shell? I would like to download the database file and view its content using a database browser.

One answer here involves turning entire application package into a compressed archive, but there is no further answer on how to extract that archive once this is done and moved to the machine, leaving me very sidetracked when there might be a more direct solution to begin with

98130 次浏览

根据设计,安卓系统的 user版本(在解锁 引导程序并使用 userdebugeng软件闪光之前,你的手机上就只有这个版本)限制了对 内部存储的访问——每个应用程序只能访问自己的文件。幸运的是,对于不愿意使用 root的软件开发人员来说,他们的手机谷歌提供了一种使用 run-as命令访问 可调试的版本的 内部存储软件包的方法。

要从 Android 5.1 + 设备上下载 /data/data/debuggable.app.package.name/databases/file,请运行以下命令:

adb exec-out run-as debuggable.app.package.name cat databases/file > file

要同时在 /data/data/debuggable.app.package.name/下的文件夹中下载多个文件,请使用 tar:

adb exec-out run-as debuggable.app.package.name tar c databases/ > databases.tar
adb exec-out run-as debuggable.app.package.name tar c shared_prefs/ > shared_prefs.tar

接受的答案对我不起作用了(被 Android 屏蔽了?)

So instead I did this:

> adb shell
shell $ run-as com.example.package
shell $ chmod 666 databases/file
shell $ exit                                               ## exit out of 'run-as'
shell $ cp /data/data/package.name/databases/file /sdcard/
shell $ run-as com.example.package
shell $ chmod 600 databases/file
> adb pull /sdcard/file .

我发布了一个转储数据库的简单 shell 脚本:

Https://github.com/pixplicity/humpty-dumpty-android

它执行这里描述的两种不同的方法:

  1. 首先,它尝试让其他用户可以访问该文件,并尝试将其从设备中拉出。
  2. 如果失败,它将文件的内容通过终端传输到本地计算机。它执行一个额外的技巧来删除某些设备输出到 shell 的 \r字符。

从这里开始,您可以使用各种 CLI 或 GUISQLite 应用程序(如 sqlite3sqlitebrowser)来浏览数据库的内容。

下面是一个可以在运行 Android 5.1的设备上使用的解决方案。

您需要在 windows 上使用 Sed(或 sed.exe,例如来自 cygwin)(在 Unix 上,它就在那里;)。删除不良字符,至少在窗口上。

现在只需运行以下命令:

adb exec-out "run-as com.yourcompany.yourapp /data/data/com.yourcompany.yourapp/databases/YourDatabaseName" | c:\cygwin\bin\sed.exe 's/\x0D\x0A/\x0A/'>YourDatabaseName.db

Sed 命令删除尾随/r 字符。

当然,您应该将“ com.yourcompany.yourapp”替换为应用程序的包名称,并将“ YourDatabaseName”替换为应用程序中数据库的名称。

对于应用程序的调试版本,使用命令 adb exec-out run-as xxx.yyy.zzz cat somefile > somefile提取单个文件非常方便。但是您必须对多个文件执行多次操作。下面是我用来解压缩目录的一个简单脚本。

#!/bin/bash
P=
F=
D=


function usage()
{
echo "$(basename $0) [-f file] [-d directory] -p package"
exit 1
}


while getopts ":p:f:d:" opt
do
case $opt in
p)
P=$OPTARG
echo package is $OPTARG
;;
f)
F=$OPTARG
echo file is $OPTARG
;;
d)
D=$OPTARG
echo directory is $OPTARG
;;
\?)
echo Unknown option -$OPTARG
usage
;;
\:)
echo Required argument not found -$OPTARG
usage
;;
esac
done


[ x$P == x ] && {
echo "package can not be empty"
usage
exit 1
}


[[ x$F == x  &&  x$D == x ]] && {
echo "file or directory can not be empty"
usage
exit 1
}


function file_type()
{
# use printf to avoid carriage return
__t=$(adb shell run-as $P "sh -c \"[ -f $1 ] && printf f || printf d\"")
echo $__t
}


function list_and_pull()
{
t=$(file_type $1)
if [ $t == d ]; then
for f in $(adb shell run-as $P ls $1)
do
# the carriage return output from adb shell should
# be removed
mkdir -p $(echo -e $1 |sed $'s/\r//')
list_and_pull $(echo -e $1/$f |sed $'s/\r//')
done
else
echo pull file $1
[ ! -e $(dirname $1) ] && mkdir -p $(dirname $1)
$(adb exec-out run-as $P cat $1 > $1)
fi
}


[ ! -z $D ] && list_and_pull $D
[ ! -z $F ] && list_and_pull $F

希望对您有所帮助。这个脚本也可以在 大意上找到。

典型的用法是

$ ./exec_out.sh -p com.example.myapplication -d databases

然后它会将你的 apps 数据库目录下的所有文件(即 /data/data/com.example.myapplication/databases)提取到工作目录中。

除了这个,我找不到别的工作:

adb shell
run-as package.name
cat /databases/databaseFileName.db > /sdcard/copiedDatabaseFileName.db
exit
exit
adb pull /sdcard/copiedDatabaseFileName.db /file/location/on/computer/

第一个出口是退出 run-as,第二个出口是退出 adb shell 以执行拉取操作。

将文件下载到本地计算机的方法要简单得多:

In your PC shell run:

adb -d shell 'run-as <package_name> cat /data/data/<package_name>/databases/<db_name>' > <local_file_name>

如果有人正在寻找另一个答案,可以用来检索 Database以及 Shared Preferences,然后按照下面的步骤:

在应用程序的 build.gradle文件中添加行

编译‘ com.amitshekhar.android: debug-db: 1.0.0’

现在,当你运行你的应用程序在 non-release模式,然后你的应用程序将自动打开8080端口从你的设备 IP address确保你的设备是通过 wifi连接,你的 laptop是共享相同的网络。现在只需访问网址

http://your_mobile_device_ip:8080/

监视数据库中的所有数据以及共享首选项。

如果任何人寻找从 调试应用程序提取数据库可以使用下面的程序:

  1. 搜索和打开设备文件资源管理器

search and open device file explorer

  1. 选择您的手机,然后浏览到 data/data目录

go to data/data directory

  1. 现在找到您的应用程序包并转到数据库文件夹。您可以在那里看到数据库,右键单击即可获得选项 把这个保存到你的硬盘里。

enter image description here

#!/bin/bash
#export for adb
export PATH=$PATH:/Users/userMe/Library/Android/sdk/platform-tools
export PATH=$PATH:/Users/userMe/Library/Android/sdk/tools


adb -d shell 'run-as com.android.app  cp /data/data/com.android.app/files/db.realm /sdcard'
adb pull sdcard/db.realm /Users/userMe/Desktop/db

您可以使用这个脚本来获取域数据库。

使用 adb run-as时,数据库文件为 空虚。这可以通过在 RoomDatabase 实例上调用 close ()来解决。调用 close ()让 SQLite 将其日志写入磁盘。 I've created this button that closes the database connection on request:

via GIPHY

下面是如何在 RoomDatabase 实例上调用 close

Steps to pull app db(installed in debug mode) from device

如果打开数据库连接,则关闭数据库连接

Open cmd (command prompt) (Change dir to your adb path)

Cd C: Program Files (x86) Android Android-sdk Platform-tools

(list the app files)

Adb-d shell“ run-as com.xyz.name ls /资料/资料/ com.xyz.name/files/" ;

(copy required file to sdcard)

Adb-d shell“ run-as com.xyz.name cp /data/data/ com.xyz.name/files/abc.db /sdcard/abc.db”

(从 sdcard 复制到机器 adb 文件夹)

Adb pull/sdcard/abc.db

打开数据库连接

目标文件路径在我的案例 C: 用户{ userName } AppData 本地虚拟存储程序文件(x86) Android Android-sdk Platform-tools 或设备存储