ANDROID: Как получить root-доступ в приложении для Android?

Я разрабатываю свое первое приложение для Android , и мне любопытно, есть ли «стандартные» способы выполнения привилегированных команд shell . Я только смог найти один способ сделать это, выполнив su , а затем добавив свои команды в stdin процесса 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"; 

Я читал об объявлении привилегированных ( superuser ) вызовов в JNI : возможно ли это? Если да, то как это сделать? Кроме этого, существуют ли другие способы вызова привилегированных инструкций из Java ?

Solutions Collecting From Web of "ANDROID: Как получить root-доступ в приложении для Android?"

Насколько я знаю, вы можете запускать только команды командной строки, используя привилегии root. Вы можете использовать этот общий класс, который я сделал, который обертывает корневой доступ в вашем коде: http://muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

Все, что вам нужно сделать, это расширить этот класс и переопределить метод getCommandsToExecute чтобы вернуть команды, которые вы хотите выполнить с правами 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(); } 

Возможное решение, которое я знаю, – подписать ваше приложение как систему, которая, насколько мне известно, не совсем то же самое, что и root: как подписать Android-приложение с сигнатурой системы? , Но я полагаю, это не то, что вы хотели.

Еще одна вещь, которую я сделал, – создать собственное приложение, которое делает то, что нужно, запуская его как внешний процесс. Но для этого родного приложения необходимо предоставить необходимые вам привилегии и бит suid, если раздел не является nosuid. Но это не то, что вам нужно, я полагаю.

C-код, вызываемый через JNI, должен подвергаться тем же ограничениям, что и жить в одном процессе.

Если у вас есть su бинарный доступ, то вы можете запускать команды из java с чем-то вроде: Runtime.getRuntime (). Exec («su -c reboot»).

Я не помню другого пути.