I'm writing an application that should modify some files it doesn't have access to: another application's database, default.prop, etc.
Currently, it is done with "su" request and temporary "chmod 0777" to required files. But I think that's not the best solution.
Is there any preferable way to do such operations?
And how, for example, I should check if shell commands (chown, chmod, grep, find) are supported by toolbox (if there's not busybox)?
Related
I recently jumped into an android development tutorials and doing my own app for the sake of learning. I want to get root permissions within my code in a proper way. So not by calling /system/xbin/su but by using something like seteuid(0). Unfortunately seteuid method does not work for me.
I am testing app on a real device, which I rooted, enabled debugging mode and well I clearly see that when using a call to /system/xbin/su my app requests root permissions from system, which does not happen with seteuid and seteguid (setuid and setguid do not work either but I would not expect those to do it as they are capable only in lowering the permissions).
Please, advice on where to look for a proper code implementation for requesting root permissions like it would do a top notch developer. Maybe some native api call? Or does everyone just use a call to su to get the needed access?
The usual way in Linux of elevating privileges -- that is, to run an application with greater privileges than the logged-in user -- is to set the SUID flag on the executable (e.g., chmod ug+s ...). This will make the process take the identity of the binary's owner (usually root), rather than the logged-in user.
This is tricky to do effectively on Android, even on a rooted device. First, you won't be able to install an app using the usual (APK) mechanisms that includes binaries with SUID permissions. Second, an Android app is not an executable in the usual sense -- a single executable handles the launching of all apps.
Still, if you want to experiment on the command line, it should be possible to set the SUID flag on binaries, in at least some filesystem locations.
If you have a rooted Android, then very likely there is some infrastructure already in place to control privilege elevation. Most likely the "su" command will work (because there will be kernel mods to make it work), and it will be provided either with credentials or with some other way to control which apps can use it. I believe that, as you suggest, calling "su" is the usual way to do privilege elevation in apps on rooted Android. It is fraught with difficulties, however. There's a document https://su.chainfire.eu/ that explains how "su" is typically implemented in rooted Android devices, and gives some guidance on how to use it properly.
Just in case posting my solution to the problem which I did in Java (no native code is needed here):
protected void hideRoot() throws IOException, InterruptedException {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream dos = new DataOutputStream(p.getOutputStream());
dos.writeBytes("mount -o remount,rw /system\n");
dos.writeBytes("mv /system/xbin/su /system/xbin/suhidden\n");
dos.writeBytes("exit\n");
dos.flush();
p.waitFor();
}
I have an app in Android that needs to modify the private databases of other apps using root. The current method works on all devices up to and including Lollypop, but seems to fail on Marshmallow devices due to SELinux.
To modify databases, the app does the following:
From root:
Copy target database to my app's folder preserving permissions and ownership (cp -p)
Change permissions (chmod 777)
From app, use SQLiteDatabase class to open database and execute queries
From root
Move back database and restore permissions
However, on Marshmallow, attempting to open the copied database with SQLiteDatabase fails and yields the follow AVC denial:
avc: denied { open } for path="/data/data/<my app package>/cache/<database>.db" dev="dm-0" ino=509488 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0
The only thing I've tried is running chcon u:r:untrusted_app:s0 on the file as root, but it says permission denied.
Additionally, from what I've read here: https://source.android.com/security/selinux/, it appears that SELinux was set to enforcing mode in the 5.0 release, so how come this is only an issue now on 6.0 but wasn't on 5.0?
I have just completed something like this for one of my apps so it works on Android 7 on a Pixel device.
Like you, I copy the original database files to my app's location. Then I not only chmod them but I also chown/chgrp them to my app's uid. Finally, I chcon the database files to the context found for them in their original location. I am then able to access and manipulate them via SqliteDatabase classes in my app.
Once I am finished, I move the database files back to their original location, chown/chgrp them back to the owning app's uid, and restorecon them.
This is a giant pain. But it seems to work in my limited testing so far. But beware that in later versions of Android the toolbox commands seem to have been replaced with toybox commands and this really impacts the chown/chgrp. Toolbox versions allow changing of owner and group in the same command. Toybox does not so you must issue both chown and chgrp commands.
There may be other command changes as well. for example, on the Pixel, the grep command is now a stand-alone binary and NOT a part of toolbox or toybox.
you can turn off the enforcing mode and move to permissive mode using adb shell su 0 setenforce 0 through code.
In permissive mode you are allowed do to do whatever you would do on normal phone without SELinux.
Once the enforcing mode is turned off you can do whatever you were doing before.
i'm trying to access my database file from adb shell, but sqlite3 cant open it, i think this is because i dont have root, searching on the web i found that to get root acess you need to:
adb root ->adbd is restarted as root(dont really know what is this)
adb connect <device>
adb -s <device> shell
this commands work fine here, but i still cant get root access and still cant acess my database file
The error i'm getting is:
Error: unable to open database "ClientsInfoDB.db": unable to open database file 1
on my app code to create the database i use:
public DatabaseHelper(Context context){
super(context, "ClientsInfoDB", null, 2);
can anyone help me here?
thanks for attention
EDITED ---
Important informations that was missing(sorry for that :s): i'm using Blluestacks to run my app
To access the app directory i did(on the shell):
cd data/data/<my_package_name>/databases
ls --> wont work
sqlite3 ClientsInfoDB
.databases --> message error that i posted above
If you're using a standard version of Android (i.e. not AOSP) you won't be able to get root by default. The steps for rooting the phone vary based on manufacturer and version and sometimes you can find instructions online. That said, it's not something that is officially supported and may damage your phone.
That said, without doing that, you can't access your application's database without root because the data directory for your application is restricted to your application only. If you need to access it, try having your application store the database somewhere like the /sdcard or equivalent directory which is generally accessible. The downside to this is that any application can access it, so be careful what you put there in production.
I want to copy some files from it's own data folder(e.g. "/data/data/com.example.copy/") to "/data/local/tmp/". I can't access /data/local/tmp/ in my app. Is it possible to do it?
I don't have root access on my device.
Here's my code:
Process p=Runtime.getRuntime().exec("cat "+ this.getApplicationInfo().dataDir +"1.txt > /data/local/tmp/1.txt" );
p.waitFor();
No, you cannot do this from an application unless your device has something like a hacked su which lets you run a helper process as a more privileged user (ie, unless it is "rooted").
You should put the file somewhere else - such as the external storage. (If the adb shell is allowed to create directories under /data/local/tmp you might be able to create one there and chmod or chown it to give your app access, but that's non-portable across versions)
Or if you are merely trying to expose it, change the access permissions (someone will probably come along and point out the java constant for setting a file world readable is superficially deprecated, but actual disabling the capability would require a drastic change to the underlying operating system)
I have android device with root and i try to implement some small app. This app need to read files from /proc/pid/net . I made it with Runtime.getRuntime().exec(new String[] { "su", "-c", "cat /proc/"+PID+ "/net/tcp6" }); but I must accept su -permission for each pid. There are some other possibilities how i can to read system files in android from my app? Something with FileReader? How can I get the su-permissions without exec -commando?
The exec command IS how you get su permissions. You might be able to chmod 777 the files you want and then they can likely be read via java. That, or you could move the files you want to read to the sdcard, or your apps data location and read them from there. Here is something very useful for root. You won't have to manually use the exec command each time, but RootTools does still use exec.
I believe if you do something like:
Process p = Runtime.getRuntime().exec("su");
you will get the root access.
And then you can do just:
p.getRuntime().exec("command");
and then you won't have to put the su in as long as that process is still active.
Though, I haven't done what I explained above (with the process) in quite some time, so I may be wrong. You may still have to include su each time. But either way, I'd recommend using RootTools.