Android: How to Gain Root Access in an Android Application

ANDROID: How to gain root access in an Android application?

As far as I know, you can only run command-line commands using root privileges. You can use this generic class I made that wraps the root access in your code:
http://muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

All you need to do is extend this class and override the getCommandsToExecute method to return the commands you want to execute as root.

public abstract class ExecuteAsRootBase
{
public static boolean canRunRootCommands()
{
boolean retval = false;
Process suProcess;

try
{
suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
DataInputStream osRes = new DataInputStream(suProcess.getInputStream());

if (null != os && null != osRes)
{
// Getting the id of the current user to check if this is root
os.writeBytes("id\n");
os.flush();

String currUid = osRes.readLine();
boolean exitSu = false;
if (null == currUid)
{
retval = false;
exitSu = false;
Log.d("ROOT", "Can't get root access or denied by user");
}
else if (true == currUid.contains("uid=0"))
{
retval = true;
exitSu = true;
Log.d("ROOT", "Root access granted");
}
else
{
retval = false;
exitSu = true;
Log.d("ROOT", "Root access rejected: " + currUid);
}

if (exitSu)
{
os.writeBytes("exit\n");
os.flush();
}
}
}
catch (Exception e)
{
// Can't get root !
// Probably broken pipe exception on trying to write to output stream (os) after su failed, meaning that the device is not rooted

retval = false;
Log.d("ROOT", "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage());
}

return retval;
}

public final boolean execute()
{
boolean retval = false;

try
{
ArrayList<String> commands = getCommandsToExecute();
if (null != commands && commands.size() > 0)
{
Process suProcess = Runtime.getRuntime().exec("su");

DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());

// Execute commands that require root access
for (String currCommand : commands)
{
os.writeBytes(currCommand + "\n");
os.flush();
}

os.writeBytes("exit\n");
os.flush();

try
{
int suProcessRetval = suProcess.waitFor();
if (255 != suProcessRetval)
{
// Root access granted
retval = true;
}
else
{
// Root access denied
retval = false;
}
}
catch (Exception ex)
{
Log.e("ROOT", "Error executing root action", ex);
}
}
}
catch (IOException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (SecurityException ex)
{
Log.w("ROOT", "Can't get root access", ex);
}
catch (Exception ex)
{
Log.w("ROOT", "Error executing internal operation", ex);
}

return retval;
}
protected abstract ArrayList<String> getCommandsToExecute();
}

Getting 'root permission for Android App

First: note that you can only execute shell commands using su (= you can only use shell commands as root, not java code).

Second: Not sure if this applies to all su apps out there, but this is the help message of su on my phone:

Usage: su [options] [--] [-] [LOGIN] [--] [args...]

Options:
--daemon start the su daemon agent
-c, --command COMMAND pass COMMAND to the invoked shell
-h, --help display this help message and exit
-, -l, --login pretend the shell to be a login shell
-m, -p,
--preserve-environment do not change environment variables
-s, --shell SHELL use SHELL instead of the default /system/bin/sh
-u display the multiuser mode and exit
-v, --version display version number and exit
-V display version code and exit,
this is used almost exclusively by Superuser.apk

This means: you have to run su -c something (or su -c something - root, but rootis the default anyway). essentially this is equal to su on most Linux systems, except the daemon-thing, as there is no daemon ahndling su calls on regular linux systems.

If other su commands behave differently (which is possible), it's more secure to open a stream to a shell, execute su, evaluate it's return code, then proceed to execute other commands, finally execute exit.

How to create android apps with root access?

You need su installed in the phone (of course). Details here:
http://forum.xda-developers.com/showthread.php?t=682828

And to use it, is as simple as running su command. Here is a sample I use to reboot the phone programmatically (copied from this answer: Android 2.2: Reboot device programmatically )

try {
Runtime.getRuntime().exec("su");
Runtime.getRuntime().exec("reboot");
} catch (IOException e) {
}

How do I request root access in Android?

Just exec the command su and within that Process you have root priviliges:

Process p = Runtime.getRuntime().exec("su");

See this blog post for full example.

How can I get root to work for system app in Android?

The only solution that works for me is the server binary that launched by init as root process. I wrote simple server binary that can be connected via LocalSocket from java side and I can send it some commands. To start server binary on system start, I added next lines to init.rc script:

service suservice /system/bin/suservice
class core
user root
group root
socket suservice stream 0600 system system

On java side I wrote simple library that works via callback interface and receives data from this service or error if something wrong.

Now only apps that started as system:system can use this local socket to run root commands. User apps receive Permission denied as expexted.

P.S. There is no need to run or keep su binary now at all, because server binary already runs as root. I can completly remove su binary from the system now.

How can I get root permissions through the Android SDK?

What you need to do is something like:

Process root = Runtime.getRuntime().exec("su");

That causes SuperUser to show, which lets you either Allow or Block it from root access. This approach might not work if the user is not rooted. Here is a way you can test it.

Getting root permissions on android app within native code

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.



Related Topics



Leave a reply



Submit