studio permission permisos name internet example access_superuser java android root

java - permission - ANDROID: ¿Cómo obtener acceso de root en una aplicación de Android?



user permission android name android permission internet/> (2)

Estoy desarrollando mi primera aplicación de Android , y tengo curiosidad por saber si hay formas "estándar" para ejecutar comandos de shell privilegiados. Solo he podido encontrar una forma de hacerlo, ejecutando su y anexando mis comandos al proceso del su .

DataOutputStream pOut = new DataOutputStream(p.getOutputStream()); DataInputStream pIn = new DataInputStream(p.getInputStream()); String rv = ""; // su must exit before its output can be read pOut.writeBytes(cmd + "/nexit/n"); pOut.flush(); p.waitFor(); while (pIn.available() > 0) rv += pIn.readLine() + "/n";

He leído acerca de envolver llamadas privilegiadas ( superuser ) en JNI : ¿es esto posible? Si es así, ¿cómo lograrlo? Aparte de eso, ¿hay alguna otra forma de llamar instrucciones privilegiadas de Java ?


Por lo que sé, solo puedes ejecutar comandos de línea de comandos usando privilegios de administrador. Puede utilizar esta clase genérica que hice que envuelve el acceso raíz en su código: http://muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

Todo lo que necesita hacer es extender esta clase y anular el método getCommandsToExecute para devolver los comandos que desea ejecutar como raíz.

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(); }


Una posible solución que conozco es firmar su aplicación como sistema, que no es exactamente lo mismo que root, hasta donde yo sé: cómo firmar la aplicación de Android con la firma del sistema? . Pero supongo que esto no es lo que querías.

Otra cosa que hice fue crear una aplicación nativa que hiciera lo necesario, ejecutándola como un proceso externo. Pero es necesario darle a esta aplicación nativa los privilegios que necesita y el bit de suid, siempre que la partición no sea nosuid. Pero esto no es lo que necesitabas, supongo.

El código C llamado a través de JNI debería estar sujeto a las mismas limitaciones que vivir en el mismo proceso, supongo.

Si tiene el binario disponible, puede ejecutar comandos desde Java con algo como: Runtime.getRuntime (). Exec ("su -c reboot").

No recuerdo de ninguna otra manera.