在有些应用中,我们需要获取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”这句话注释掉,即可。
原文地址:点击打开链接