简体   繁体   English

ANDROID:如何在Android应用程序中获得root用户访问权限?

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

I'm developing my first Android application, and I'm curious if there are any "standard" ways for executing privileged shell commands. 我正在开发我的第一个Android应用程序,并且很好奇是否有执行特权shell命令的“标准”方法。 I've only been able to find one way to do it, by executing su , and then appending my commands to stdin of the su process. 通过执行su ,然后将命令附加到su进程的stdin ,我只能找到一种方法。

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";

I've read about wrapping privileged ( superuser ) calls up in JNI : is this possible? 我已经读过有关在JNI包装特权( superuser )调用的信息:这可能吗? If so, how would one go about accomplishing it? 如果是这样,如何去完成它? Other than that, are there any other ways of calling privileged instructions from Java ? 除此之外,还有其他从Java调用特权指令的方法吗?

As far as I know, you can only run command-line commands using root privileges. 据我所知,您只能使用root特权运行命令行命令。 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 您可以使用我制作的将根访问权限包装在您的代码中的通用类: 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. 您需要做的就是扩展此类,并重写getCommandsToExecute方法以返回要作为根用户执行的命令。

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

A possible solution I know is to sign your application as system, which is not exactly the same as root as far as I know: How to sign Android app with system signature? 我知道一个可能的解决方案是将您的应用程序作为系统签名,就我所知,这与root用户并不完全相同: 如何使用系统签名对Android应用程序进行签名? . But I suppose this is not what you wanted. 但是我想这不是您想要的。

Another thing I did is to create a native application that does what is needed, running it as an external process. 我要做的另一件事是创建一个本机应用程序,该应用程序执行所需的操作,并将其作为外部进程运行。 But it is necessary to give this native application the privileges you need and the suid bit, provided the partition is not nosuid. 但是有必要为该本机应用程序提供所需的特权和suid位,前提是该分区不是nosuid。 But this is not what you needed either I suppose. 但这不是我所需要的。

C code called through JNI should be subject to the same limitations as living in the same process, I suppose. 我想通过JNI调用的C代码应该受到与生活在同一过程中相同的限制。

If you have the su binary available then you can run commands from java with something like: Runtime.getRuntime().exec("su -c reboot") . 如果您拥有su二进制文件,则可以从Java运行类似以下命令的命令: Runtime.getRuntime().exec("su -c reboot")

I don't remember any other way. 我不记得有其他办法了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM