在运行RunTime.exec("su")时出现“uid 1000 not allowed to su”错误

3
当我尝试从我的拥有系统权限的程序运行su命令时,stderr返回以下错误信息:

uid 1000 not allowed to su

我将共享uid设置为android.uid.system或android.uid.shell,但没有任何改变。这个设备应该已经root了。我真的不明白发生了什么。
下面是代码:
private boolean runAsRoot(String cmd, File workdir) throws IOException {
    Log.i(LOG_TAG, "Execute command as root: " + cmd);
    Process p = Runtime.getRuntime().exec(new String[] {"su", "-c", cmd});
    if (p == null) {
        Log.e(LOG_TAG, "cannot create process for " + cmd);
        return false;
    }

    int exit = -1;
    try {
        exit = p.waitFor();

        InputStreamReader isr;
        if (exit == 0) {
            isr = new InputStreamReader(p.getInputStream());
        } else {
            isr = new InputStreamReader(p.getErrorStream());
        }

        BufferedReader br = new BufferedReader(isr);
        StringBuilder sb = new StringBuilder();

        String line;
        while ((line = br.readLine()) != null) {
            if (sb.length() > 0) {
                sb.append('\n');
            }
            sb.append(line);
        }

        String string = sb.toString();

        Log.l(LOG_TAG, exit == 0 ? Level.INFO : Level.SEVERE, string);

    } catch (InterruptedException e) {
        Log.e(LOG_TAG, e);
    }

    return exit == 0;
}
2个回答

3
最简单的方法是按照以下方式构建自己的nano“sudo”:
sudo.c
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[], char *envp[]) {
    int i;
    int n = 1;
    for (i = 1; i < argc; i++) {
        n += strlen(argv[i]) + 1;
    }
    char buf[n + 2];
    char* p = buf;
    for (i = 1; i < argc; i++) {
        strcpy(p, argv[i]);
        p += strlen(argv[i]);
        *p++ = i == argc - 1 ? 0 : ' ';
    }
    *p++ = 0;
    char* a[] = {"/system/bin/sh", "-c", buf, NULL};
    execve("/system/bin/sh", a, envp);
    fprintf(stderr, "sudo: /system/bin/sh  error:%s\n", strerror(errno));
    return 1;
}

按照以下方式编译和安装:

使用make-sudo.sh脚本

export NDK_ROOT=~/<path to android-ndk>
export GCC=$NDK_ROOT/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc
export SYS_ROOT=$NDK_ROOT/platforms/android-17/arch-arm
$GCC --sysroot $SYS_ROOT ./sudo.c -o ./sudo
adb root
adb shell "mount -o rw,remount /system"
adb shell "rm /system/xbin/sudo"
adb push  sudo /system/xbin/
adb shell "chmod 06755 /system/xbin/sudo"
adb shell "ls -l /system/xbin/sudo"
adb remount
rm ./sudo

警告:这是一种简单但危险的方法,因为缺少sudoers文件或任何其他黑/白名单允许所有其他应用程序使用sudo。对我来说可用,因为我的应用程序是嵌入式Android上唯一的一个,不需要额外的安全性。


3

您有一个标准/官方的安卓'su'程序,它并不适用于此目的,而是来自像超级用户.apk这样的已被修改以允许此操作的程序。

您不能(从普通第三方应用程序中)将共享UID设置为特权用户,例如系统甚至是半特权用户,例如shell。

您的设备可能尚未被修改以完全允许root访问。


好的,这是可能的。至少ADB是有root权限的。你可以通过将共享用户ID设置为此类值并使用制造商的密钥和证书签署APK来获取UID SYSTEM或SHELL(对我来说没有问题)。 - slash33
slash33,好的,我已经完成了所有操作,并执行了adb安装,但仍然无法su。它显示uid 1000不允许su。也许我需要以某种方式安装到系统文件夹,而不仅仅是通过adb安装? - djdance
1
当然你不能,安卓系统专门设计成不允许你在生产环境中获取 root 权限,也不允许应用程序代码以任何形式在任何构建中执行。如果你想尝试利用一些安全漏洞,可以去 xda-developers 上看看,但这超出了网站关注的软件开发范畴。 - Chris Stratton

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