安卓获取root权限的脚本

3

我需要帮助这个脚本,有人能告诉我我做错了什么吗?我试图在启动时制作一个根检查器。

  1. 检查写入权限
  2. 返回没有root的警报
  3. 按下退出键后退出(待完成)

这是我正在构建的Java代码片段:

{
        Process p;
    try
    { 
        //  Run root command
        p = Runtime.getRuntime().exec("su"); 

        // Attempt to write a file to system
        DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
        os.writeBytes("echo \"Do I have root?\" >/system/temporary.txt\n");

        // Close the stream
        os.writeBytes("exit\n"); 
        os.flush(); 
        try
        { 
            p.waitFor(); 
            if (p.exitValue() != 255)
            { 
                // Code to run on ROOTED
                //  NOTHING JUST GO FORWARD
            }
            else
            { 
                // Code to run on NON ROOTED

            } 
        }
        catch (InterruptedException e)
        { {
            // TODO Code to run with interrupted exception

            }
        } 
    }
    catch (IOException e)
    { 
        // TODO Code to run in input/output exception

    }}}

APK文件可以在此处下载,供测试人员使用。

有关根代码片段的源注释,请参见此处


虽然问题可能已经解决,但永远不要“删除”您的问题。如果您希望将其删除,请删除它。如果不是,请将其保留原样,因为其他用户可能会遇到类似的问题,并且可以阅读并尝试理解您的问题,如果提供的解决方案对他们有帮助。 - Bonatti
@Bonatti 谢谢Bonatti,我会为其他人修复原始问题...我发现我写错了id,所以我用额外的ELSE IF修复了这个问题。 - Empire of E
不要删除所有原始内容。 - Memor-X
1个回答

1
通常检查root权限需要检查您的“用户ID”,使用Linux命令id
因此,不要使用以下代码: os.writeBytes("echo \"Do I have root?\" >/system/temporary.txt\n"); 而是使用以下代码: os.writeBytes("id\n"); os.flush(); 然后使用以下内容读取响应: DataInputStream data = new DataInputStream(p.getInputStream()); 并使用以下内容检查结果: if (data.readLine().contains("uid=0")); 编辑:
我在我的应用程序中使用以下Root Privileges类:
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Root related operations.
 */
public class RootPrivileges {
    public static final String TAG = "RootPrivileges";

    private RootPrivileges() {
        Log.e(TAG, "RootPrivileges should not be instantiated");
    }

    /**
     * Checks and asks for Root privileges
     *
     * @return true if has root privileges, false otherwise
     */
    public static boolean hasRoot() {
        boolean resp = false;
        Process suProcess;
        try {
            suProcess = Runtime.getRuntime().exec("su");
            DataOutputStream os = new DataOutputStream(suProcess.getOutputStream());
            DataInputStream osRes = new DataInputStream(suProcess.getInputStream());
            if (os != null && osRes != null) {
                os.writeBytes("id\n");
                os.flush();
                String currUid = osRes.readLine();
                boolean exitSu;
                if (null == currUid) {
                    resp = false;
                    exitSu = false;
                    Log.e(TAG, "No root privileges, or denied by user");
                } else if (currUid.contains("uid=0")) {
                    resp = true;
                    exitSu = true;
                    Log.v(TAG, "Root privileges given");
                } else {
                    resp = false;
                    exitSu = true;
                    Log.e(TAG, "Not enough privileges.\n   Received: " + currUid + "\n   Expected: 0");
                }
                if (exitSu) {
                    os.writeBytes("exit\n");
                    os.flush();
                }
            }
        } catch (Exception e) {
            resp = false;
            Log.e(TAG, "Root privileges denied. [" + e.getClass().getName() + "] : " + e.getMessage());
        }
        return resp;
    }

    /**
     * Executes a command as root.
     *
     * @param cmd the command.
     * @return if code was sent to execute
     */
    public static final boolean execute(String cmd) {
        try {
            if (cmd != null && cmd.length() > 0) {
                Process suProcess = Runtime.getRuntime().exec("su");
                DataOutputStream dataOutputStream = new DataOutputStream(suProcess.getOutputStream());
                DataInputStream dataInputStream = new DataInputStream(suProcess.getInputStream());
                DataInputStream dataErrorStream = new DataInputStream(suProcess.getErrorStream());

                dataOutputStream.writeBytes(cmd);
                dataOutputStream.writeBytes("\n");
                dataOutputStream.flush();
                dataOutputStream.writeBytes("exit\n");

                BufferedReader reader = new BufferedReader(new InputStreamReader(dataInputStream));
                BufferedReader err_reader = new BufferedReader(new InputStreamReader(dataErrorStream));
                String resp;
                while ((resp = reader.readLine()) != null) {
                    Log.v(TAG, "[resp]" + resp);
                }
                while ((resp = err_reader.readLine()) != null) {
                    Log.v(TAG, "[err_resp]" + resp);
                }
                reader.close();
                err_reader.close();
                dataOutputStream.flush();
                try {
                    int suProcessRetval = suProcess.waitFor();
                    suProcess.destroy();
                    return (suProcessRetval != 255);
                } catch (Exception ex) {
                    Log.e(TAG, "Error in Root command execution");
                    ex.printStackTrace();
                }
            } else {
                Log.e(TAG, "command is null or empty");
            }
        } catch (IOException ex) {
            Log.e(TAG, "IOException");
            ex.printStackTrace();
        } catch (SecurityException ex) {
            Log.e(TAG, "SecurityException");
            ex.printStackTrace();
        } catch (Exception ex) {
            Log.e(TAG, "Generic Exception");
            ex.printStackTrace();
        }
        return false;
    }
}

就Android而言,您永远不应该“关闭应用程序”,因为准备和分配所有内容所需的电量比Android内存管理系统中所需的电量更多。您应该阅读有关"Android生命周期"的信息,以更好地了解应用程序应如何运行。如果这是在Activity的上下文中,请只需使用finish()来结束该Activity。至于超级用户/切换用户,这个类对我来说一直很有效。 - Bonatti
通常情况下是这样的,但该应用程序仅设计用于按下安装或删除按钮。删除按钮还通过运行.sh脚本文件关闭和卸载应用程序本身。因此,无法不断运行它。 - Empire of E
谢谢,我会试一下...我尝试了几个,但问题似乎在ELSE命令周围,一旦我按拒绝root,它仍然加载,就好像我已经获得了root权限。 - Empire of E
你正在使用这个类吗?如果是的话,RootPrivileges.hasRoot() 应该总是阻止应用程序,并等待某些“授权 root”的应用程序出现。如果你在其中按下“否”,那么 hasRoot() 将返回 false。 - Bonatti
嗯,这种行为是出乎意料的。您正在运行哪个Android版本?此外,您知道使用了什么Rooting过程,并且su二进制文件是否存在并在其他su命令中正常工作吗?白屏很可能是因为您在活动中设置布局之前请求了root权限。我曾经在一些三星设备上看到过“延迟”,但没有ANR(应用程序无响应),我也看到过当设备使用“Kingroot”或其竞争对手进行Root时会出现“延迟”。ChainFire的“SuperSu”是我迄今为止使用过的最好的Root工具。如果必要,请在AsynkTask上请求root权限。 - Bonatti
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接