Simple script brings back nonesense error - android

I have been trying to make a shell script for android that removes certain files to harden the device slightly against attack. This script has worked on an android emulator on ubuntu running froyo i think. when i try to run it on a windows box running 4.2 it brings up the error at the bottom. I have checked all the directories and they exist. I am running this using the adb.
echo ANDROID
echo HARDENING STARTED
#removing files in the /system/xbin directory
mount -o rw,remount /dev/block/mdblock0 /system
rm /system/xbin/tcpdump
rm /system/xbin/su
#removing files in the /system/bin directory
rm /system/bin/bootanimation
rm /system/bin/dumpstate
rm /system/bin/ping
rm /system/bin/ping6
mount -o ro,remount /dev/block/mdblock0 /system
echo ANDROID
echo HARDENING COMPLETE
Brings back this error.. I have no idea whats going on.
ANDROID
HARDENING STARTED
mount:No such file or directory
, No such file or directorytcpdump
, No such file or directorysu
, No such file or directoryootanimation
, No such file or directoryumpstate
, No such file or directorying
, No such file or directorying6
mount:No such file or directory
ANDROID
HARDENING COMPLETE
PLEASE HELP
Ryan

The directory /system does not exists, so your mount command fails.
Next you try to delete a couple of files from the non-existing and thus not mounted /system directory, which result in more errors.
Finally, you try to remount the /system, which still does not exists, resulting in your last error.
Only thing is that the errors messages are a bit garbled, the filenames are overwritten by the message somehow.
Edit: To answer your additional question...
If you can check if the file exists you can handle this situation properly (instead of using wildcards):
# Check which device to use
if [ -e /dev/block/mdblock0 ]; then
device=/dev/block/mdblock0
elif [ -e /dev/block/mtdblock0 ]; then
device=/dev/block/mtdblock0
else
echo "Device not found";
exit 1;
fi
mount -o rw,remount $device /system
# etc...
I do not know the exact Android shell commands, but assuming it is quite similar to bash this should work.

Change the line ending to Unix style, will solve all your problem.

Related

Edit an app SharedPreferences [duplicate]

