簡體   English   中英

ANDROID:如何在Android應用程序中獲得root用戶訪問權限?

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

我正在開發我的第一個Android應用程序,並且很好奇是否有執行特權shell命令的“標准”方法。 通過執行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";

我已經讀過有關在JNI包裝特權( superuser )調用的信息:這可能嗎? 如果是這樣,如何去完成它? 除此之外,還有其他從Java調用特權指令的方法嗎?

據我所知,您只能使用root特權運行命令行命令。 您可以使用我制作的將根訪問權限包裝在您的代碼中的通用類: http : //muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

您需要做的就是擴展此類,並重寫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();
}

我知道一個可能的解決方案是將您的應用程序作為系統簽名,就我所知,這與root用戶並不完全相同: 如何使用系統簽名對Android應用程序進行簽名? 但是我想這不是您想要的。

我要做的另一件事是創建一個本機應用程序,該應用程序執行所需的操作,並將其作為外部進程運行。 但是有必要為該本機應用程序提供所需的特權和suid位,前提是該分區不是nosuid。 但這不是我所需要的。

我想通過JNI調用的C代碼應該受到與生活在同一過程中相同的限制。

如果您擁有su二進制文件,則可以從Java運行類似以下命令的命令: Runtime.getRuntime().exec("su -c reboot")

我不記得有其他辦法了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM