Android應用程序如何獲取root權限

在有些應用中,我們需要獲取root權限,比如刪除系統自帶的應用程序等,下面介紹一般應用程序如何獲取root:

1. root手機

    應用程序能獲取root權限的前提是手機已經被root,一般手機廠商在出廠時,都會將su命令去掉,防止一般應用獲取root權限,所以需要root手機。一般有兩種root手機的方法:一種是手機廠商自己提供root工具,另一種是利用手機漏洞將su和superuser.apk push到手機中。superuser用於管理獲取root權限的應用程序,所以其實,root手機就是將su命令放入手機/system/xbin目錄以及安裝superuser.apk。

2. 應用程序獲取root權限

    應用程序通過執行su命令切換到root用戶獲取root權限,然後執行命令,如下所示:

            Process process = null;
            DataOutputStream os = null;
            String cmd = "touch /system/app/phonekey.kk";

            try {
                process = Runtime.getRuntime().exec("su");
                os = new DataOutputStream(process.getOutputStream());
                DataInputStream error = new DataInputStream(process.getErrorStream());
                DataInputStream input = new DataInputStream(process.getInputStream());
                os.writeBytes(cmd + "\n");
                os.flush();
                os.writeBytes("exit\n");
                os.flush();
                process.waitFor();
            } catch (Exception e) {
                return false;
            } finally {
                try {
                    if (os != null) {
                        os.close();
                    }
                    process.destroy();
                } catch (Exception e) {
                }
            }

3. root過程中可能遇到的問題

    最常見的一個錯誤就是 "su: uid xxxxx not allowed to su"。出現這個錯誤的原因是因爲su限制了獲取root的用戶,看su的源代碼如下(system/exras/su/su.c):

/*
 * SU can be given a specific command to exec. UID _must_ be
 * specified for this (ie argc => 3).
 *
 * Usage:
 * su 1000
 * su 1000 ls -l
 */
int main(int argc, char **argv)
{
    struct passwd *pw;
    int uid, gid, myuid;

    /* Until we have something better, only root and the shell can use su. */
    myuid = getuid();
    if (myuid != AID_ROOT && myuid != AID_SHELL) {
        fprintf(stderr,"su: uid %d not allowed to su-heihei\n", myuid);
        return 1;
    }

    if(argc < 2) {
        uid = gid = 0;
    } else {
        pw = getpwnam(argv[1]);

        if(pw == 0) {
            uid = gid = atoi(argv[1]);
        } else {
            uid = pw->pw_uid;
            gid = pw->pw_gid;
        }
    }

    if(setgid(gid) || setuid(uid)) {
        fprintf(stderr,"su: permission denied\n");
        return 1;
    }

    /* User specified command for exec. */
    if (argc == 3 ) {
        if (execlp(argv[2], argv[2], NULL) < 0) {
            fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
                    strerror(errno));
            return -errno;
        }
    } else if (argc > 3) {
        /* Copy the rest of the args from main. */
        char *exec_args[argc - 1];
        memset(exec_args, 0, sizeof(exec_args));
        memcpy(exec_args, &argv[2], sizeof(exec_args));
        if (execvp(argv[2], exec_args) < 0) {
            fprintf(stderr, "su: exec failed for %s Error:%s\n", argv[2],
                    strerror(errno));
            return -errno;
        }
    }

    /* Default exec shell. */
    execlp("/system/bin/sh", "sh", NULL);

    fprintf(stderr, "su: exec failed\n");
    return 1;
}
觀察源代碼16-17行發現 默認只有AID_ROOT和 AID_SHELL用戶支持su命令,所以我們可以將18行的“return 1”這句話註釋掉,即可。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章