Attempting to pull a single file using
adb pull /data/data/com.corp.appName/files/myFile.txt myFile.txt
fails with
failed to copy '/data/data/com.corp.appName/files/myFile.txt myFile.txt' to 'myFile.txt': Permission denied
despite that USB debugging is enabled on the device.
We can go around the problem through the archaic route
adb shell
run-as com.corp.appName
cat files/myFile.txt > myFile.txt
but this is unwieldy for more than one file.
How can I pull the directory /data/data/com.corp.appName/files to my MacBook?
Doing this either directly or through a transit in `/storage/sdcard0/myDir (from where I can continue with Android File Transfer) is fine.
Additional Comment
It may be that just running
adb backup -f myFiles com.corp.appName
will generate the files I am looking for. In that case I am looking for a way to untar/unzip the resulting backup!
adb backup will write an Android-specific archive:
adb backup -f myAndroidBackup.ab com.corp.appName
This archive can be converted to tar format using:
dd if=myAndroidBackup.ab bs=4K iflag=skip_bytes skip=24 | openssl zlib -d > myAndroidBackup.tar
Reference:
http://nelenkov.blogspot.ca/2012/06/unpacking-android-backups.html
Search for "Update" at that link.
Alternatively, use Android backup extractor to extract files from the Android backup (.ab) file.
I had the same problem but solved it running following:
$ adb shell
$ run-as {app-package-name}
$ cd /data/data/{app-package-name}
$ chmod 777 {file}
$ cp {file} /mnt/sdcard/
After this you can run
$ adb pull /mnt/sdcard/{file}
Here is what worked for me:
adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db
I'm printing the database directly into local file.
On MacOSX, by combining the answers from Calaf and Ollie Ford, the following worked for me.
On the command line (be sure adb is in your path, mine was at ~/Library/Android/sdk/platform-tools/adb) and with your android device plugged in and in USB debugging mode, run:
adb backup -f backup com.mypackage.myapp
Your android device will ask you for permission to backup your data. Select "BACKUP MY DATA"
Wait a few moments.
The file backup will appear in the directory where you ran adb.
Now run:
dd if=backup bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar
Now you'll you have a backup.tar file you can untar like this:
tar xvf backup.tar
And see all the files stored by your application.
Newer versions of Android Studio include the Device File Explorer which I've found to be a handy GUI method of downloading files from my development Nexus 7.
You Must make sure you have enabled USB Debugging on the device
Click View > Tool Windows > Device File Explorer or click the Device File Explorer button in the tool window bar to open the Device File Explorer.
Select a device from the drop down list.
Interact with the device content in the file explorer window. Right-click on a file or directory to create a new file or directory, save the selected file or directory to your machine, upload, delete, or synchronize. Double-click a file to open it in Android Studio.
Android Studio saves files you open this way in a temporary directory outside of your project. If you make modifications to a file you opened using the Device File Explorer, and would like to save your changes back to the device, you must manually upload the modified version of the file to the device.
Full Documentation
You may use this shell script below. It is able to pull files from app cache as well, not like the adb backup tool:
#!/bin/sh
if [ -z "$1" ]; then
echo "Sorry script requires an argument for the file you want to pull."
exit 1
fi
adb shell "run-as com.corp.appName cat '/data/data/com.corp.appNamepp/$1' > '/sdcard/$1'"
adb pull "/sdcard/$1"
adb shell "rm '/sdcard/$1'"
Then you can use it like this:
./pull.sh files/myFile.txt
./pull.sh cache/someCachedData.txt
If you are using a Mac machine and a Samsung phone, this is what you have to do (since run-as doesn't work on Samsung and zlib doesn't work on Mac)
Take a backup of your app's data directory
adb backup -f /Users/username/Desktop/data.ab com.example
You will be asked for a password to encrypt in your Phone, don't enter any. Just tap on "Back up my data". See How to take BackUp?
Once successfully backed up, you will see data.ab file in your Desktop. Now we need to convert this to tar format.
Use Android Backup Extractor for this. Download | SourceCode
Download it and you will see abe.jar file. Add this to your PATH variable.
Execute this to generate the tar file: java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar
Extract the data.tar file to access all the files
After setting the right permissions by adding the following code:
File myFile = ...;
myFile.setReadable(true, false); // readable, not only for the owner
adb pull works as desired.
see File.setReadable()
This answer is based on my experience with other answers, and comments in the answers. My hope is I can help someone in a similar situation.
I am doing this on OSX via terminal.
Previously Vinicius Avellar's answer worked great for me. I was only ever most of the time needing the database from the device from a debug application.
Today I had a use case where I needed multiple private files. I ended up with two solutions that worked good for this case.
Use the accepted answer along with Someone Somewhere's OSX specific comments. Create a backup and use the 3rd party solution,
sourceforge.net/projects/adbextractor/files/?source=navbar to unpack
into a tar. I'll write more about my experience with this solution at the bottom of this answer. Scroll down if
this is what you are looking for.
A faster solution which I settled with. I created a script for pulling multiple files similar to Tamas' answer. I am able to do it
this way because my app is a debug app and I have access to run-as on
my device. If you don't have access to run-as this method won't work
for you on OSX.
Here is my script for pulling multiple private files that I'll share with you, the reader, who is also investigating this awesome question ;) :
#!/bin/bash
#
# Strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
#
# Usage: script -f fileToPull -p packageName
#
# This script is for pulling private files from an Android device
# using run-as. Note: not all devices have run-as access, and
# application must be a debug version for run-as to work.
#
# If run-as is deactivated on your device use one of the
# alternative methods here:
# http://stackoverflow.com/questions/15558353/how-can-one-pull-the-private-data-of-ones-own-android-app
#
# If you have encrypted backup files use:
# sourceforge.net/projects/adbextractor/files/?source=navbar
# From comments in the accepted answer in the above SO question
#
# If your files aren't encrypted use the accepted answer
# ( see comments and other answers for OSX compatibility )
#
# This script is open to expansions to allow selecting
# device used. Currently first selected device from
# adb shell will be used.
#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null
if [ $? -gt 0 ]; then
echo "No device connected to adb."
exit 1
fi
# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
case $opt in
f)
fileToPull=$OPTARG
;;
p)
packageName=$OPTARG
;;
esac
done;
# Block file arg from being blank
if [ -z "$fileToPull" ]; then
echo "Please specify file or folder to pull with -f argument"
exit 1
fi
# Block package name arg from being blank
if [ -z "$packageName" ]; then
echo "Please specify package name to run as when pulling file"
exit 1
fi
# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
echo "Package name $packageName does not exist on device"
exit 1
fi
# Check file exists and has permission with run-as
fileCheck=`adb shell "run-as $packageName ls $fileToPull"`
if [[ $fileCheck =~ "Permission denied" ]] || [[ $fileCheck =~ "No such file or directory" ]]; then
echo "Error: $fileCheck"
echo "With file -> $fileToPull"
exit 1
fi
# Function to pull private file
#
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function pull_private_file () {
mkdir -p `dirname $3`
echo -e "\033[0;35m***" >&2
echo -e "\033[0;36m Coping file $2 -> $3" >&2
echo -e "\033[0;35m***\033[0m" >&2
adb shell "run-as $1 cat $2" > $3
}
# Check if a file is a directory
#
# param 1 = directory to check
function is_file_dir() {
adb shell "if [ -d \"$1\" ]; then echo TRUE; fi"
}
# Check if a file is a symbolic link
#
# param 1 = directory to check
function is_file_symlink() {
adb shell "if [ -L \"$1\" ]; then echo TRUE; fi"
}
# recursively pull files from device connected to adb
#
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function recurse_pull_private_files() {
is_dir=`is_file_dir "$2"`
is_symlink=`is_file_symlink "$2"`
if [ -n "$is_dir" ]; then
files=`adb shell "run-as $1 ls \"$2\""`
# Handle the case where directory is a symbolic link
if [ -n "$is_symlink" ]; then
correctPath=`adb shell "run-as $1 ls -l \"$2\"" | sed 's/.*-> //' | tr -d '\r'`
files=`adb shell "run-as $1 ls \"$correctPath\""`
fi
for i in $files; do
# Android adds nasty carriage return that screws with bash vars
# This removes it. Otherwise weird behavior happens
fileName=`echo "$i" | tr -d '\r'`
nextFile="$2/$fileName"
nextOutput="$3/$fileName"
recurse_pull_private_files "$1" "$nextFile" "$nextOutput"
done
else
pull_private_file "$1" "$2" "$3"
fi
}
recurse_pull_private_files "$packageName" "$fileToPull" "`basename "$fileToPull"`"
Gist:
https://gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4
Back to method 1, decrypting a backup using Android Backup Extractor
Here are the steps I took on my Mac, and issues I came across:
First I queued up a backup ( and set a password to encrypt my backup, my device required it ):
adb backup -f myAndroidBackup.ab com.corp.appName
Second I downloaded just abe.jar from here: https://sourceforge.net/projects/adbextractor/files/abe.jar/download
Next I ran:
java -jar ./abe.jar unpack myAndroidBackup.ab myAndroidBackup.tar
At this point I got an error message. Because my archive is encrypted, java gave me an error that I needed to install some security policy libraries.
So I went to http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html and downloaded the security policy jars I needed. Now in my case the install instructions told me the wrong location to put the jar files. It says that the proper location is <java-home>/lib/security. I put them there first and still got the error message. So I investigated and on my Mac with Java 1.8 the correct place to put them was: <java-home>/jre/lib/security. I made sure to backup the original policy jars, and put them there. Vola I was able to enter a password with abe.jar and decrypt to a tar file.
Lastly I just ran ( after running previous command again )
tar xvf myAndroidBackup.tar
Now it is important to note that if you can just run-as and cat, it is much much faster. One, you only get the files you want and not the entire application. Two, the more files ( + encryption for me ) makes it slower to transfer. So knowing to do this way is important if you don't have run-as on OSX, but the script should be first goto for a debug application.
Mind you I just wrote it today and tested it a few times, so please notify me of any bugs!
Similar to Tamas's answer, here is a one-liner for Mac OS X to fetch all of the files for app with your.app.id from your device and save them to (in this case) ~/Desktop/your.app.id:
(
id=your.app.id &&
dest=~/Desktop &&
adb shell "run-as $id cp -r /data/data/$id /sdcard" &&
adb -d pull "/sdcard/$id" "$dest" &&
if [ -n "$id" ]; then adb shell "rm -rf /sdcard/$id"; fi
)
Exclude the -d to pull from emulator
Doesn't stomp your session variables
You can paste the whole block into Terminal.app (or remove newlines if desired)
Starting form Dave Thomas script I've been able to write my own solution to overcome 2 problems:
my backup was containing only the manifest file
binary files got with Dave Thomas where unreadable
This is my script, that copies app data to sdcard and then pull it
#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null
if [ $? -gt 0 ]; then
echo "No device connected to adb."
exit 1
fi
# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
case $opt in
f)
fileToPull=$OPTARG
;;
p)
packageName=$OPTARG
;;
esac
done;
# Block package name arg from being blank
if [ -z "$packageName" ]; then
echo "Please specify package name to run as when pulling file"
exit 1
fi
# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
echo "Package name $packageName does not exist on device"
exit 1
fi
adb shell "run-as $packageName cp -r /data/data/$packageName/ /sdcard/$packageName"
adb pull /sdcard/$packageName
adb shell rm -rf /sdcard/$packageName
Backed up Game data with apk. Nougat Oneplus 2.
**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
Does that mean that one could chmod the directory from world:--x to world:r-x long enough to be able to fetch the files?
Yes, exactly. Weirdly enough, you also need the file to have the x bit set. (at least on Android 2.3)
chmod 755 all the way down worked to copy a file (but you should revert permissions afterwards, if you plan to continue using the device).
you can do:
adb pull /storage/emulated/0/Android/data//

Can't mount system android : read file only [duplicate]

I recently rooted my Droid X and everything seems to be working perfectly. I made some changes to build.prop and when I do adb push build.prop /system/ I get the following error: failed to copy 'c:\build.prop' to '/system//build.prop': Read-only file system.
How can I fix this?
Not all phones and versions of android have things mounted the same.
Limiting options when remounting would be best.
Simply remount as rw (Read/Write):
# mount -o rw,remount /system
Once you are done making changes, remount to ro (read-only):
# mount -o ro,remount /system
adb remount
works for me and seems to be the simplest solution.
While I know the question is about the real device, in case someone got here with a similar issue in the emulator, with whatever tools are the latest as of Feb, 2017, the emulator needs to be launched from the command line with:
-writable-system
For anything to be writable to the /system. Without this flag no combination of remount or mount will allow one to write to /system.
After the emulator is launched with that flag, a single adb remount after adb root is sufficient to get permissions to push to /system.
Here's an example of the command line I use to run my emulator:
./emulator -writable-system -avd Nexus_5_API_25 -no-snapshot-load -qemu
The value for the -avd flags comes from:
./emulator -list-avds
Got this off an Android forum where I asked the same question. Hope this helps somebody else.
On a terminal emulator on the phone:
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
Then on the cmd prompt, do the adb push
I think the safest way is remounting the /system as read-write, using:
mount -o remount,rw /system
and when done, remount it as read-only:
mount -o remount,ro /system
adb disable-verity
adb reboot
adb root
adb remount
This works for me, and is the simplest solution.
On my Samsung galaxy mini S5570 (after got root on cellphone):
Fist, as root, I ran:
systemctl start adb
as a normal user:
adb shell
su
Grant root permissions on touch screen
mount
list all mount points that we have and we can see, in my case, that /dev/stl12 was mounted on /system as ro (ready only), so we just need do:
mount -o rw,remount /dev/stl12 /system
Try the following on the command prompt:
>adb remount
>adb push framework-res_old.apk /system/framework-res.apk
Here is what worked for me. I was running an emulated Android 7.1.1 (Nougat) device.
On a terminal, I hit the following command. One thing to be noticed is the -writable-system flag
./emulator -writable-system -avd Nexus_6_API_25 -partition-size 280
On another tab
./adb shell
su
mount -o rw,remount -t ext4 /dev/block/vda /system
All the changes that you do on the /system contents will survive a restart.
I checked with emulator and following worked.
adb reboot
adb root && adb remount && adb push ~/Desktop/hosts /system/etc/hosts
As mentioned above as well, execute second step in single shot.
Open terminal emulator on the phone:
then
adb shell
after that daemon is started
su
mount -o rw,remount /mnt/sdcard
then the read only is converted into the read-Write.
Sometimes you get the error because the destination location in phone are not exist. For example, some android phone external storage location is /storage/emulated/legacy instead of /storage/emulated/0.
mount -o rw,remount /dev/stl12 /system
works for me
This worked for me
#Mount as ReadOnly
su -c "mount -o rw,remount /system"
# Change Permission for file
su -c "chmod 777 /system/build.prop"
#Edit the file to add the property
su -c "busybox vi /system/build.prop"
# Add now
service.adb.tcp.port=5678
# Reset old permissions
su -c "chmod 644 /system/build.prop"
# Mount as readonly again once done
su -c "mount -o ro,remount /system"
I found this article from google, and thought I'd add the steps necessary on a Sony Xperia Z (4.2.2).
The Sony has a watchdog process which detects when you've changed ro to rw on / and /system (these are the only ones I was trying to modify) and possibly others.
The following was what I ran to perform the changes I was trying to achieve. I pasted these into a window, because removing the execute bit from /sbin/ric needs to be done quickly in order to stop it restarting itself. (I tried stop ric; this doesn't work - although it worked on a previous version of android on the phone).
pkill -9 ric; mount -o rw,remount -t rootfs /
chmod 640 /sbin/ric
mount -o rw,remount /system
I modified the hosts file here, so this is the place you make the changes you need to the filesystem. To leave things the way we found them, do this:
mount -o ro,remount /system
chmod 750 /sbin/ric
mount -o ro,remount -t rootfs /
At which point ric should automatically restart. (It restarted for me automatically.)
Adding a little bit more to Jan Bergström's answer: Because Android is a Linux based system, and the path in Linux contains forward slashes(../), while using push command, use "/" to define destination path in the Android device.
For Example, the command goes: adb push C:\Users\admin\Desktop\1.JPG sdcard/pictures/
Notice that here, back slashes are used to define source path of the file to be pushed from windows PC and forward slashes are used to define destination path because Android is a Linux based system. You don't have to act as a root to use this command and also, it works perfectly fine on production devices.
Thanks, Sérgio, for "mount" command without parameters idea.
I'd need to made adb push into /data/data/com.my.app/lib for some test issue, and get "Read-only filesystem" message.
ls command shows me:
root#android:/ # ls -l /data/data/com.my.app/
drwxrwx--x u0_a98 u0_a98 2016-05-06 09:16 cache
drwxrwx--x u0_a98 u0_a98 2016-05-06 09:04 files
lrwxrwxrwx system system 2016-05-06 11:43 lib -> /mnt/asec/com.my.app-1/lib
So, it's understood, that "lib" directory is separated from other application directories.
Command
mount -o rw,remount /mnt/asec
didn't resolve "r/o fs" issue, it wants device parameter before directory parameter.
"df" command didn't help also, but shows that my /mnt/asec/com.my.app-1 directory is at the separate mount point.
Then I looks by mount and voila!
root#android:/ # mount
.........
/dev/block/dm-4 /mnt/asec/com.my.app-1 ext4 ro,dirsync,relatime 0 0
Next steps are already described upwards: remount to RW, push and remount back to RO.
it sames that must extract and repack initrc.img and edit init file with the code of mount /system
Copy files to the SD-card?
Well, I assume you like to copy data to the Sd-card from the developers computer? You might have rooted the devise and made the area you address available?) I had about the same problem to upload data files for my application(Android Studio 1.3.2 in Win7), but.
First the adb command-shell has to be found in th path:
PATH=%PATH%;C:\Users\XXXXX\AppData\Local\Android\sdk\platform-tools (the folder AppData is hidden, so you have to set the folder setup not hiding concealed files and folder to find it, Path works regardless)
You have to spell the folder path right or you get a read-only error message, most likely it must start with /sdcard or it is read only area. As soon as I did no problem pushing the file to the emulator.
So for instance the the adb command can look like this:
adb push C:\testdata\t.txt /sdcard/download/t.txt
If there's a failure in copying the read-only file you can try locating the original file in the root directory and modify it with a root text editor (preferably) RB text editor, it comes with ROM Toolbox app.
Try this in a Terminal Emulator as root:
restorecon -v -R /data/media
In my case I was using the command adb push ~/Desktop/file.txt ~/sdcard/
I changed it to ~/Desktop/file.txt /sdcard/ and then it worked.
Make sure to disconnect and reconnect the phone.
As chen-xing mentioned the simplest way is:
adb reboot
But for me I had to change my settings first:
Settings → Developer options → Root access
Make sure ADB has Root access:
I just only needed this:
su -c "mount -o rw,remount /system"

How can one pull the (private) data of one's own Android app?

Attempting to pull a single file using
adb pull /data/data/com.corp.appName/files/myFile.txt myFile.txt
fails with
failed to copy '/data/data/com.corp.appName/files/myFile.txt myFile.txt' to 'myFile.txt': Permission denied
despite that USB debugging is enabled on the device.
We can go around the problem through the archaic route
adb shell
run-as com.corp.appName
cat files/myFile.txt > myFile.txt
but this is unwieldy for more than one file.
How can I pull the directory /data/data/com.corp.appName/files to my MacBook?
Doing this either directly or through a transit in `/storage/sdcard0/myDir (from where I can continue with Android File Transfer) is fine.
Additional Comment
It may be that just running
adb backup -f myFiles com.corp.appName
will generate the files I am looking for. In that case I am looking for a way to untar/unzip the resulting backup!
adb backup will write an Android-specific archive:
adb backup -f myAndroidBackup.ab com.corp.appName
This archive can be converted to tar format using:
dd if=myAndroidBackup.ab bs=4K iflag=skip_bytes skip=24 | openssl zlib -d > myAndroidBackup.tar
Reference:
http://nelenkov.blogspot.ca/2012/06/unpacking-android-backups.html
Search for "Update" at that link.
Alternatively, use Android backup extractor to extract files from the Android backup (.ab) file.
I had the same problem but solved it running following:
$ adb shell
$ run-as {app-package-name}
$ cd /data/data/{app-package-name}
$ chmod 777 {file}
$ cp {file} /mnt/sdcard/
After this you can run
$ adb pull /mnt/sdcard/{file}
Here is what worked for me:
adb -d shell "run-as com.example.test cat /data/data/com.example.test/databases/data.db" > data.db
I'm printing the database directly into local file.
On MacOSX, by combining the answers from Calaf and Ollie Ford, the following worked for me.
On the command line (be sure adb is in your path, mine was at ~/Library/Android/sdk/platform-tools/adb) and with your android device plugged in and in USB debugging mode, run:
adb backup -f backup com.mypackage.myapp
Your android device will ask you for permission to backup your data. Select "BACKUP MY DATA"
Wait a few moments.
The file backup will appear in the directory where you ran adb.
Now run:
dd if=backup bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" > backup.tar
Now you'll you have a backup.tar file you can untar like this:
tar xvf backup.tar
And see all the files stored by your application.
Newer versions of Android Studio include the Device File Explorer which I've found to be a handy GUI method of downloading files from my development Nexus 7.
You Must make sure you have enabled USB Debugging on the device
Click View > Tool Windows > Device File Explorer or click the Device File Explorer button in the tool window bar to open the Device File Explorer.
Select a device from the drop down list.
Interact with the device content in the file explorer window. Right-click on a file or directory to create a new file or directory, save the selected file or directory to your machine, upload, delete, or synchronize. Double-click a file to open it in Android Studio.
Android Studio saves files you open this way in a temporary directory outside of your project. If you make modifications to a file you opened using the Device File Explorer, and would like to save your changes back to the device, you must manually upload the modified version of the file to the device.
Full Documentation
You may use this shell script below. It is able to pull files from app cache as well, not like the adb backup tool:
#!/bin/sh
if [ -z "$1" ]; then
echo "Sorry script requires an argument for the file you want to pull."
exit 1
fi
adb shell "run-as com.corp.appName cat '/data/data/com.corp.appNamepp/$1' > '/sdcard/$1'"
adb pull "/sdcard/$1"
adb shell "rm '/sdcard/$1'"
Then you can use it like this:
./pull.sh files/myFile.txt
./pull.sh cache/someCachedData.txt
If you are using a Mac machine and a Samsung phone, this is what you have to do (since run-as doesn't work on Samsung and zlib doesn't work on Mac)
Take a backup of your app's data directory
adb backup -f /Users/username/Desktop/data.ab com.example
You will be asked for a password to encrypt in your Phone, don't enter any. Just tap on "Back up my data". See How to take BackUp?
Once successfully backed up, you will see data.ab file in your Desktop. Now we need to convert this to tar format.
Use Android Backup Extractor for this. Download | SourceCode
Download it and you will see abe.jar file. Add this to your PATH variable.
Execute this to generate the tar file: java -jar abe.jar unpack /Users/username/Desktop/data.ab /Users/username/Desktop/data.tar
Extract the data.tar file to access all the files
After setting the right permissions by adding the following code:
File myFile = ...;
myFile.setReadable(true, false); // readable, not only for the owner
adb pull works as desired.
see File.setReadable()
This answer is based on my experience with other answers, and comments in the answers. My hope is I can help someone in a similar situation.
I am doing this on OSX via terminal.
Previously Vinicius Avellar's answer worked great for me. I was only ever most of the time needing the database from the device from a debug application.
Today I had a use case where I needed multiple private files. I ended up with two solutions that worked good for this case.
Use the accepted answer along with Someone Somewhere's OSX specific comments. Create a backup and use the 3rd party solution,
sourceforge.net/projects/adbextractor/files/?source=navbar to unpack
into a tar. I'll write more about my experience with this solution at the bottom of this answer. Scroll down if
this is what you are looking for.
A faster solution which I settled with. I created a script for pulling multiple files similar to Tamas' answer. I am able to do it
this way because my app is a debug app and I have access to run-as on
my device. If you don't have access to run-as this method won't work
for you on OSX.
Here is my script for pulling multiple private files that I'll share with you, the reader, who is also investigating this awesome question ;) :
#!/bin/bash
#
# Strict mode: http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
#
# Usage: script -f fileToPull -p packageName
#
# This script is for pulling private files from an Android device
# using run-as. Note: not all devices have run-as access, and
# application must be a debug version for run-as to work.
#
# If run-as is deactivated on your device use one of the
# alternative methods here:
# http://stackoverflow.com/questions/15558353/how-can-one-pull-the-private-data-of-ones-own-android-app
#
# If you have encrypted backup files use:
# sourceforge.net/projects/adbextractor/files/?source=navbar
# From comments in the accepted answer in the above SO question
#
# If your files aren't encrypted use the accepted answer
# ( see comments and other answers for OSX compatibility )
#
# This script is open to expansions to allow selecting
# device used. Currently first selected device from
# adb shell will be used.
#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null
if [ $? -gt 0 ]; then
echo "No device connected to adb."
exit 1
fi
# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
case $opt in
f)
fileToPull=$OPTARG
;;
p)
packageName=$OPTARG
;;
esac
done;
# Block file arg from being blank
if [ -z "$fileToPull" ]; then
echo "Please specify file or folder to pull with -f argument"
exit 1
fi
# Block package name arg from being blank
if [ -z "$packageName" ]; then
echo "Please specify package name to run as when pulling file"
exit 1
fi
# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
echo "Package name $packageName does not exist on device"
exit 1
fi
# Check file exists and has permission with run-as
fileCheck=`adb shell "run-as $packageName ls $fileToPull"`
if [[ $fileCheck =~ "Permission denied" ]] || [[ $fileCheck =~ "No such file or directory" ]]; then
echo "Error: $fileCheck"
echo "With file -> $fileToPull"
exit 1
fi
# Function to pull private file
#
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function pull_private_file () {
mkdir -p `dirname $3`
echo -e "\033[0;35m***" >&2
echo -e "\033[0;36m Coping file $2 -> $3" >&2
echo -e "\033[0;35m***\033[0m" >&2
adb shell "run-as $1 cat $2" > $3
}
# Check if a file is a directory
#
# param 1 = directory to check
function is_file_dir() {
adb shell "if [ -d \"$1\" ]; then echo TRUE; fi"
}
# Check if a file is a symbolic link
#
# param 1 = directory to check
function is_file_symlink() {
adb shell "if [ -L \"$1\" ]; then echo TRUE; fi"
}
# recursively pull files from device connected to adb
#
# param 1 = package name
# param 2 = file to pull
# param 3 = output file
function recurse_pull_private_files() {
is_dir=`is_file_dir "$2"`
is_symlink=`is_file_symlink "$2"`
if [ -n "$is_dir" ]; then
files=`adb shell "run-as $1 ls \"$2\""`
# Handle the case where directory is a symbolic link
if [ -n "$is_symlink" ]; then
correctPath=`adb shell "run-as $1 ls -l \"$2\"" | sed 's/.*-> //' | tr -d '\r'`
files=`adb shell "run-as $1 ls \"$correctPath\""`
fi
for i in $files; do
# Android adds nasty carriage return that screws with bash vars
# This removes it. Otherwise weird behavior happens
fileName=`echo "$i" | tr -d '\r'`
nextFile="$2/$fileName"
nextOutput="$3/$fileName"
recurse_pull_private_files "$1" "$nextFile" "$nextOutput"
done
else
pull_private_file "$1" "$2" "$3"
fi
}
recurse_pull_private_files "$packageName" "$fileToPull" "`basename "$fileToPull"`"
Gist:
https://gist.github.com/davethomas11/6c88f92c6221ffe6bc26de7335107dd4
Back to method 1, decrypting a backup using Android Backup Extractor
Here are the steps I took on my Mac, and issues I came across:
First I queued up a backup ( and set a password to encrypt my backup, my device required it ):
adb backup -f myAndroidBackup.ab com.corp.appName
Second I downloaded just abe.jar from here: https://sourceforge.net/projects/adbextractor/files/abe.jar/download
Next I ran:
java -jar ./abe.jar unpack myAndroidBackup.ab myAndroidBackup.tar
At this point I got an error message. Because my archive is encrypted, java gave me an error that I needed to install some security policy libraries.
So I went to http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html and downloaded the security policy jars I needed. Now in my case the install instructions told me the wrong location to put the jar files. It says that the proper location is <java-home>/lib/security. I put them there first and still got the error message. So I investigated and on my Mac with Java 1.8 the correct place to put them was: <java-home>/jre/lib/security. I made sure to backup the original policy jars, and put them there. Vola I was able to enter a password with abe.jar and decrypt to a tar file.
Lastly I just ran ( after running previous command again )
tar xvf myAndroidBackup.tar
Now it is important to note that if you can just run-as and cat, it is much much faster. One, you only get the files you want and not the entire application. Two, the more files ( + encryption for me ) makes it slower to transfer. So knowing to do this way is important if you don't have run-as on OSX, but the script should be first goto for a debug application.
Mind you I just wrote it today and tested it a few times, so please notify me of any bugs!
Similar to Tamas's answer, here is a one-liner for Mac OS X to fetch all of the files for app with your.app.id from your device and save them to (in this case) ~/Desktop/your.app.id:
(
id=your.app.id &&
dest=~/Desktop &&
adb shell "run-as $id cp -r /data/data/$id /sdcard" &&
adb -d pull "/sdcard/$id" "$dest" &&
if [ -n "$id" ]; then adb shell "rm -rf /sdcard/$id"; fi
)
Exclude the -d to pull from emulator
Doesn't stomp your session variables
You can paste the whole block into Terminal.app (or remove newlines if desired)
Starting form Dave Thomas script I've been able to write my own solution to overcome 2 problems:
my backup was containing only the manifest file
binary files got with Dave Thomas where unreadable
This is my script, that copies app data to sdcard and then pull it
#Check we have one connected device
adb devices -l | grep -e 'device\b' > /dev/null
if [ $? -gt 0 ]; then
echo "No device connected to adb."
exit 1
fi
# Set filename or directory to pull from device
# Set package name we will run as
while getopts f:p: opt; do
case $opt in
f)
fileToPull=$OPTARG
;;
p)
packageName=$OPTARG
;;
esac
done;
# Block package name arg from being blank
if [ -z "$packageName" ]; then
echo "Please specify package name to run as when pulling file"
exit 1
fi
# Check package exists
adb shell pm list packages | grep "$packageName" > /dev/null
if [ $? -gt 0 ]; then
echo "Package name $packageName does not exist on device"
exit 1
fi
adb shell "run-as $packageName cp -r /data/data/$packageName/ /sdcard/$packageName"
adb pull /sdcard/$packageName
adb shell rm -rf /sdcard/$packageName
Backed up Game data with apk. Nougat Oneplus 2.
**adb backup "-apk com.nekki.shadowfight" -f "c:\myapk\samsung2.ab"**
Does that mean that one could chmod the directory from world:--x to world:r-x long enough to be able to fetch the files?
Yes, exactly. Weirdly enough, you also need the file to have the x bit set. (at least on Android 2.3)
chmod 755 all the way down worked to copy a file (but you should revert permissions afterwards, if you plan to continue using the device).
you can do:
adb pull /storage/emulated/0/Android/data//

