在有些應用中,我們需要獲取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”這句話註釋掉,即可。