script running through too fast! possibly

I have been attempting to write a script to harden android. I have had no success!
I am running a AVD via emulator and have tried this with both the android shell and bash shell which i loaded. The script is simple as you will see below and each command runs fine independently but in a script it just runs through too fast or something.
I know there's no shebang at the top but that's because of errors when i inserted one.
my script is:
echo ANDROID
echo HARDENING STARTED
device=/dev/block/mtdblock0
mount -o rw,remount $device /system
#removing files in the /system/xbin directory
rm /system/xbin/tcpdump
rm /system/xbin/su
#removing files in the /system/bin directory
rm /system/bin/bootanimation
rm /system/bin/dumpstate
rm /system/bin/ping
rm /system/bin/ping6
echo ANDROID
echo HARDENING COMPLETE
I have taken all indenting out as i thought this may be causing the error and the directories and files definitely exist. I have been on this for three days now and its wearing thin.
I had an if statement at the beginning to select devices on other handsets but i took this out in attempt to reduce errors (that's why i declare device instead of mounting).
here is the error:
ANDROID
HARDENING STARTED
mount: no such file or directory exist
, no such file or directorytcpdump
, no such file or directorysu
, no such file or directoryootanimation
, no such file or directoryumpstate
, no such file or directorying
, no such file or directorying6
ANDROID
HARDENING COMPLETED
NOTICE THE MERGING AFTER DIRECTORY THIS IS NOT A TYPO.
thanks Ryan
You edited this file on a Windows system and it has DOS-style end-of-lines (<cr><lf>). Convert it to use Unix-style end-of-line markers (<lf>) and it should work fine. Any decent programmer's editor will have the ability to do this for you, or you can do it using standard command line tools.
Incidentally, the shell doesn't care about indenting at all. This:
echo Hello
echo world.
Is the same as:
echo Hello
echo world.
Change the line ending to Unix style, will solve all your problem.

Read only file system on Android

I recently rooted my Droid X and everything seems to be working perfectly. I made some changes to build.prop and when I do adb push build.prop /system/ I get the following error: failed to copy 'c:\build.prop' to '/system//build.prop': Read-only file system.
How can I fix this?
Not all phones and versions of android have things mounted the same.
Limiting options when remounting would be best.
Simply remount as rw (Read/Write):
# mount -o rw,remount /system
Once you are done making changes, remount to ro (read-only):
# mount -o ro,remount /system
adb remount
works for me and seems to be the simplest solution.
While I know the question is about the real device, in case someone got here with a similar issue in the emulator, with whatever tools are the latest as of Feb, 2017, the emulator needs to be launched from the command line with:
-writable-system
For anything to be writable to the /system. Without this flag no combination of remount or mount will allow one to write to /system.
After the emulator is launched with that flag, a single adb remount after adb root is sufficient to get permissions to push to /system.
Here's an example of the command line I use to run my emulator:
./emulator -writable-system -avd Nexus_5_API_25 -no-snapshot-load -qemu
The value for the -avd flags comes from:
./emulator -list-avds
Got this off an Android forum where I asked the same question. Hope this helps somebody else.
On a terminal emulator on the phone:
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
Then on the cmd prompt, do the adb push
I think the safest way is remounting the /system as read-write, using:
mount -o remount,rw /system
and when done, remount it as read-only:
mount -o remount,ro /system
adb disable-verity
adb reboot
adb root
adb remount
This works for me, and is the simplest solution.
On my Samsung galaxy mini S5570 (after got root on cellphone):
Fist, as root, I ran:
systemctl start adb
as a normal user:
adb shell
su
Grant root permissions on touch screen
mount
list all mount points that we have and we can see, in my case, that /dev/stl12 was mounted on /system as ro (ready only), so we just need do:
mount -o rw,remount /dev/stl12 /system
Try the following on the command prompt:
>adb remount
>adb push framework-res_old.apk /system/framework-res.apk
Here is what worked for me. I was running an emulated Android 7.1.1 (Nougat) device.
On a terminal, I hit the following command. One thing to be noticed is the -writable-system flag
./emulator -writable-system -avd Nexus_6_API_25 -partition-size 280
On another tab
./adb shell
su
mount -o rw,remount -t ext4 /dev/block/vda /system
All the changes that you do on the /system contents will survive a restart.
I checked with emulator and following worked.
adb reboot
adb root && adb remount && adb push ~/Desktop/hosts /system/etc/hosts
As mentioned above as well, execute second step in single shot.
Open terminal emulator on the phone:
then
adb shell
after that daemon is started
su
mount -o rw,remount /mnt/sdcard
then the read only is converted into the read-Write.
Sometimes you get the error because the destination location in phone are not exist. For example, some android phone external storage location is /storage/emulated/legacy instead of /storage/emulated/0.
mount -o rw,remount /dev/stl12 /system
works for me
This worked for me
#Mount as ReadOnly
su -c "mount -o rw,remount /system"
# Change Permission for file
su -c "chmod 777 /system/build.prop"
#Edit the file to add the property
su -c "busybox vi /system/build.prop"
# Add now
service.adb.tcp.port=5678
# Reset old permissions
su -c "chmod 644 /system/build.prop"
# Mount as readonly again once done
su -c "mount -o ro,remount /system"
I found this article from google, and thought I'd add the steps necessary on a Sony Xperia Z (4.2.2).
The Sony has a watchdog process which detects when you've changed ro to rw on / and /system (these are the only ones I was trying to modify) and possibly others.
The following was what I ran to perform the changes I was trying to achieve. I pasted these into a window, because removing the execute bit from /sbin/ric needs to be done quickly in order to stop it restarting itself. (I tried stop ric; this doesn't work - although it worked on a previous version of android on the phone).
pkill -9 ric; mount -o rw,remount -t rootfs /
chmod 640 /sbin/ric
mount -o rw,remount /system
I modified the hosts file here, so this is the place you make the changes you need to the filesystem. To leave things the way we found them, do this:
mount -o ro,remount /system
chmod 750 /sbin/ric
mount -o ro,remount -t rootfs /
At which point ric should automatically restart. (It restarted for me automatically.)
Adding a little bit more to Jan Bergström's answer: Because Android is a Linux based system, and the path in Linux contains forward slashes(../), while using push command, use "/" to define destination path in the Android device.
For Example, the command goes: adb push C:\Users\admin\Desktop\1.JPG sdcard/pictures/
Notice that here, back slashes are used to define source path of the file to be pushed from windows PC and forward slashes are used to define destination path because Android is a Linux based system. You don't have to act as a root to use this command and also, it works perfectly fine on production devices.
Thanks, Sérgio, for "mount" command without parameters idea.
I'd need to made adb push into /data/data/com.my.app/lib for some test issue, and get "Read-only filesystem" message.
ls command shows me:
root#android:/ # ls -l /data/data/com.my.app/
drwxrwx--x u0_a98 u0_a98 2016-05-06 09:16 cache
drwxrwx--x u0_a98 u0_a98 2016-05-06 09:04 files
lrwxrwxrwx system system 2016-05-06 11:43 lib -> /mnt/asec/com.my.app-1/lib
So, it's understood, that "lib" directory is separated from other application directories.
Command
mount -o rw,remount /mnt/asec
didn't resolve "r/o fs" issue, it wants device parameter before directory parameter.
"df" command didn't help also, but shows that my /mnt/asec/com.my.app-1 directory is at the separate mount point.
Then I looks by mount and voila!
root#android:/ # mount
.........
/dev/block/dm-4 /mnt/asec/com.my.app-1 ext4 ro,dirsync,relatime 0 0
Next steps are already described upwards: remount to RW, push and remount back to RO.
it sames that must extract and repack initrc.img and edit init file with the code of mount /system
Copy files to the SD-card?
Well, I assume you like to copy data to the Sd-card from the developers computer? You might have rooted the devise and made the area you address available?) I had about the same problem to upload data files for my application(Android Studio 1.3.2 in Win7), but.
First the adb command-shell has to be found in th path:
PATH=%PATH%;C:\Users\XXXXX\AppData\Local\Android\sdk\platform-tools (the folder AppData is hidden, so you have to set the folder setup not hiding concealed files and folder to find it, Path works regardless)
You have to spell the folder path right or you get a read-only error message, most likely it must start with /sdcard or it is read only area. As soon as I did no problem pushing the file to the emulator.
So for instance the the adb command can look like this:
adb push C:\testdata\t.txt /sdcard/download/t.txt
If there's a failure in copying the read-only file you can try locating the original file in the root directory and modify it with a root text editor (preferably) RB text editor, it comes with ROM Toolbox app.
Try this in a Terminal Emulator as root:
restorecon -v -R /data/media
In my case I was using the command adb push ~/Desktop/file.txt ~/sdcard/
I changed it to ~/Desktop/file.txt /sdcard/ and then it worked.
Make sure to disconnect and reconnect the phone.
As chen-xing mentioned the simplest way is:
adb reboot
But for me I had to change my settings first:
Settings → Developer options → Root access
Make sure ADB has Root access:
I just only needed this:
su -c "mount -o rw,remount /system"

Categories

Resources